mirror of
https://github.com/troglobit/finit.git
synced 2026-11-02 13:20:32 +00: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:
1 parent
d21dc2b477
commit
077a7e82e0
13 files changed
+296
-131
No files matched your search
@@ -36,7 +36,6 @@ CFLAGS += -W -Wall -Werror -Os
|
|||||||
# Disable annoying gcc warning for "warn_unused_result", see GIT 37af997
|
# Disable annoying gcc warning for "warn_unused_result", see GIT 37af997
|
||||||
CPPFLAGS += -U_FORTIFY_SOURCE
|
CPPFLAGS += -U_FORTIFY_SOURCE
|
||||||
CPPFLAGS += -I$(ROOTDIR)/$(CONFIG_LINUXDIR)/include/
|
CPPFLAGS += -I$(ROOTDIR)/$(CONFIG_LINUXDIR)/include/
|
||||||
CPPFLAGS += -DBUILTIN_RUNPARTS
|
|
||||||
CPPFLAGS += -DVERSION=\"$(VERSION)\" -DWHOAMI=\"`whoami`@`hostname`\"
|
CPPFLAGS += -DVERSION=\"$(VERSION)\" -DWHOAMI=\"`whoami`@`hostname`\"
|
||||||
CPPFLAGS += -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE
|
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 "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
|
#include "signal.h"
|
||||||
|
|
||||||
int debug = 0;
|
int debug = 0;
|
||||||
|
int verbose = 1;
|
||||||
char *sdown = NULL;
|
char *sdown = NULL;
|
||||||
char *network = NULL;
|
char *network = NULL;
|
||||||
char *startx = NULL;
|
char *startx = NULL;
|
||||||
@@ -105,27 +107,22 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
* Populate /dev and prepare for runtime events from kernel.
|
* Populate /dev and prepare for runtime events from kernel.
|
||||||
*/
|
*/
|
||||||
#if defined(USE_UDEV)
|
#if defined(USE_UDEV)
|
||||||
system("udevd --daemon");
|
run_interactive("udevd --daemon", "Populating device tree");
|
||||||
#elif defined (MDEV)
|
#elif defined (MDEV)
|
||||||
system(MDEV "-s");
|
run_interactive(MDEV "-s", "Populating device tree");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse kernel parameters
|
* Parse kernel parameters
|
||||||
*/
|
*/
|
||||||
if ((fp = fopen("/proc/cmdline", "r")) != NULL) {
|
if ((fp = fopen("/proc/cmdline", "r")) != NULL) {
|
||||||
fgets(line, LINE_SIZE, fp);
|
fgets(line, sizeof(line), fp);
|
||||||
|
|
||||||
if (strstr(line, "finit_debug") ||
|
if (strstr(line, "finit_debug") || strstr(line, "--debug"))
|
||||||
strstr(line, "--verbose") ||
|
|
||||||
strstr(line, "--debug"))
|
|
||||||
debug = 1;
|
debug = 1;
|
||||||
|
|
||||||
if (!debug && strstr(line, "quiet")) {
|
if (!debug && strstr(line, "quiet"))
|
||||||
close(0);
|
verbose = 0;
|
||||||
close(1);
|
|
||||||
close(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
@@ -141,7 +138,7 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
|
|
||||||
_d("Parse %s ...", FINIT_CONF);
|
_d("Parse %s ...", FINIT_CONF);
|
||||||
while (!feof(fp)) {
|
while (!feof(fp)) {
|
||||||
if (!fgets(line, LINE_SIZE, fp))
|
if (!fgets(line, sizeof(line), fp))
|
||||||
continue;
|
continue;
|
||||||
chomp(line);
|
chomp(line);
|
||||||
|
|
||||||
@@ -155,7 +152,7 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
if (MATCH_CMD(line, "check ", x)) {
|
if (MATCH_CMD(line, "check ", x)) {
|
||||||
strcpy(cmd, "/sbin/fsck -C -a ");
|
strcpy(cmd, "/sbin/fsck -C -a ");
|
||||||
build_cmd(cmd, x, CMD_SIZE);
|
build_cmd(cmd, x, CMD_SIZE);
|
||||||
system(cmd);
|
run_interactive(cmd, "Checking file system integrity on %s", x);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MATCH_CMD(line, "user ", x)) {
|
if (MATCH_CMD(line, "user ", x)) {
|
||||||
@@ -176,13 +173,13 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
if (MATCH_CMD(line, "module ", x)) {
|
if (MATCH_CMD(line, "module ", x)) {
|
||||||
strcpy(cmd, "/sbin/modprobe ");
|
strcpy(cmd, "/sbin/modprobe ");
|
||||||
build_cmd(cmd, x, CMD_SIZE);
|
build_cmd(cmd, x, CMD_SIZE);
|
||||||
system(cmd);
|
run_interactive(cmd, " Loading module %s", x);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MATCH_CMD(line, "mknod ", x)) {
|
if (MATCH_CMD(line, "mknod ", x)) {
|
||||||
strcpy(cmd, "/bin/mknod ");
|
strcpy(cmd, "/bin/mknod ");
|
||||||
build_cmd(cmd, x, CMD_SIZE);
|
build_cmd(cmd, x, CMD_SIZE);
|
||||||
system(cmd);
|
run_interactive(cmd, " Creating device node %s", x);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MATCH_CMD(line, "network ", x)) {
|
if (MATCH_CMD(line, "network ", x)) {
|
||||||
@@ -210,18 +207,18 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
_d("Mount filesystems in /etc/fstab ...");
|
_d("Mount filesystems in /etc/fstab ...");
|
||||||
|
|
||||||
#ifdef REMOUNT_ROOTFS_RW
|
#ifdef REMOUNT_ROOTFS_RW
|
||||||
system("/bin/mount -n -o remount,rw /");
|
run("/bin/mount -n -o remount,rw /");
|
||||||
#endif
|
#endif
|
||||||
#ifdef SYSROOT
|
#ifdef SYSROOT
|
||||||
mount(SYSROOT, "/", NULL, MS_MOVE, NULL);
|
run(SYSROOT, "/", NULL, MS_MOVE, NULL);
|
||||||
#endif
|
#endif
|
||||||
umask(0);
|
umask(0);
|
||||||
system("mount -na");
|
run("mount -na");
|
||||||
system("swapon -ea");
|
run("swapon -ea");
|
||||||
umask(0022);
|
umask(0022);
|
||||||
|
|
||||||
/* Cleanup stale files, if any still linger on. */
|
/* 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
|
* Base FS up, enable standard SysV init signals
|
||||||
@@ -233,7 +230,7 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
*/
|
*/
|
||||||
#ifndef NO_HCTOSYS
|
#ifndef NO_HCTOSYS
|
||||||
_d("Adjust system clock ...");
|
_d("Adjust system clock ...");
|
||||||
system("/sbin/hwclock --hctosys");
|
run_interactive("/sbin/hwclock --hctosys", "Restoring system clock (UTC) from RTC");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -248,7 +245,7 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
while ((d = readdir(dir)) != NULL) {
|
while ((d = readdir(dir)) != NULL) {
|
||||||
if (isalnum(d->d_name[0]))
|
if (isalnum(d->d_name[0]))
|
||||||
continue;
|
continue;
|
||||||
snprintf(line, LINE_SIZE,
|
snprintf(line, sizeof(line),
|
||||||
"/etc/resolvconf/run/interface/%s", d->d_name);
|
"/etc/resolvconf/run/interface/%s", d->d_name);
|
||||||
unlink(line);
|
unlink(line);
|
||||||
}
|
}
|
||||||
@@ -279,11 +276,7 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
touch("/etc/resolvconf/run/enable-updates");
|
touch("/etc/resolvconf/run/enable-updates");
|
||||||
|
|
||||||
chdir("/etc/resolvconf/run/interface");
|
chdir("/etc/resolvconf/run/interface");
|
||||||
#ifdef BUILTIN_RUNPARTS
|
|
||||||
run_parts("/etc/resolvconf/update.d", "-i", NULL);
|
run_parts("/etc/resolvconf/update.d", "-i", NULL);
|
||||||
#else
|
|
||||||
system(RUNPARTS " --arg=i /etc/resolvconf/update.d");
|
|
||||||
#endif /* BUILTIN_RUNPARTS */
|
|
||||||
chdir("/");
|
chdir("/");
|
||||||
#endif /* USE_ETC_RESOLVCONF_RUN */
|
#endif /* USE_ETC_RESOLVCONF_RUN */
|
||||||
|
|
||||||
@@ -293,14 +286,15 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
remove("/etc/network/run/ifstate");
|
remove("/etc/network/run/ifstate");
|
||||||
#endif
|
#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 initial hostname. */
|
||||||
set_hostname(hostname);
|
set_hostname(hostname);
|
||||||
|
|
||||||
ifconfig("lo", "127.0.0.1", "255.0.0.0", 1);
|
ifconfig("lo", "127.0.0.1", "255.0.0.0", 1);
|
||||||
if (network) {
|
if (network)
|
||||||
_d("Starting networking: %s", network);
|
run_interactive(network, "Starting networking: %s", network);
|
||||||
system(network);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set random seed
|
* Set random seed
|
||||||
@@ -317,14 +311,14 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
* Console setup (for X)
|
* Console setup (for X)
|
||||||
*/
|
*/
|
||||||
makepath("/var/run/console");
|
makepath("/var/run/console");
|
||||||
snprintf(line, LINE_SIZE, "/var/run/console/%s", username);
|
snprintf(line, sizeof(line), "/var/run/console/%s", username);
|
||||||
touch(line);
|
touch(line);
|
||||||
|
|
||||||
#ifdef PAM_CONSOLE
|
#ifdef PAM_CONSOLE
|
||||||
if ((fd = open("/var/run/console/console.lock", O_CREAT|O_WRONLY|O_TRUNC, 0644)) >= 0) {
|
if ((fd = open("/var/run/console/console.lock", O_CREAT|O_WRONLY|O_TRUNC, 0644)) >= 0) {
|
||||||
write(fd, username, strlen(username));
|
write(fd, username, strlen(username));
|
||||||
close(fd);
|
close(fd);
|
||||||
system("/sbin/pam_console_apply");
|
run("/sbin/pam_console_apply");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -333,15 +327,18 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
*/
|
*/
|
||||||
mkdir("/tmp/.X11-unix", 01777);
|
mkdir("/tmp/.X11-unix", 01777);
|
||||||
mkdir("/tmp/.ICE-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);
|
umask(022);
|
||||||
|
|
||||||
#ifdef USE_MESSAGE_BUS
|
#ifdef USE_MESSAGE_BUS
|
||||||
_d("Starting D-Bus ...");
|
_d("Starting D-Bus ...");
|
||||||
mkdir("/var/run/dbus", 0755);
|
mkdir("/var/run/dbus", 0755);
|
||||||
mkdir("/var/lock/subsys/messagebus", 0755);
|
mkdir("/var/lock/subsys/messagebus", 0755);
|
||||||
system("dbus-uuidgen --ensure");
|
run("dbus-uuidgen --ensure");
|
||||||
system("su -c \"dbus-daemon --system\" messagebus");
|
remove("/var/run/dbus/pid");
|
||||||
|
run_interactive("dbus-daemon --system", "Starting D-Bus");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_d("Starting services from %s", FINIT_CONF);
|
_d("Starting services from %s", FINIT_CONF);
|
||||||
@@ -396,7 +393,8 @@ int main(int UNUSED(args), char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (startx && !debug) {
|
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);
|
system(line);
|
||||||
} else {
|
} else {
|
||||||
static const char msg[] = "\nPlease press Enter to activate this console. ";
|
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))
|
if (fexist(SYNC_STOPPED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
system(GETTY);
|
run(GETTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-6
@@ -1,6 +1,13 @@
|
|||||||
user fred
|
# Simple Debian finit.conf
|
||||||
module intel-agp
|
check /dev/vda1
|
||||||
module p4-clockmod
|
module tipc
|
||||||
check /dev/sda3
|
module evdev
|
||||||
host eviltwin
|
module loop
|
||||||
startx /usr/bin/startx
|
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
|
# define USE_MESSAGE_BUS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SYNC_SHUTDOWN "/var/lock/finit.shutdown"
|
|
||||||
#define SYNC_STOPPED "/var/lock/finit.stopped"
|
|
||||||
|
|
||||||
#ifndef DEFUSER
|
#ifndef DEFUSER
|
||||||
# define DEFUSER "root"
|
# define DEFUSER "root"
|
||||||
#endif
|
#endif
|
||||||
@@ -105,8 +102,9 @@
|
|||||||
# define DEFHOST "noname"
|
# define DEFHOST "noname"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CMD_SIZE 256
|
||||||
#define LINE_SIZE 1024
|
#define LINE_SIZE 1024
|
||||||
#define CMD_SIZE 256
|
#define BUF_SIZE 4096
|
||||||
#define USERNAME_SIZE 16
|
#define USERNAME_SIZE 16
|
||||||
#define HOSTNAME_SIZE 32
|
#define HOSTNAME_SIZE 32
|
||||||
|
|
||||||
@@ -131,20 +129,15 @@
|
|||||||
#define MATCH_CMD(l, c, x) \
|
#define MATCH_CMD(l, c, x) \
|
||||||
(!strncmp(l, c, strlen(c)) && (x = (l) + strlen(c)))
|
(!strncmp(l, c, strlen(c)) && (x = (l) + strlen(c)))
|
||||||
|
|
||||||
#define echo(fmt, args...) do { fprintf(stderr, fmt "\n", ##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 _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 _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)
|
#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 debug;
|
||||||
|
extern int verbose;
|
||||||
extern char *sdown;
|
extern char *sdown;
|
||||||
|
|
||||||
/* signal.c */
|
|
||||||
void do_shutdown (int sig);
|
|
||||||
int sig_stopped (void);
|
|
||||||
void sig_init (void);
|
|
||||||
void sig_setup (void);
|
|
||||||
|
|
||||||
/* initctl.c */
|
/* initctl.c */
|
||||||
void listen_initctl (void);
|
void listen_initctl (void);
|
||||||
|
|
||||||
|
|||||||
@@ -37,17 +37,19 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#ifdef BUILTIN_RUNPARTS
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.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
|
* Helpers to replace system() calls
|
||||||
@@ -101,7 +103,6 @@ void ifconfig(char *name, char *inet, char *mask, int up)
|
|||||||
close(sock);
|
close(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BUF_SIZE 4096
|
|
||||||
|
|
||||||
void copyfile(char *src, char *dst, int size)
|
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)
|
int start_process(char *cmd, char *args[], int console)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
sigset_t nmask, omask;
|
|
||||||
|
|
||||||
if (sig_stopped())
|
if (sig_stopped())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Block SIGCHLD while forking. */
|
|
||||||
sigemptyset(&nmask);
|
|
||||||
sigaddset(&nmask, SIGCHLD);
|
|
||||||
sigprocmask(SIG_BLOCK, &nmask, &omask);
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
int i;
|
int i;
|
||||||
struct sigaction act;
|
struct sigaction sa;
|
||||||
|
|
||||||
/* Reset signal handlers that were set by the parent process */
|
/* Reset signal handlers that were set by the parent process */
|
||||||
sigemptyset(&act.sa_mask);
|
for (i = 1; i < NSIG; i++)
|
||||||
act.sa_handler = SIG_DFL;
|
DFLSIG(sa, i, 0);
|
||||||
|
|
||||||
sigemptyset(&nmask);
|
|
||||||
sigaddset(&nmask, SIGCHLD);
|
|
||||||
sigprocmask(SIG_UNBLOCK, &nmask, NULL);
|
|
||||||
|
|
||||||
for (i = 1; i < NSIG; i++)
|
|
||||||
sigaction(i, &act, NULL);
|
|
||||||
|
|
||||||
if (console) {
|
if (console) {
|
||||||
int fd = open (CONSOLE, O_WRONLY | O_APPEND);
|
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);
|
exit(!console ? print_result(0) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pid;
|
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 */
|
/* We must create a copy that is possible to modify. */
|
||||||
#define NUM_ARGS 16
|
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)
|
static int cmp(const void *s1, const void *s2)
|
||||||
{
|
{
|
||||||
@@ -293,7 +414,6 @@ int run_parts(char *dir, ...)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* BUILTIN_RUNPARTS */
|
|
||||||
|
|
||||||
int getuser(char *s)
|
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);
|
int kill_procname (const char *name, int signo);
|
||||||
void set_hostname (char *hostname);
|
void set_hostname (char *hostname);
|
||||||
|
|
||||||
#ifdef BUILTIN_RUNPARTS
|
int run (char *cmd);
|
||||||
|
int run_interactive (char *cmd, char *fmt, ...);
|
||||||
int run_parts (char *dir, ...);
|
int run_parts (char *dir, ...);
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* FINIT_HELPERS_H_ */
|
#endif /* FINIT_HELPERS_H_ */
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
|
#include "signal.h" /* do_shutdown() */
|
||||||
|
|
||||||
#define INIT_MAGIC 0x03091969
|
#define INIT_MAGIC 0x03091969
|
||||||
#define INIT_CMD_RUNLVL 1
|
#define INIT_CMD_RUNLVL 1
|
||||||
|
|||||||
@@ -35,10 +35,11 @@
|
|||||||
#include <sys/wait.h> /* wait() */
|
#include <sys/wait.h> /* wait() */
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
|
#include "helpers.h"
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "helpers.h"
|
#include "signal.h"
|
||||||
|
|
||||||
static int dynamic_event_arg = 0; /* XXX: Fragile construct, refactor! --Jocke */
|
static int dynamic_event_arg = 0; /* XXX: Fragile construct, refactor! --Jocke */
|
||||||
static int sd = -1;
|
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 "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
#include "signal.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)
|
|
||||||
|
|
||||||
static int stopped = 0;
|
static int stopped = 0;
|
||||||
|
|
||||||
|
|
||||||
void do_shutdown (int sig)
|
void do_shutdown (int sig)
|
||||||
{
|
{
|
||||||
touch(SYNC_SHUTDOWN);
|
touch(SYNC_SHUTDOWN);
|
||||||
|
|
||||||
if (sdown) {
|
if (sdown)
|
||||||
_d("Calling shutdown hook: %s", sdown);
|
run_interactive(sdown, "Calling shutdown hook: %s", sdown);
|
||||||
system(sdown);
|
|
||||||
}
|
|
||||||
|
|
||||||
_d("Sending SIGTERM to all processes.");
|
_d("Sending SIGTERM to all processes.");
|
||||||
kill(-1, SIGTERM);
|
kill(-1, SIGTERM);
|
||||||
sleep(2);
|
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.");
|
_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.");
|
_d("Sending SIGKILL to remaining processes.");
|
||||||
kill(-1, SIGKILL);
|
kill(-1, SIGKILL);
|
||||||
|
|
||||||
sync();
|
sync();
|
||||||
sync();
|
sync();
|
||||||
_d("Unmounting file systems, remounting / read-only.");
|
_d("Unmounting file systems, remounting / read-only.");
|
||||||
system("/bin/umount -fa 2>/dev/null");
|
run("/bin/umount -fa 2>/dev/null");
|
||||||
system("/bin/mount -n -o remount,ro / 2>/dev/null");
|
run("/bin/mount -n -o remount,ro / 2>/dev/null");
|
||||||
|
|
||||||
_d("%s.", sig == SIGINT || sig == SIGUSR1 ? "Rebooting" : "Halting");
|
_d("%s.", sig == SIGINT || sig == SIGUSR1 ? "Rebooting" : "Halting");
|
||||||
if (sig == SIGINT || sig == SIGUSR1)
|
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)
|
void sig_init(void)
|
||||||
{
|
{
|
||||||
@@ -155,6 +139,8 @@ void sig_init(void)
|
|||||||
|
|
||||||
for (i = 1; i < NSIG; i++)
|
for (i = 1; i < NSIG; i++)
|
||||||
IGNSIG(sa, i, SA_RESTART);
|
IGNSIG(sa, i, SA_RESTART);
|
||||||
|
|
||||||
|
SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -162,7 +148,6 @@ void sig_init(void)
|
|||||||
*/
|
*/
|
||||||
void sig_setup(void)
|
void sig_setup(void)
|
||||||
{
|
{
|
||||||
sigset_t nmask;
|
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
_d("Setup signals");
|
_d("Setup signals");
|
||||||
@@ -192,12 +177,6 @@ void sig_setup(void)
|
|||||||
SETSIG(sa, SIGSTOP, sigstop_handler, 0);
|
SETSIG(sa, SIGSTOP, sigstop_handler, 0);
|
||||||
SETSIG(sa, SIGTSTP, sigstop_handler, 0);
|
SETSIG(sa, SIGTSTP, sigstop_handler, 0);
|
||||||
SETSIG(sa, SIGCONT, sigcont_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 */
|
/* Disable CTRL-ALT-DELETE from kernel, we handle shutdown gracefully with SIGINT, above */
|
||||||
reboot(RB_DISABLE_CAD);
|
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