A patch from Matt Kraai that adds a new 'shutdown' action to busybox init. Now

you can specify an arbitrary behavior for 'ctrlaltdel' without that behavior
needing to be a reboot.
This commit is contained in:
Eric Andersen 2001-04-03 18:01:51 +00:00
parent 0f0c0b41ce
commit c97ec34370
9 changed files with 103 additions and 46 deletions

View File

@ -1,7 +1,12 @@
0.51pre 0.51pre
* Erik Andersen -- added env applet * Erik Andersen -- added env applet
* Erik Andersen -- Split utility.c into libbb * Erik Andersen -- Split utility.c into libbb
* <fixme> * Andreas Neuhaus <andy@fasta.fh-dortmund.de> -- fix for merging
kernel command line environment variables into child environment
for init.c
* Matt Kraai -- Added a new 'shutdown' action to busybox init. Now
you can specify arbitrary behavior for 'ctrlaltdel' without that
behavior needing to be a reboot.
-Erik Andersen, not yet released -Erik Andersen, not yet released

View File

@ -663,10 +663,15 @@
"\n" \ "\n" \
" ::sysinit:/etc/init.d/rcS\n" \ " ::sysinit:/etc/init.d/rcS\n" \
" ::askfirst:/bin/sh\n" \ " ::askfirst:/bin/sh\n" \
" ::ctrlaltdel:/sbin/reboot\n" \
" ::shutdown:/sbin/swapoff -a\n" \
" ::shutdown:/bin/umount -a -r\n" \
"\n" \ "\n" \
"if it detects that /dev/console is _not_ a serial console, it will also run:\n" \ "if it detects that /dev/console is _not_ a serial console, it will also run:\n" \
"\n" \ "\n" \
" tty2::askfirst:/bin/sh\n" \ " tty2::askfirst:/bin/sh\n" \
" tty3::askfirst:/bin/sh\n" \
" tty4::askfirst:/bin/sh\n" \
"\n" \ "\n" \
"If you choose to use an /etc/inittab file, the inittab entry format is as follows:\n" \ "If you choose to use an /etc/inittab file, the inittab entry format is as follows:\n" \
"\n" \ "\n" \
@ -692,7 +697,7 @@
" <action>: \n" \ " <action>: \n" \
"\n" \ "\n" \
" Valid actions include: sysinit, respawn, askfirst, wait, \n" \ " Valid actions include: sysinit, respawn, askfirst, wait, \n" \
" once, and ctrlaltdel.\n" \ " once, ctrlaltdel, and shutdown.\n" \
"\n" \ "\n" \
" The available actions can be classified into two groups: actions\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" \ " that are run only once, and actions that are re-run when the specified\n" \
@ -706,9 +711,12 @@
" 'wait' actions, like 'sysinit' actions, cause init to wait until\n" \ " 'wait' actions, like 'sysinit' actions, cause init to wait until\n" \
" the specified task completes. 'once' actions are asyncronous,\n" \ " the specified task completes. 'once' actions are asyncronous,\n" \
" therefore, init does not wait for them to complete. 'ctrlaltdel'\n" \ " therefore, init does not wait for them to complete. 'ctrlaltdel'\n" \
" actions are run immediately before init causes the system to reboot\n" \ " actions are run when the system detects that someone on the system\n" \
" (unmounting filesystems with a 'ctrlaltdel' action is a very good\n" \ " console has pressed the CTRL-ALT-DEL key combination. Typically one\n" \
" idea).\n" \ " wants to run 'reboot' at this point to cause the system to reboot.\n" \
" Finally the 'shutdown' action specifies the actions to taken when\n" \
" init is told to reboot. Unmounting filesystems and disabling swap\n" \
" is a very good here\n" \
"\n" \ "\n" \
" Run repeatedly actions:\n" \ " Run repeatedly actions:\n" \
"\n" \ "\n" \
@ -759,8 +767,9 @@
" #::respawn:/sbin/getty 57600 ttyS2\n" \ " #::respawn:/sbin/getty 57600 ttyS2\n" \
" \n" \ " \n" \
" # Stuff to do before rebooting\n" \ " # Stuff to do before rebooting\n" \
" ::ctrlaltdel:/bin/umount -a -r\n" \ " ::ctrlaltdel:/sbin/reboot\n" \
" ::ctrlaltdel:/sbin/swapoff -a\n" " ::shutdown:/bin/umount -a -r\n" \
" ::shutdown:/sbin/swapoff -a\n"
#define insmod_trivial_usage \ #define insmod_trivial_usage \
"[OPTION]... MODULE [symbol=value]..." "[OPTION]... MODULE [symbol=value]..."

