[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: [BusyBox] another init.c complication
From: Tom Oehser <tom () toms ! net>
Date: 2002-04-27 10:12:03
[Download RAW message or body]
Another complication turns out to be that init deletes actions
from the list, rather than marking them run, so the reload has
no way to know they aren't updates. I think I'm going to just
start in on major butchery, here is what I had so far, which
behaves as expected as long as all the run-once things have
the same null ID as something (anything) that hangs around
(like a ctrl-alt-del action). I think it really needs a
status field that changes to 'done' without deleting.
What I have so far:
--- ../../busybox-cvs-rb2/busybox/init/init.c Fri Mar 29 00:59:44 2002
+++ init/init.c Sat Apr 27 16:06:31 2002
@@ -1,5 +1,5 @@
/* vi: set sw=4 ts=4: */
-/*
+/*
* Mini init implementation for busybox
*
*
@@ -37,6 +37,7 @@
#include <termios.h>
#include <unistd.h>
#include <limits.h>
+#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
@@ -153,10 +154,12 @@
char terminal[256];
struct init_action *next;
int action;
+ char id[3];
};
/* Static variables */
static struct init_action *init_action_list = NULL;
+static char first_time = '1';
static char *secondConsole = VC_2;
static char *thirdConsole = VC_3;
static char *fourthConsole = VC_4;
@@ -499,6 +502,7 @@
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGHUP, SIG_DFL);
+ signal(SIGURG, SIG_DFL);
signal(SIGCONT, SIG_DFL);
signal(SIGSTOP, SIG_DFL);
signal(SIGTSTP, SIG_DFL);
@@ -718,6 +722,7 @@
/* first disable all our signals */
sigemptyset(&block_signals);
sigaddset(&block_signals, SIGHUP);
+ sigaddset(&block_signals, SIGURG);
sigaddset(&block_signals, SIGCHLD);
sigaddset(&block_signals, SIGUSR1);
sigaddset(&block_signals, SIGUSR2);
@@ -839,7 +844,7 @@
#endif /* ! DEBUG_INIT */
-static void new_init_action(int action, char *command, char *cons)
+static void new_init_action(int action, char *command, char *cons, char *id)
{
struct init_action *new_action, *a;
@@ -856,6 +861,11 @@
if (strcmp(cons, "/dev/null") == 0 && (action & ASKFIRST))
return;
+ if (! first_time)
+ for (a = init_action_list; a && a->next; a = a->next)
+ if (!strcmp(a->id, id))
+ return;
+
new_action = calloc((size_t) (1), sizeof(struct init_action));
if (!new_action) {
message(LOG | CONSOLE, "\rMemory allocation failure\n");
@@ -873,6 +883,7 @@
new_action->action = action;
safe_strncpy(new_action->terminal, cons, 255);
new_action->pid = 0;
+ safe_strncpy(new_action->id, id, 255);
// message(LOG|CONSOLE, "command='%s' action='%d' terminal='%s'\n",
// new_action->command, new_action->action, new_action->terminal);
}
@@ -906,42 +917,40 @@
#ifdef CONFIG_FEATURE_USE_INITTAB
FILE *file;
char buf[256], lineAsRead[256], tmpConsole[256];
- char *id, *runlev, *action, *command, *eol;
+ char *id, *runlev, *action, *command, *eol, *tty;
const struct init_action_type *a = actions;
int foundIt;
-
+ struct stat staat; // we really junk it and could use some other buffer
file = fopen(INITTAB, "r");
if (file == NULL) {
/* No inittab file -- set up some default behavior */
#endif
/* Reboot on Ctrl-Alt-Del */
- new_init_action(CTRLALTDEL, "/sbin/reboot", console);
+ new_init_action(CTRLALTDEL, "/sbin/reboot", console, "1");
/* Umount all filesystems on halt/reboot */
- new_init_action(SHUTDOWN, "/bin/umount -a -r", console);
+ new_init_action(SHUTDOWN, "/bin/umount -a -r", console, "2");
#if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__)
/* Swapoff on halt/reboot */
- new_init_action(SHUTDOWN, "/sbin/swapoff -a", console);
+ new_init_action(SHUTDOWN, "/sbin/swapoff -a", console, "3");
#endif
/* Prepare to restart init when a HUP is received */
- new_init_action(RESTART, "/sbin/init", console);
+ new_init_action(RESTART, "/sbin/init", console, "4");
/* Askfirst shell on tty1 */
- new_init_action(ASKFIRST, LOGIN_SHELL, console);
+ new_init_action(ASKFIRST, LOGIN_SHELL, console, "5");
/* Askfirst shell on tty2 */
if (secondConsole != NULL)
- new_init_action(ASKFIRST, LOGIN_SHELL, secondConsole);
+ new_init_action(ASKFIRST, LOGIN_SHELL, secondConsole, "6");
/* Askfirst shell on tty3 */
if (thirdConsole != NULL)
- new_init_action(ASKFIRST, LOGIN_SHELL, thirdConsole);
+ new_init_action(ASKFIRST, LOGIN_SHELL, thirdConsole, "7");
/* Askfirst shell on tty4 */
if (fourthConsole != NULL)
- new_init_action(ASKFIRST, LOGIN_SHELL, fourthConsole);
+ new_init_action(ASKFIRST, LOGIN_SHELL, fourthConsole, "8");
/* sysinit */
- new_init_action(SYSINIT, INIT_SCRIPT, console);
-
- return;
-#ifdef CONFIG_FEATURE_USE_INITTAB
+ new_init_action(SYSINIT, INIT_SCRIPT, console, "9");
}
+#ifdef CONFIG_FEATURE_USE_INITTAB
while (fgets(buf, 255, file) != NULL) {
foundIt = FALSE;
@@ -990,16 +999,31 @@
++command;
}
+ /* Separate the id from the tty */
+ if (*id == '\0') { // we got nothing
+ tty=id; // maybe hash or checksum the line for ID ?
+ } else {
+ tty=id; // default use as both
+// figure out whether our entry is the tty
+ strcpy(tmpConsole, "/dev/");
+ strncat(tmpConsole, tty, 200);
+ if (stat(tmpConsole,&staat)) { // treat as id only
+ tty=NULL;
+ } else {
+ // it can be both
+ }
+ }
+
/* Ok, now process it */
a = actions;
while (a->name != 0) {
if (strcmp(a->name, action) == 0) {
- if (*id != '\0') {
+ if (*tty != '\0') {
strcpy(tmpConsole, "/dev/");
- strncat(tmpConsole, id, 200);
- id = tmpConsole;
+ strncat(tmpConsole, tty, 200);
+ tty = tmpConsole;
}
- new_init_action(a->action, command, id);
+ new_init_action(a->action, command, tty, id);
foundIt = TRUE;
}
a++;
@@ -1011,11 +1035,16 @@
message(LOG | CONSOLE, "\rBad inittab entry: %s\n", lineAsRead);
}
}
- return;
#endif /* CONFIG_FEATURE_USE_INITTAB */
+ first_time = '\0';
+ return;
}
-
+static void reload_signal(int sig)
+{
+ parse_inittab();
+ signal(SIGHUP, reload_signal);
+}
extern int init_main(int argc, char **argv)
{
@@ -1023,6 +1052,18 @@
pid_t wpid;
int status;
+ if (argc > 1 && !strcmp(argv[1], "-r")) {
+ /* don't assume init's pid == 1 */
+ long *pid = find_pid_by_name("init");
+ if (!pid || *pid<=0) {
+ pid = find_pid_by_name("linuxrc");
+ if (!pid || *pid<=0)
+ error_msg_and_die("no process killed");
+ }
+ kill(*pid, SIGURG);
+ exit(0);
+ }
+
if (argc > 1 && !strcmp(argv[1], "-q")) {
/* don't assume init's pid == 1 */
long *pid = find_pid_by_name("init");
@@ -1047,7 +1088,8 @@
}
/* Set up sig handlers -- be sure to
* clear all of these in run() */
- signal(SIGHUP, exec_signal);
+ signal(SIGHUP, reload_signal);
+ signal(SIGURG, exec_signal);
signal(SIGUSR1, halt_signal);
signal(SIGUSR2, halt_signal);
signal(SIGINT, ctrlaltdel_signal);
@@ -1090,13 +1132,13 @@
!strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) {
/* Ask first then start a shell on tty2-4 */
if (secondConsole != NULL)
- new_init_action(ASKFIRST, LOGIN_SHELL, secondConsole);
+ new_init_action(ASKFIRST, LOGIN_SHELL, secondConsole, "1");
if (thirdConsole != NULL)
- new_init_action(ASKFIRST, LOGIN_SHELL, thirdConsole);
+ new_init_action(ASKFIRST, LOGIN_SHELL, thirdConsole, "2");
if (fourthConsole != NULL)
- new_init_action(ASKFIRST, LOGIN_SHELL, fourthConsole);
+ new_init_action(ASKFIRST, LOGIN_SHELL, fourthConsole, "3");
/* Start a shell on tty1 */
- new_init_action(RESPAWN, LOGIN_SHELL, console);
+ new_init_action(RESPAWN, LOGIN_SHELL, console, "4");
} else {
/* Not in single user mode -- see what inittab says */
@@ -1139,7 +1181,7 @@
sleep(1);
/* Wait for a child process to exit */
- wpid = wait(&status);
+ wpid = waitpid(-1, &status, WNOHANG);
if (wpid > 0) {
/* Find out who died and clean up their corpse */
for (a = init_action_list; a; a = a->next) {
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic