aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/inittab7
-rw-r--r--include/usage.h11
-rw-r--r--init/init.c33
3 files changed, 47 insertions, 4 deletions
diff --git a/examples/inittab b/examples/inittab
index 45f5a61fe..4eed84885 100644
--- a/examples/inittab
+++ b/examples/inittab
@@ -24,7 +24,7 @@
# <runlevels>: The runlevels field is completely ignored.
#
# <action>: Valid actions include: sysinit, respawn, askfirst, wait, once,
-# ctrlaltdel, and shutdown.
+# restart, ctrlaltdel, and shutdown.
#
# Note: askfirst acts just like respawn, but before running the specified
# process it displays the line "Please press Enter to activate this
@@ -43,6 +43,8 @@
# ::ctrlaltdel:/sbin/reboot
# ::shutdown:/sbin/swapoff -a
# ::shutdown:/bin/umount -a -r
+# ::restart:/sbin/init
+#
# if it detects that /dev/console is _not_ a serial console, it will
# also run:
# tty2::askfirst:/bin/sh
@@ -79,6 +81,9 @@ tty5::respawn:/sbin/getty 38400 tty6
# Example how to put a getty on a modem line.
#::respawn:/sbin/getty 57600 ttyS2
+# Stuff to do when restarting the init process
+::restart:/sbin/init
+
# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
diff --git a/include/usage.h b/include/usage.h
index b84cdd5e3..a970c0f9c 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -765,6 +765,7 @@
" ::ctrlaltdel:/sbin/reboot\n" \
" ::shutdown:/sbin/swapoff -a\n" \
" ::shutdown:/bin/umount -a -r\n" \
+" ::restart:/sbin/init\n" \
"\n" \
"if it detects that /dev/console is _not_ a serial console, it will also run:\n" \
"\n" \
@@ -796,7 +797,7 @@
" <action>: \n" \
"\n" \
" Valid actions include: sysinit, respawn, askfirst, wait, \n" \
-" once, ctrlaltdel, and shutdown.\n" \
+" once, restart, ctrlaltdel, and shutdown.\n" \
"\n" \
" The available actions can be classified into two groups: actions\n" \
" that are run only once, and actions that are re-run when the specified\n" \
@@ -809,7 +810,10 @@
" completion of all sysinit actions, all 'wait' actions are run.\n" \
" 'wait' actions, like 'sysinit' actions, cause init to wait until\n" \
" the specified task completes. 'once' actions are asynchronous,\n" \
-" therefore, init does not wait for them to complete. 'ctrlaltdel'\n" \
+" therefore, init does not wait for them to complete. 'restart' is\n" \
+" the action taken to restart the init process. By default this should\n" \
+" simply run /sbin/init, but can be a script which runs pivot_root or it\n" \
+" can do all sorts of other interesting things. The 'ctrlaltdel' init\n" \
" actions are run when the system detects that someone on the system\n" \
" console has pressed the CTRL-ALT-DEL key combination. Typically one\n" \
" wants to run 'reboot' at this point to cause the system to reboot.\n" \
@@ -865,6 +869,9 @@
" # Example how to put a getty on a modem line.\n" \
" #::respawn:/sbin/getty 57600 ttyS2\n" \
" \n" \
+" # Stuff to do when restarting the init process\n" \
+" ::restart:/sbin/init\n" \
+" \n" \
" # Stuff to do before rebooting\n" \
" ::ctrlaltdel:/sbin/reboot\n" \
" ::shutdown:/bin/umount -a -r\n" \
diff --git a/init/init.c b/init/init.c
index d0beb2a9a..f6108f1e8 100644
--- a/init/init.c
+++ b/init/init.c
@@ -142,7 +142,8 @@ typedef enum {
WAIT,
ONCE,
CTRLALTDEL,
- SHUTDOWN
+ SHUTDOWN,
+ RESTART
} initActionEnum;
/* A mapping between "inittab" action name strings and action type codes. */
@@ -159,6 +160,7 @@ static const struct initActionType actions[] = {
{"once", ONCE},
{"ctrlaltdel", CTRLALTDEL},
{"shutdown", SHUTDOWN},
+ {"restart", RESTART},
{0, 0}
};
@@ -688,6 +690,26 @@ static void shutdown_system(void)
}
}
+static void exec_signal(int sig)
+{
+ initAction *a, *tmp;
+ for (a = initActionList; a; a = tmp) {
+ tmp = a->nextPtr;
+ if (a->action == RESTART) {
+ shutdown_system();
+ message(CONSOLE|LOG, "Trying to re-exec %s\n", a->process);
+ execl(a->process, a->process, NULL);
+
+ message(CONSOLE|LOG, "execl of %s failed: %s\n",
+ a->process, sys_errlist[errno]);
+ sync();
+ sleep(2);
+ init_reboot(RB_HALT_SYSTEM);
+ loop_forever();
+ }
+ }
+}
+
static void halt_signal(int sig)
{
shutdown_system();
@@ -839,6 +861,8 @@ static void parse_inittab(void)
/* Swapoff on halt/reboot */
new_initAction(SHUTDOWN, "/sbin/swapoff -a", console);
#endif
+ /* Prepare to restart init when a HUP is received */
+ new_initAction(RESTART, "/sbin/init", console);
/* Askfirst shell on tty1 */
new_initAction(ASKFIRST, LOGIN_SHELL, console);
/* Askfirst shell on tty2 */
@@ -937,6 +961,12 @@ extern int init_main(int argc, char **argv)
pid_t wpid;
int status;
+
+ if (argc > 1 && !strcmp(argv[1], "-q")) {
+ kill(1, SIGHUP);
+ exit(0);
+ }
+
#ifndef DEBUG_INIT
/* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
if (getpid() != 1
@@ -949,6 +979,7 @@ extern int init_main(int argc, char **argv)
}
/* Set up sig handlers -- be sure to
* clear all of these in run() */
+ signal(SIGHUP, exec_signal);
signal(SIGUSR1, halt_signal);
signal(SIGUSR2, halt_signal);
signal(SIGINT, ctrlaltdel_signal);