View File

@ -906,10 +906,15 @@ it has the following default behavior:
::sysinit:/etc/init.d/rcS ::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh ::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
if it detects that /dev/console is _not_ a serial console, it will also run: if it detects that /dev/console is _not_ a serial console, it will also run:
tty2::askfirst:/bin/sh tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
If you choose to use an /etc/inittab file, the inittab entry format is as follows: If you choose to use an /etc/inittab file, the inittab entry format is as follows:
@ -935,7 +940,7 @@ If you choose to use an /etc/inittab file, the inittab entry format is as follow
<action>: <action>:
Valid actions include: sysinit, respawn, askfirst, wait, Valid actions include: sysinit, respawn, askfirst, wait,
once, and ctrlaltdel. once, ctrlaltdel, and shutdown.
The available actions can be classified into two groups: actions The available actions can be classified into two groups: actions
that are run only once, and actions that are re-run when the specified that are run only once, and actions that are re-run when the specified
@ -949,9 +954,12 @@ If you choose to use an /etc/inittab file, the inittab entry format is as follow
'wait' actions, like 'sysinit' actions, cause init to wait until 'wait' actions, like 'sysinit' actions, cause init to wait until
the specified task completes. 'once' actions are asyncronous, the specified task completes. 'once' actions are asyncronous,
therefore, init does not wait for them to complete. 'ctrlaltdel' therefore, init does not wait for them to complete. 'ctrlaltdel'
actions are run immediately before init causes the system to reboot actions are run when the system detects that someone on the system
(unmounting filesystems with a 'ctrlaltdel' action is a very good console has pressed the CTRL-ALT-DEL key combination. Typically one
idea). wants to run 'reboot' at this point to cause the system to reboot.
Finally the 'shutdown' action specifies the actions to taken when
init is told to reboot. Unmounting filesystems and disabling swap
is a very good here.
Run repeatedly actions: Run repeatedly actions:
@ -984,10 +992,9 @@ Example /etc/inittab file:
tty4::respawn:/sbin/getty 38400 tty5 tty4::respawn:/sbin/getty 38400 tty5
tty5::respawn:/sbin/getty 38400 tty6 tty5::respawn:/sbin/getty 38400 tty6
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::ctrlaltdel:/bin/umount -a -r ::shutdown:/sbin/swapoff -a
::ctrlaltdel:/sbin/swapoff -a
------------------------------- -------------------------------
@ -2476,4 +2483,4 @@ Enrique Zanardi <ezanardi@ull.es>
=cut =cut
# $Id: busybox.pod,v 1.92 2001/03/15 21:20:25 markw Exp $ # $Id: busybox.pod,v 1.93 2001/04/03 18:01:51 andersen Exp $

View File

