mirror of
https://github.com/troglobit/finit.git
synced 2026-10-02 14:02:52 +07:00
Debian now boots to X!
finit.conf:
Use this as /etc/finit.conf on a Debian 6.0 based system with X
installed and sysklogd instead of rsyslogd. Works.
services:
Alternative method for extending the finit boot procedure. Simply
place this script file in an /etc/finit.d/ directory. The script
uses the standard run-parts tool to chain load other start scripts.
helpers.c:
o New functions:
- run(): home grown system() replacement
- run_interactive(): display progress and status when called
o Bugfix start_process(), make sure to use same signal setup for
children as in run() and run_interactive(). Also, use execvp()
instead of execv() to allow searching $PATH for executables.
finit.h:
o Move signal specific code to new signal.h.
o Bypass verbosity setting to let echo() always print to screen.
finit.c:
o Make run_parts() the default, remove external deps, it works.
o Use run() and run_interactive() to speed up execution further
on embedded systems where forking is expensive.
o Kernel cmdline "quiet" should not close STDIO since this makes
it impossible to run some daemons and start scripts. Instead,
we let "quiet" toggle the finit verbosity setting.
o Remove kernel cmdline "--verbose" (Upstart compat), to be used
to enable verbose finit when kernel should be quiet.
o Setup kernel specific settings in /etc/sysctl.conf
o Fix D-Bus startup problems. Probably what caused X from not
working initially. Silly rabbit.
o Use system() workaround to start X, cannot get it to start
at all using run() or run_interactive() at the moment.
signal.h:
New file, header file for signal.c. Was about time.
signal.c:
Remove blocking of SIGCHLD from sig_setup(), instead we setup
SIGCHLD early in sig_init() to handle fork() in run() & C:o.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
@@ -36,7 +36,6 @@ CFLAGS += -W -Wall -Werror -Os
|
||||
# Disable annoying gcc warning for "warn_unused_result", see GIT 37af997
|
||||
CPPFLAGS += -U_FORTIFY_SOURCE
|
||||
CPPFLAGS += -I$(ROOTDIR)/$(CONFIG_LINUXDIR)/include/
|
||||
CPPFLAGS += -DBUILTIN_RUNPARTS
|
||||
CPPFLAGS += -DVERSION=\"$(VERSION)\" -DWHOAMI=\"`whoami`@`hostname`\"
|
||||
CPPFLAGS += -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# Simple Debian finit.conf
|
||||
check /dev/vda1
|
||||
module tipc
|
||||
module evdev
|
||||
module loop
|
||||
module psmouse
|
||||
user admin
|
||||
host testbed
|
||||
network service networking start
|
||||
service /usr/sbin/sshd -D -- OpenSSH Server
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/sh
|
||||
run-parts /etc/rcS.d --arg=start
|
||||
run-parts /etc/rc2.d --arg=start
|
||||
#service acpid start
|
||||
#service networking start
|
||||
#service ssh start
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "finit.h"
|
||||
#include "helpers.h"
|
||||
#include "service.h"
|
||||
#include "signal.h"
|
||||
|
||||
int debug = 0;
|
||||
int verbose = 1;
|
||||
char *sdown = NULL;
|
||||
char *network = NULL;
|
||||
char *startx = NULL;
|
||||
@@ -105,27 +107,22 @@ int main(int UNUSED(args), char *argv[])
|
||||
* Populate /dev and prepare for runtime events from kernel.
|
||||
*/
|
||||
#if defined(USE_UDEV)
|
||||
system("udevd --daemon");
|
||||
run_interactive("udevd --daemon", "Populating device tree");
|
||||
#elif defined (MDEV)
|
||||
system(MDEV "-s");
|
||||
run_interactive(MDEV "-s", "Populating device tree");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Parse kernel parameters
|
||||
*/
|
||||
if ((fp = fopen("/proc/cmdline", "r")) != NULL) {
|
||||
fgets(line, LINE_SIZE, fp);
|
||||
fgets(line, sizeof(line), fp);
|
||||
|
||||
if (strstr(line, "finit_debug") ||
|
||||
strstr(line, "--verbose") ||
|
||||
strstr(line, "--debug"))
|
||||
if (strstr(line, "finit_debug") || strstr(line, "--debug"))
|
||||
debug = 1;
|
||||
|
||||
if (!debug && strstr(line, "quiet")) {
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
}
|
||||
if (!debug && strstr(line, "quiet"))
|
||||
verbose = 0;
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
@@ -141,7 +138,7 @@ int main(int UNUSED(args), char *argv[])
|
||||
|
||||
_d("Parse %s ...", FINIT_CONF);
|
||||
while (!feof(fp)) {
|
||||
if (!fgets(line, LINE_SIZE, fp))
|
||||
if (!fgets(line, sizeof(line), fp))
|
||||
continue;
|
||||
chomp(line);
|
||||
|
||||
@@ -155,7 +152,7 @@ int main(int UNUSED(args), char *argv[])
|
||||
if (MATCH_CMD(line, "check ", x)) {
|
||||
strcpy(cmd, "/sbin/fsck -C -a ");
|
||||
build_cmd(cmd, x, CMD_SIZE);
|
||||
system(cmd);
|
||||
run_interactive(cmd, "Checking file system integrity on %s", x);
|
||||
continue;
|
||||
}
|
||||
if (MATCH_CMD(line, "user ", x)) {
|
||||
@@ -176,13 +173,13 @@ int main(int UNUSED(args), char *argv[])
|
||||
if (MATCH_CMD(line, "module ", x)) {
|
||||
strcpy(cmd, "/sbin/modprobe ");
|
||||
build_cmd(cmd, x, CMD_SIZE);
|
||||
system(cmd);
|
||||
run_interactive(cmd, " Loading module %s", x);
|
||||
continue;
|
||||
}
|
||||
if (MATCH_CMD(line, "mknod ", x)) {
|
||||
strcpy(cmd, "/bin/mknod ");
|
||||
build_cmd(cmd, x, CMD_SIZE);
|
||||
system(cmd);
|
||||
run_interactive(cmd, " Creating device node %s", x);
|
||||
continue;
|
||||
}
|
||||
if (MATCH_CMD(line, "network ", x)) {
|
||||
@@ -210,18 +207,18 @@ int main(int UNUSED(args), char *argv[])
|
||||
_d("Mount filesystems in /etc/fstab ...");
|
||||
|
||||
#ifdef REMOUNT_ROOTFS_RW
|
||||
system("/bin/mount -n -o remount,rw /");
|
||||
run("/bin/mount -n -o remount,rw /");
|
||||
#endif
|
||||
#ifdef SYSROOT
|
||||
mount(SYSROOT, "/", NULL, MS_MOVE, NULL);
|
||||
run(SYSROOT, "/", NULL, MS_MOVE, NULL);
|
||||
#endif
|
||||
umask(0);
|
||||
system("mount -na");
|
||||
system("swapon -ea");
|
||||
run("mount -na");
|
||||
run("swapon -ea");
|
||||
umask(0022);
|
||||
|
||||
/* Cleanup stale files, if any still linger on. */
|
||||
system("rm -rf /tmp/* /var/run/* /var/lock/*");
|
||||
run_interactive("rm -rf /tmp/* /var/run/* /var/lock/*", "Cleanup temporary directories");
|
||||
|
||||
/*
|
||||
* Base FS up, enable standard SysV init signals
|
||||
@@ -233,7 +230,7 @@ int main(int UNUSED(args), char *argv[])
|
||||
*/
|
||||
#ifndef NO_HCTOSYS
|
||||
_d("Adjust system clock ...");
|
||||
system("/sbin/hwclock --hctosys");
|
||||
run_interactive("/sbin/hwclock --hctosys", "Restoring system clock (UTC) from RTC");
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -248,7 +245,7 @@ int main(int UNUSED(args), char *argv[])
|
||||
while ((d = readdir(dir)) != NULL) {
|
||||
if (isalnum(d->d_name[0]))
|
||||
continue;
|
||||
snprintf(line, LINE_SIZE,
|
||||
snprintf(line, sizeof(line),
|
||||
"/etc/resolvconf/run/interface/%s", d->d_name);
|
||||
unlink(line);
|
||||
}
|
||||
@@ -279,11 +276,7 @@ int main(int UNUSED(args), char *argv[])
|
||||
touch("/etc/resolvconf/run/enable-updates");
|
||||
|
||||
chdir("/etc/resolvconf/run/interface");
|
||||
#ifdef BUILTIN_RUNPARTS
|
||||
run_parts("/etc/resolvconf/update.d", "-i", NULL);
|
||||
#else
|
||||
system(RUNPARTS " --arg=i /etc/resolvconf/update.d");
|
||||
#endif /* BUILTIN_RUNPARTS */
|
||||
chdir("/");
|
||||
#endif /* USE_ETC_RESOLVCONF_RUN */
|
||||
|
||||
@@ -293,14 +286,15 @@ int main(int UNUSED(args), char *argv[])
|
||||
remove("/etc/network/run/ifstate");
|
||||
#endif
|
||||
|
||||
/* Setup kernel specific settings, e.g. allow broadcast ping, etc. */
|
||||
run("/sbin/sysctl -e -p /etc/sysctl.conf >/dev/null");
|
||||
|
||||
/* Set initial hostname. */
|
||||
set_hostname(hostname);
|
||||
|
||||
ifconfig("lo", "127.0.0.1", "255.0.0.0", 1);
|
||||
if (network) {
|
||||
_d("Starting networking: %s", network);
|
||||
system(network);
|
||||
}
|
||||
if (network)
|
||||
run_interactive(network, "Starting networking: %s", network);
|
||||
|
||||
/*
|
||||
* Set random seed
|
||||
@@ -317,14 +311,14 @@ int main(int UNUSED(args), char *argv[])
|
||||
* Console setup (for X)
|
||||
*/
|
||||
makepath("/var/run/console");
|
||||
snprintf(line, LINE_SIZE, "/var/run/console/%s", username);
|
||||
snprintf(line, sizeof(line), "/var/run/console/%s", username);
|
||||
touch(line);
|
||||
|
||||
#ifdef PAM_CONSOLE
|
||||
if ((fd = open("/var/run/console/console.lock", O_CREAT|O_WRONLY|O_TRUNC, 0644)) >= 0) {
|
||||
write(fd, username, strlen(username));
|
||||
close(fd);
|
||||
system("/sbin/pam_console_apply");
|
||||
run("/sbin/pam_console_apply");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -333,15 +327,18 @@ int main(int UNUSED(args), char *argv[])
|
||||
*/
|
||||
mkdir("/tmp/.X11-unix", 01777);
|
||||
mkdir("/tmp/.ICE-unix", 01777);
|
||||
mkdir("/var/run/sshd", 01755);
|
||||
mkdir("/var/run/sshd", 01755); /* OpenSSH */
|
||||
mkfifo("/dev/xconsole", 0640); /* sysklogd */
|
||||
chown("/dev/xconsole", 0, getgroup("tty"));
|
||||
umask(022);
|
||||
|
||||
#ifdef USE_MESSAGE_BUS
|
||||
_d("Starting D-Bus ...");
|
||||
mkdir("/var/run/dbus", 0755);
|
||||
mkdir("/var/lock/subsys/messagebus", 0755);
|
||||
system("dbus-uuidgen --ensure");
|
||||
system("su -c \"dbus-daemon --system\" messagebus");
|
||||
run("dbus-uuidgen --ensure");
|
||||
remove("/var/run/dbus/pid");
|
||||
run_interactive("dbus-daemon --system", "Starting D-Bus");
|
||||
#endif
|
||||
|
||||
_d("Starting services from %s", FINIT_CONF);
|
||||
@@ -396,7 +393,8 @@ int main(int UNUSED(args), char *argv[])
|
||||
}
|
||||
|
||||
if (startx && !debug) {
|
||||
snprintf(line, sizeof(line), "su -c \"%s\" -l %s", startx, username);
|
||||
echo("Starting X ...");
|
||||
snprintf(line, sizeof(line), "su -c '%s' -l %s", startx, username);
|
||||
system(line);
|
||||
} else {
|
||||
static const char msg[] = "\nPlease press Enter to activate this console. ";
|
||||
@@ -408,7 +406,7 @@ int main(int UNUSED(args), char *argv[])
|
||||
if (fexist(SYNC_STOPPED))
|
||||
continue;
|
||||
|
||||
system(GETTY);
|
||||
run(GETTY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-6
@@ -1,6 +1,13 @@
|
||||
user fred
|
||||
module intel-agp
|
||||
module p4-clockmod
|
||||
check /dev/sda3
|
||||
host eviltwin
|
||||
startx /usr/bin/startx
|
||||
# Simple Debian finit.conf
|
||||
check /dev/vda1
|
||||
module tipc
|
||||
module evdev
|
||||
module loop
|
||||
module psmouse
|
||||
user admin
|
||||
host testbed
|
||||
network service networking start
|
||||
service /sbin/klogd -n -- Kernel logging server
|
||||
service /sbin/syslogd -n -- Syslog server
|
||||
service /usr/sbin/sshd -D -- OpenSSH server
|
||||
startx startx
|
||||
|
||||
@@ -95,9 +95,6 @@
|
||||
# define USE_MESSAGE_BUS
|
||||
#endif
|
||||
|
||||
#define SYNC_SHUTDOWN "/var/lock/finit.shutdown"
|
||||
#define SYNC_STOPPED "/var/lock/finit.stopped"
|
||||
|
||||
#ifndef DEFUSER
|
||||
# define DEFUSER "root"
|
||||
#endif
|
||||
@@ -105,8 +102,9 @@
|
||||
# define DEFHOST "noname"
|
||||
#endif
|
||||
|
||||
#define CMD_SIZE 256
|
||||
#define LINE_SIZE 1024
|
||||
#define CMD_SIZE 256
|
||||
#define BUF_SIZE 4096
|
||||
#define USERNAME_SIZE 16
|
||||
#define HOSTNAME_SIZE 32
|
||||
|
||||
@@ -131,20 +129,15 @@
|
||||
#define MATCH_CMD(l, c, x) \
|
||||
(!strncmp(l, c, strlen(c)) && (x = (l) + strlen(c)))
|
||||
|
||||
#define echo(fmt, args...) do { fprintf(stderr, fmt "\n", ##args); } while (0)
|
||||
#define _d(fmt, args...) do { if (debug) { fprintf(stderr, "finit:%s() - " fmt "\n", __func__, ##args); } } while (0)
|
||||
#define echo(fmt, args...) do { if (1) { fprintf(stderr, fmt "\n", ##args); } } while (0)
|
||||
#define _d(fmt, args...) do { if (debug) { fprintf(stderr, "finit:%s() - " fmt "\n", __func__, ##args); } } while (0)
|
||||
#define _e(fmt, args...) do { fprintf(stderr, "finit:%s() - " fmt "\n", __func__, ##args); } while (0)
|
||||
#define _pe(fmt, args...) do { fprintf(stderr, "finit:%s() - " fmt ". Error %d: %s\n", __func__, ##args, errno, strerror(errno)); } while (0)
|
||||
|
||||
extern int debug;
|
||||
extern int verbose;
|
||||
extern char *sdown;
|
||||
|
||||
/* signal.c */
|
||||
void do_shutdown (int sig);
|
||||
int sig_stopped (void);
|
||||
void sig_init (void);
|
||||
void sig_setup (void);
|
||||
|
||||
/* initctl.c */
|
||||
void listen_initctl (void);
|
||||
|
||||
|
||||
@@ -37,17 +37,19 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#ifdef BUILTIN_RUNPARTS
|
||||
#include <dirent.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "finit.h"
|
||||
#include "helpers.h"
|
||||
#include "signal.h"
|
||||
|
||||
#define NUM_ARGS 16
|
||||
#define NUM_SCRIPTS 128 /* ought to be enough for anyone */
|
||||
|
||||
/*
|
||||
* Helpers to replace system() calls
|
||||
@@ -101,7 +103,6 @@ void ifconfig(char *name, char *inet, char *mask, int up)
|
||||
close(sock);
|
||||
}
|
||||
|
||||
#define BUF_SIZE 4096
|
||||
|
||||
void copyfile(char *src, char *dst, int size)
|
||||
{
|
||||
@@ -175,31 +176,18 @@ int print_result(int fail)
|
||||
int start_process(char *cmd, char *args[], int console)
|
||||
{
|
||||
pid_t pid;
|
||||
sigset_t nmask, omask;
|
||||
|
||||
if (sig_stopped())
|
||||
return 0;
|
||||
|
||||
/* Block SIGCHLD while forking. */
|
||||
sigemptyset(&nmask);
|
||||
sigaddset(&nmask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &nmask, &omask);
|
||||
pid = fork();
|
||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
if (!pid) {
|
||||
int i;
|
||||
struct sigaction act;
|
||||
struct sigaction sa;
|
||||
|
||||
/* Reset signal handlers that were set by the parent process */
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_handler = SIG_DFL;
|
||||
|
||||
sigemptyset(&nmask);
|
||||
sigaddset(&nmask, SIGCHLD);
|
||||
sigprocmask(SIG_UNBLOCK, &nmask, NULL);
|
||||
|
||||
for (i = 1; i < NSIG; i++)
|
||||
sigaction(i, &act, NULL);
|
||||
for (i = 1; i < NSIG; i++)
|
||||
DFLSIG(sa, i, 0);
|
||||
|
||||
if (console) {
|
||||
int fd = open (CONSOLE, O_WRONLY | O_APPEND);
|
||||
@@ -209,17 +197,150 @@ int start_process(char *cmd, char *args[], int console)
|
||||
}
|
||||
}
|
||||
|
||||
execv(cmd, args);
|
||||
execvp(cmd, args);
|
||||
exit(!console ? print_result(0) : 0);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
#ifdef BUILTIN_RUNPARTS
|
||||
int run(char *cmd)
|
||||
{
|
||||
int status, result, i = 0;
|
||||
FILE *fp;
|
||||
char *args[NUM_ARGS + 1], *arg, *backup;
|
||||
pid_t pid;
|
||||
|
||||
#define NUM_SCRIPTS 128 /* ought to be enough for anyone */
|
||||
#define NUM_ARGS 16
|
||||
/* We must create a copy that is possible to modify. */
|
||||
backup = arg = strdup(cmd);
|
||||
if (!arg)
|
||||
return 1; /* Failed allocating a string to be modified. */
|
||||
|
||||
/* Split command line into tokens of an argv[] array. */
|
||||
args[i++] = strsep(&arg, "\t ");
|
||||
do {
|
||||
/* Handle run("su -c \"dbus-daemon --system\" messagebus");
|
||||
* => "su", "-c", "\"dbus-daemon --system\"", "messagebus" */
|
||||
if (*arg == '\'' || *arg == '"') {
|
||||
char *p, delim[2] = " ";
|
||||
|
||||
delim[0] = arg[0];
|
||||
args[i++] = arg++;
|
||||
strsep(&arg, delim);
|
||||
p = arg - 1;
|
||||
*p = *delim;
|
||||
*arg++ = 0;
|
||||
} else {
|
||||
args[i++] = strsep(&arg, "\t ");
|
||||
}
|
||||
} while (arg && i < NUM_ARGS);
|
||||
args[i] = NULL;
|
||||
#if 0
|
||||
_e("Splitting: '%s' =>", cmd);
|
||||
for (i = 0; args[i]; i++)
|
||||
_e("\t%s", args[i]);
|
||||
#endif
|
||||
if (i == NUM_ARGS && args[i]) {
|
||||
_e("Command too long: %s", cmd);
|
||||
free(backup);
|
||||
errno = EOVERFLOW;
|
||||
return 1;
|
||||
}
|
||||
|
||||
fp = fopen("/dev/null", "w");
|
||||
pid = fork();
|
||||
if (0 == pid) {
|
||||
int i;
|
||||
struct sigaction sa;
|
||||
|
||||
/* Reset signal handlers that were set by the parent process */
|
||||
for (i = 1; i < NSIG; i++)
|
||||
DFLSIG(sa, i, 0);
|
||||
|
||||
/* Redirect stdio if the caller requested so. */
|
||||
if (fp) {
|
||||
int fd = fileno(fp);
|
||||
|
||||
dup2(fd, STDIN_FILENO);
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
dup2(fd, STDERR_FILENO);
|
||||
}
|
||||
|
||||
execvp(args[0], args);
|
||||
_exit(1); /* Only if execv() fails. */
|
||||
} else if (-1 == pid) {
|
||||
_pe("%s", args[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (waitpid(pid, &status, 0) == -1) {
|
||||
if (errno == EINTR)
|
||||
_e("Caught unblocked signal waiting for %s, aborting.", args[0]);
|
||||
else if (errno == ECHILD)
|
||||
_e("Caught SIGCHLD waiting for %s, aborting.", args[0]);
|
||||
else
|
||||
_e("Failed starting %s, error %d: %s", args[0], errno, strerror (errno));
|
||||
|
||||
if (fp) fclose(fp);
|
||||
free(backup);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
result = WEXITSTATUS(status);
|
||||
if (WIFEXITED(status)) {
|
||||
_d("Started %s and ended OK: %d", args[0], result);
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
_d("Process %s terminated by signal %d", args[0], WTERMSIG(status));
|
||||
if (!result)
|
||||
result = 1; /* Must alert callee that the command did complete successfully.
|
||||
* This is necessary since not all programs trap signals and
|
||||
* change their return code accordingly. --Jocke */
|
||||
}
|
||||
|
||||
if (fp) fclose(fp);
|
||||
free(backup);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int run_interactive(char *cmd, char *fmt, ...)
|
||||
{
|
||||
int status, oldout = 1, olderr = 2;
|
||||
char line[LINE_SIZE];
|
||||
va_list ap;
|
||||
FILE *fp = tmpfile();
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(line, sizeof(line), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
print_descr("", line);
|
||||
if (fp && !debug) {
|
||||
oldout = dup(STDOUT_FILENO);
|
||||
olderr = dup(STDERR_FILENO);
|
||||
dup2(fileno(fp), STDOUT_FILENO);
|
||||
dup2(fileno(fp), STDERR_FILENO);
|
||||
}
|
||||
status = run(cmd);
|
||||
if (fp && !debug) {
|
||||
dup2(oldout, STDOUT_FILENO);
|
||||
dup2(olderr, STDERR_FILENO);
|
||||
}
|
||||
print_result(status);
|
||||
if (fp && !debug) {
|
||||
size_t len, written;
|
||||
|
||||
rewind(fp);
|
||||
do {
|
||||
len = fread(line, 1, sizeof(line), fp);
|
||||
written = fwrite(line, len, sizeof(char), stderr);
|
||||
} while (len > 0 && written == len);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int cmp(const void *s1, const void *s2)
|
||||
{
|
||||
@@ -293,7 +414,6 @@ int run_parts(char *dir, ...)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* BUILTIN_RUNPARTS */
|
||||
|
||||
int getuser(char *s)
|
||||
{
|
||||
|
||||
@@ -40,9 +40,9 @@ char *get_pidname (pid_t pid, char *name, size_t len);
|
||||
int kill_procname (const char *name, int signo);
|
||||
void set_hostname (char *hostname);
|
||||
|
||||
#ifdef BUILTIN_RUNPARTS
|
||||
int run (char *cmd);
|
||||
int run_interactive (char *cmd, char *fmt, ...);
|
||||
int run_parts (char *dir, ...);
|
||||
#endif
|
||||
|
||||
#endif /* FINIT_HELPERS_H_ */
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "finit.h"
|
||||
#include "signal.h" /* do_shutdown() */
|
||||
|
||||
#define INIT_MAGIC 0x03091969
|
||||
#define INIT_CMD_RUNLVL 1
|
||||
|
||||
@@ -35,10 +35,11 @@
|
||||
#include <sys/wait.h> /* wait() */
|
||||
|
||||
#include "finit.h"
|
||||
#include "helpers.h"
|
||||
#include "ipc.h"
|
||||
#include "svc.h"
|
||||
#include "service.h"
|
||||
#include "helpers.h"
|
||||
#include "signal.h"
|
||||
|
||||
static int dynamic_event_arg = 0; /* XXX: Fragile construct, refactor! --Jocke */
|
||||
static int sd = -1;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# Alternative boot method for other distributions than Debian 6.0
|
||||
# Place this file in a /etc/finit.d/ directory. At boot finit will
|
||||
# run all files, using its built-in run_parts(), in that directory.
|
||||
#
|
||||
# Here we chain load Debian /etc/rcS.d and /etc/rc2.d directories
|
||||
# in sequence using the standard run-parts tool.
|
||||
run-parts /etc/rcS.d --arg=start
|
||||
run-parts /etc/rc2.d --arg=start
|
||||
|
||||
# You can also place other commands in this services file, akin to
|
||||
# the old finit /usr/sbin/services.sh (not supported anymore).
|
||||
#service acpid start
|
||||
#service networking start
|
||||
#service ssh start
|
||||
@@ -43,48 +43,32 @@
|
||||
|
||||
#include "finit.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#define SETSIG(sa, sig, fun, flags) \
|
||||
do { \
|
||||
sa.sa_sigaction = fun; \
|
||||
sa.sa_flags = SA_SIGINFO | flags; \
|
||||
sigemptyset(&sa.sa_mask); \
|
||||
sigaction(sig, &sa, NULL); \
|
||||
} while (0)
|
||||
|
||||
#define IGNSIG(sa, sig, flags) \
|
||||
do { \
|
||||
sa.sa_handler = SIG_IGN; \
|
||||
sa.sa_flags = flags; \
|
||||
sigemptyset(&sa.sa_mask); \
|
||||
sigaction(sig, &sa, NULL); \
|
||||
} while (0)
|
||||
#include "signal.h"
|
||||
|
||||
static int stopped = 0;
|
||||
|
||||
|
||||
void do_shutdown (int sig)
|
||||
{
|
||||
touch(SYNC_SHUTDOWN);
|
||||
|
||||
if (sdown) {
|
||||
_d("Calling shutdown hook: %s", sdown);
|
||||
system(sdown);
|
||||
}
|
||||
if (sdown)
|
||||
run_interactive(sdown, "Calling shutdown hook: %s", sdown);
|
||||
|
||||
_d("Sending SIGTERM to all processes.");
|
||||
kill(-1, SIGTERM);
|
||||
sleep(2);
|
||||
system("/usr/sbin/alsactl store > /dev/null 2>&1");
|
||||
run_interactive("/usr/sbin/alsactl store > /dev/null 2>&1", "Saving sound settings");
|
||||
_d("Saving the system clock.");
|
||||
system("/sbin/hwclock --systohc");
|
||||
run_interactive("/sbin/hwclock --utc --systohc", "Saving system time (UTC) to RTC");
|
||||
_d("Sending SIGKILL to remaining processes.");
|
||||
kill(-1, SIGKILL);
|
||||
|
||||
sync();
|
||||
sync();
|
||||
_d("Unmounting file systems, remounting / read-only.");
|
||||
system("/bin/umount -fa 2>/dev/null");
|
||||
system("/bin/mount -n -o remount,ro / 2>/dev/null");
|
||||
run("/bin/umount -fa 2>/dev/null");
|
||||
run("/bin/mount -n -o remount,ro / 2>/dev/null");
|
||||
|
||||
_d("%s.", sig == SIGINT || sig == SIGUSR1 ? "Rebooting" : "Halting");
|
||||
if (sig == SIGINT || sig == SIGUSR1)
|
||||
@@ -146,7 +130,7 @@ int sig_stopped(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Inital signal setup - ignore everything until we're capable of responding
|
||||
* Inital signal setup - ignore everything but SIGCHLD until we're capable of responding
|
||||
*/
|
||||
void sig_init(void)
|
||||
{
|
||||
@@ -155,6 +139,8 @@ void sig_init(void)
|
||||
|
||||
for (i = 1; i < NSIG; i++)
|
||||
IGNSIG(sa, i, SA_RESTART);
|
||||
|
||||
SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -162,7 +148,6 @@ void sig_init(void)
|
||||
*/
|
||||
void sig_setup(void)
|
||||
{
|
||||
sigset_t nmask;
|
||||
struct sigaction sa;
|
||||
|
||||
_d("Setup signals");
|
||||
@@ -192,12 +177,6 @@ void sig_setup(void)
|
||||
SETSIG(sa, SIGSTOP, sigstop_handler, 0);
|
||||
SETSIG(sa, SIGTSTP, sigstop_handler, 0);
|
||||
SETSIG(sa, SIGCONT, sigcont_handler, 0);
|
||||
SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
|
||||
|
||||
/* Block SIGCHLD while forking */
|
||||
sigemptyset(&nmask);
|
||||
sigaddset(&nmask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &nmask, NULL);
|
||||
|
||||
/* Disable CTRL-ALT-DELETE from kernel, we handle shutdown gracefully with SIGINT, above */
|
||||
reboot(RB_DISABLE_CAD);
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/* Signal management - Be conservative with what finit responds to!
|
||||
*
|
||||
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FINIT_SIGNAL_H_
|
||||
#define FINIT_SIGNAL_H_
|
||||
|
||||
#define SYNC_SHUTDOWN "/var/lock/finit.shutdown"
|
||||
#define SYNC_STOPPED "/var/lock/finit.stopped"
|
||||
|
||||
#define SETSIG(sa, sig, fun, flags) \
|
||||
do { \
|
||||
sa.sa_sigaction = fun; \
|
||||
sa.sa_flags = SA_SIGINFO | flags; \
|
||||
sigemptyset(&sa.sa_mask); \
|
||||
sigaction(sig, &sa, NULL); \
|
||||
} while (0)
|
||||
|
||||
#define IGNSIG(sa, sig, flags) \
|
||||
do { \
|
||||
sa.sa_handler = SIG_IGN; \
|
||||
sa.sa_flags = flags; \
|
||||
sigemptyset(&sa.sa_mask); \
|
||||
sigaction(sig, &sa, NULL); \
|
||||
} while (0)
|
||||
|
||||
#define DFLSIG(sa, sig, flags) \
|
||||
do { \
|
||||
sa.sa_handler = SIG_DFL; \
|
||||
sa.sa_flags = flags; \
|
||||
sigemptyset(&sa.sa_mask); \
|
||||
sigaction(sig, &sa, NULL); \
|
||||
} while (0)
|
||||
|
||||
void do_shutdown (int sig);
|
||||
int sig_stopped (void);
|
||||
void sig_init (void);
|
||||
void sig_setup (void);
|
||||
|
||||
#endif /* FINIT_SIGNAL_H_ */
|
||||
|
||||
/**
|
||||
* Local Variables:
|
||||
* version-control: t
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
Reference in New Issue
Block a user