Add in a new restart init target, triggered by SIGHUP. Patch from
authorEric Andersen <andersen@codepoet.org>
Mon, 17 Dec 2001 23:13:08 +0000 (23:13 -0000)
committerEric Andersen <andersen@codepoet.org>
Mon, 17 Dec 2001 23:13:08 +0000 (23:13 -0000)
Russ Dill, with adjustments by me.
 -Erik

examples/inittab
include/usage.h
init/init.c

index 45f5a61..4eed848 100644 (file)
@@ -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
index b84cdd5..a970c0f 100644 (file)
 "      ::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" \
 "      <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" \
 "                      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" \
 "      # 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" \
index d0beb2a..f6108f1 100644 (file)
@@ -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);