@ -663,10 +663,15 @@
"\n" \ "\n" \
" ::sysinit:/etc/init.d/rcS\n" \ " ::sysinit:/etc/init.d/rcS\n" \
" ::askfirst:/bin/sh\n" \ " ::askfirst:/bin/sh\n" \
" ::ctrlaltdel:/sbin/reboot\n" \
" ::shutdown:/sbin/swapoff -a\n" \
" ::shutdown:/bin/umount -a -r\n" \
"\n" \ "\n" \
"if it detects that /dev/console is _not_ a serial console, it will also run:\n" \ "if it detects that /dev/console is _not_ a serial console, it will also run:\n" \
"\n" \ "\n" \
" tty2::askfirst:/bin/sh\n" \ " tty2::askfirst:/bin/sh\n" \
" tty3::askfirst:/bin/sh\n" \
" tty4::askfirst:/bin/sh\n" \
"\n" \ "\n" \
"If you choose to use an /etc/inittab file, the inittab entry format is as follows:\n" \ "If you choose to use an /etc/inittab file, the inittab entry format is as follows:\n" \
"\n" \ "\n" \
@ -692,7 +697,7 @@
" <action>: \n" \ " <action>: \n" \
"\n" \ "\n" \
" Valid actions include: sysinit, respawn, askfirst, wait, \n" \ " Valid actions include: sysinit, respawn, askfirst, wait, \n" \
" once, and ctrlaltdel.\n" \ " once, ctrlaltdel, and shutdown.\n" \
"\n" \ "\n" \
" The available actions can be classified into two groups: actions\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" \ " that are run only once, and actions that are re-run when the specified\n" \
@ -706,9 +711,12 @@
" 'wait' actions, like 'sysinit' actions, cause init to wait until\n" \ " 'wait' actions, like 'sysinit' actions, cause init to wait until\n" \
" the specified task completes. 'once' actions are asyncronous,\n" \ " the specified task completes. 'once' actions are asyncronous,\n" \
" therefore, init does not wait for them to complete. 'ctrlaltdel'\n" \ " therefore, init does not wait for them to complete. 'ctrlaltdel'\n" \
" actions are run immediately before init causes the system to reboot\n" \ " actions are run when the system detects that someone on the system\n" \
" (unmounting filesystems with a 'ctrlaltdel' action is a very good\n" \ " console has pressed the CTRL-ALT-DEL key combination. Typically one\n" \
" idea).\n" \ " wants to run 'reboot' at this point to cause the system to reboot.\n" \
" Finally the 'shutdown' action specifies the actions to taken when\n" \
" init is told to reboot. Unmounting filesystems and disabling swap\n" \
" is a very good here\n" \
"\n" \ "\n" \
" Run repeatedly actions:\n" \ " Run repeatedly actions:\n" \
"\n" \ "\n" \
@ -759,8 +767,9 @@
" #::respawn:/sbin/getty 57600 ttyS2\n" \ " #::respawn:/sbin/getty 57600 ttyS2\n" \
" \n" \ " \n" \
" # Stuff to do before rebooting\n" \ " # Stuff to do before rebooting\n" \
" ::ctrlaltdel:/bin/umount -a -r\n" \ " ::ctrlaltdel:/sbin/reboot\n" \
" ::ctrlaltdel:/sbin/swapoff -a\n" " ::shutdown:/bin/umount -a -r\n" \
" ::shutdown:/sbin/swapoff -a\n"
#define insmod_trivial_usage \ #define insmod_trivial_usage \
"[OPTION]... MODULE [symbol=value]..." "[OPTION]... MODULE [symbol=value]..."

23
init.c
View File

