From 730f826f25717c5db835ef738d4782e97b7b4720 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Mon, 17 Dec 2001 23:13:08 +0000 Subject: [PATCH] Add in a new restart init target, triggered by SIGHUP. Patch from Russ Dill, with adjustments by me. -Erik --- examples/inittab | 7 ++++++- include/usage.h | 11 +++++++++-- init/init.c | 33 ++++++++++++++++++++++++++++++++- 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 @@ # : The runlevels field is completely ignored. # # : 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 @@ " : \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);