@ -146,7 +146,8 @@ typedef enum {
ASKFIRST, ASKFIRST,
WAIT, WAIT,
ONCE, ONCE,
CTRLALTDEL CTRLALTDEL,
SHUTDOWN
} initActionEnum; } initActionEnum;
/* A mapping between "inittab" action name strings and action type codes. */ /* A mapping between "inittab" action name strings and action type codes. */
@ -162,6 +163,7 @@ static const struct initActionType actions[] = {
{"wait", WAIT}, {"wait", WAIT},
{"once", ONCE}, {"once", ONCE},
{"ctrlaltdel", CTRLALTDEL}, {"ctrlaltdel", CTRLALTDEL},
{"shutdown", SHUTDOWN},
{0, 0} {0, 0}
}; };
@ -617,12 +619,12 @@ static void check_memory()
} }
/* Run all commands to be run right before halt/reboot */ /* Run all commands to be run right before halt/reboot */
static void run_lastAction(void) static void run_actions(initActionEnum action)
{ {
initAction *a, *tmp; initAction *a, *tmp;
for (a = initActionList; a; a = tmp) { for (a = initActionList; a; a = tmp) {
tmp = a->nextPtr; tmp = a->nextPtr;
if (a->action == CTRLALTDEL) { if (a->action == action) {
waitfor(a->process, a->console, FALSE); waitfor(a->process, a->console, FALSE);
delete_initAction(a); delete_initAction(a);
} }
@ -654,7 +656,7 @@ static void shutdown_system(void)
sleep(1); sleep(1);
/* run everything to be run at "ctrlaltdel" */ /* run everything to be run at "ctrlaltdel" */
run_lastAction(); run_actions(SHUTDOWN);
sync(); sync();
if (kernelVersion > 0 && kernelVersion <= KERNEL_VERSION(2,2,11)) { if (kernelVersion > 0 && kernelVersion <= KERNEL_VERSION(2,2,11)) {
@ -696,6 +698,11 @@ static void reboot_signal(int sig)
exit(0); exit(0);
} }
static void ctrlaltdel_signal(int sig)
{
run_actions(CTRLALTDEL);
}
#endif /* ! DEBUG_INIT */ #endif /* ! DEBUG_INIT */
static void new_initAction(initActionEnum action, char *process, char *cons) static void new_initAction(initActionEnum action, char *process, char *cons)
@ -767,10 +774,12 @@ static void parse_inittab(void)
if (file == NULL) { if (file == NULL) {
/* No inittab file -- set up some default behavior */ /* No inittab file -- set up some default behavior */
#endif #endif
/* Reboot on Ctrl-Alt-Del */
new_initAction(CTRLALTDEL, "/sbin/reboot", console);
/* Swapoff on halt/reboot */ /* Swapoff on halt/reboot */
new_initAction(CTRLALTDEL, "/sbin/swapoff -a", console); new_initAction(SHUTDOWN, "/sbin/swapoff -a", console);
/* Umount all filesystems on halt/reboot */ /* Umount all filesystems on halt/reboot */
new_initAction(CTRLALTDEL, "/bin/umount -a -r", console); new_initAction(SHUTDOWN, "/bin/umount -a -r", console);
/* Askfirst shell on tty1 */ /* Askfirst shell on tty1 */
new_initAction(ASKFIRST, SHELL, console); new_initAction(ASKFIRST, SHELL, console);
/* Askfirst shell on tty2 */ /* Askfirst shell on tty2 */
@ -883,7 +892,7 @@ extern int init_main(int argc, char **argv)
* clear all of these in run() */ * clear all of these in run() */
signal(SIGUSR1, halt_signal); signal(SIGUSR1, halt_signal);
signal(SIGUSR2, halt_signal); signal(SIGUSR2, halt_signal);
signal(SIGINT, reboot_signal); signal(SIGINT, ctrlaltdel_signal);
signal(SIGTERM, reboot_signal); signal(SIGTERM, reboot_signal);
/* Turn off rebooting via CTL-ALT-DEL -- we get a /* Turn off rebooting via CTL-ALT-DEL -- we get a

View File

@ -146,7 +146,8 @@ typedef enum {
ASKFIRST, ASKFIRST,
WAIT, WAIT,
ONCE, ONCE,
CTRLALTDEL CTRLALTDEL,
SHUTDOWN
} initActionEnum; } initActionEnum;
/* A mapping between "inittab" action name strings and action type codes. */ /* A mapping between "inittab" action name strings and action type codes. */
@ -162,6 +163,7 @@ static const struct initActionType actions[] = {
{"wait", WAIT}, {"wait", WAIT},
{"once", ONCE}, {"once", ONCE},
{"ctrlaltdel", CTRLALTDEL}, {"ctrlaltdel", CTRLALTDEL},
{"shutdown", SHUTDOWN},
{0, 0} {0, 0}
}; };
@ -617,12 +619,12 @@ static void check_memory()
} }
/* Run all commands to be run right before halt/reboot */ /* Run all commands to be run right before halt/reboot */
static void run_lastAction(void) static void run_actions(initActionEnum action)
{ {
initAction *a, *tmp; initAction *a, *tmp;
for (a = initActionList; a; a = tmp) { for (a = initActionList; a; a = tmp) {
tmp = a->nextPtr; tmp = a->nextPtr;
if (a->action == CTRLALTDEL) { if (a->action == action) {
waitfor(a->process, a->console, FALSE); waitfor(a->process, a->console, FALSE);
delete_initAction(a); delete_initAction(a);
} }
@ -654,7 +656,7 @@ static void shutdown_system(void)
sleep(1); sleep(1);
/* run everything to be run at "ctrlaltdel" */ /* run everything to be run at "ctrlaltdel" */
run_lastAction(); run_actions(SHUTDOWN);
sync(); sync();
if (kernelVersion > 0 && kernelVersion <= KERNEL_VERSION(2,2,11)) { if (kernelVersion > 0 && kernelVersion <= KERNEL_VERSION(2,2,11)) {
@ -696,6 +698,11 @@ static void reboot_signal(int sig)
exit(0); exit(0);
} }
static void ctrlaltdel_signal(int sig)
{
run_actions(CTRLALTDEL);
}
#endif /* ! DEBUG_INIT */ #endif /* ! DEBUG_INIT */
static void new_initAction(initActionEnum action, char *process, char *cons) static void new_initAction(initActionEnum action, char *process, char *cons)
@ -767,10 +774,12 @@ static void parse_inittab(void)
if (file == NULL) { if (file == NULL) {
/* No inittab file -- set up some default behavior */ /* No inittab file -- set up some default behavior */
#endif #endif
/* Reboot on Ctrl-Alt-Del */
new_initAction(CTRLALTDEL, "/sbin/reboot", console);
/* Swapoff on halt/reboot */ /* Swapoff on halt/reboot */
new_initAction(CTRLALTDEL, "/sbin/swapoff -a", console); new_initAction(SHUTDOWN, "/sbin/swapoff -a", console);
/* Umount all filesystems on halt/reboot */ /* Umount all filesystems on halt/reboot */
new_initAction(CTRLALTDEL, "/bin/umount -a -r", console); new_initAction(SHUTDOWN, "/bin/umount -a -r", console);
/* Askfirst shell on tty1 */ /* Askfirst shell on tty1 */
new_initAction(ASKFIRST, SHELL, console); new_initAction(ASKFIRST, SHELL, console);
/* Askfirst shell on tty2 */ /* Askfirst shell on tty2 */
@ -883,7 +892,7 @@ extern int init_main(int argc, char **argv)
* clear all of these in run() */ * clear all of these in run() */
signal(SIGUSR1, halt_signal); signal(SIGUSR1, halt_signal);
signal(SIGUSR2, halt_signal); signal(SIGUSR2, halt_signal);
signal(SIGINT, reboot_signal); signal(SIGINT, ctrlaltdel_signal);
signal(SIGTERM, reboot_signal); signal(SIGTERM, reboot_signal);
/* Turn off rebooting via CTL-ALT-DEL -- we get a /* Turn off rebooting via CTL-ALT-DEL -- we get a

View File

@ -28,9 +28,9 @@ extern int reboot_main(int argc, char **argv)
{ {
#ifdef BB_FEATURE_LINUXRC #ifdef BB_FEATURE_LINUXRC
/* don't assume init's pid == 1 */ /* don't assume init's pid == 1 */
return(kill(*(find_pid_by_name("init")), SIGINT)); return(kill(*(find_pid_by_name("init")), SIGTERM));
#else #else
return(kill(1, SIGINT)); return(kill(1, SIGTERM));
#endif #endif
} }

View File

@ -28,9 +28,9 @@ extern int reboot_main(int argc, char **argv)
{ {
#ifdef BB_FEATURE_LINUXRC #ifdef BB_FEATURE_LINUXRC
/* don't assume init's pid == 1 */ /* don't assume init's pid == 1 */
return(kill(*(find_pid_by_name("init")), SIGINT)); return(kill(*(find_pid_by_name("init")), SIGTERM));
#else #else
return(kill(1, SIGINT)); return(kill(1, SIGTERM));
#endif #endif
} }

21
usage.h
View File

@ -663,10 +663,15 @@
"\n" \ "\n" \
" ::sysinit:/etc/init.d/rcS\n" \ " ::sysinit:/etc/init.d/rcS\n" \
" ::askfirst:/bin/sh\n" \ " ::askfirst:/bin/sh\n" \
" ::ctrlaltdel:/sbin/reboot\n" \
" ::shutdown:/sbin/swapoff -a\n" \
" ::shutdown:/bin/umount -a -r\n" \
"\n" \ "\n" \
"if it detects that /dev/console is _not_ a serial console, it will also run:\n" \ "if it detects that /dev/console is _not_ a serial console, it will also run:\n" \
"\n" \ "\n" \
" tty2::askfirst:/bin/sh\n" \ " tty2::askfirst:/bin/sh\n" \
" tty3::askfirst:/bin/sh\n" \
" tty4::askfirst:/bin/sh\n" \
"\n" \ "\n" \
"If you choose to use an /etc/inittab file, the inittab entry format is as follows:\n" \ "If you choose to use an /etc/inittab file, the inittab entry format is as follows:\n" \
"\n" \ "\n" \
@ -692,7 +697,7 @@
" <action>: \n" \ " <action>: \n" \
"\n" \ "\n" \
" Valid actions include: sysinit, respawn, askfirst, wait, \n" \ " Valid actions include: sysinit, respawn, askfirst, wait, \n" \
" once, and ctrlaltdel.\n" \ " once, ctrlaltdel, and shutdown.\n" \
"\n" \ "\n" \
" The available actions can be classified into two groups: actions\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" \ " that are run only once, and actions that are re-run when the specified\n" \
@ -706,9 +711,12 @@
" 'wait' actions, like 'sysinit' actions, cause init to wait until\n" \ " 'wait' actions, like 'sysinit' actions, cause init to wait until\n" \
" the specified task completes. 'once' actions are asyncronous,\n" \ " the specified task completes. 'once' actions are asyncronous,\n" \
" therefore, init does not wait for them to complete. 'ctrlaltdel'\n" \ " therefore, init does not wait for them to complete. 'ctrlaltdel'\n" \
" actions are run immediately before init causes the system to reboot\n" \ " actions are run when the system detects that someone on the system\n" \
" (unmounting filesystems with a 'ctrlaltdel' action is a very good\n" \ " console has pressed the CTRL-ALT-DEL key combination. Typically one\n" \
" idea).\n" \ " wants to run 'reboot' at this point to cause the system to reboot.\n" \
" Finally the 'shutdown' action specifies the actions to taken when\n" \
" init is told to reboot. Unmounting filesystems and disabling swap\n" \
" is a very good here\n" \
"\n" \ "\n" \
" Run repeatedly actions:\n" \ " Run repeatedly actions:\n" \
"\n" \ "\n" \
@ -759,8 +767,9 @@
" #::respawn:/sbin/getty 57600 ttyS2\n" \ " #::respawn:/sbin/getty 57600 ttyS2\n" \
" \n" \ " \n" \
" # Stuff to do before rebooting\n" \ " # Stuff to do before rebooting\n" \
" ::ctrlaltdel:/bin/umount -a -r\n" \ " ::ctrlaltdel:/sbin/reboot\n" \
" ::ctrlaltdel:/sbin/swapoff -a\n" " ::shutdown:/bin/umount -a -r\n" \
" ::shutdown:/sbin/swapoff -a\n"
#define insmod_trivial_usage \ #define insmod_trivial_usage \
"[OPTION]... MODULE [symbol=value]..." "[OPTION]... MODULE [symbol=value]..."