diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2006-06-22 00:25:23 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2006-06-22 00:25:23 +0000 |
commit | 94061cd2792be958bbc805dc22a7a26789ff1f69 (patch) | |
tree | 9e3d7a7a8ffdfc4c4e60355884857f453c3453f2 /sbin | |
parent | 671fff6b4206ff995773f6d9c531d12098def96d (diff) |
accept SIGUSR2. Like SIGUSR1, except it makes RB_POWERDOWN mandatory.
This will be used by kernel components which are trying to really really
power the system down. suggested and tested by jason
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/init/init.8 | 9 | ||||
-rw-r--r-- | sbin/init/init.c | 32 |
2 files changed, 33 insertions, 8 deletions
diff --git a/sbin/init/init.8 b/sbin/init/init.8 index 61ad2ffb688..fb395034a4f 100644 --- a/sbin/init/init.8 +++ b/sbin/init/init.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: init.8,v 1.34 2005/12/10 22:17:55 jmc Exp $ +.\" $OpenBSD: init.8,v 1.35 2006/06/22 00:25:22 deraadt Exp $ .\" $NetBSD: init.8,v 1.6 1995/03/18 14:56:31 cgd Exp $ .\" .\" Copyright (c) 1980, 1991, 1993 @@ -217,7 +217,14 @@ run .Pa /etc/rc.shutdown , and halt the machine if user-defined signal 1 .Pq Dv USR1 +or user-defined signal 2 +.Pd Dv USR2 is received. +.Pa /etc/rc.shutdown +can specify that a powerdown is requested. +Alternatively, +.Dv USR2 +specifically requests a powerdown. .Pp The role of .Nm diff --git a/sbin/init/init.c b/sbin/init/init.c index 5dfdb03b725..127813ac7e2 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init.c,v 1.38 2006/03/19 18:43:56 otto Exp $ */ +/* $OpenBSD: init.c,v 1.39 2006/06/22 00:25:22 deraadt Exp $ */ /* $NetBSD: init.c,v 1.22 1996/05/15 23:29:33 jtc Exp $ */ /*- @@ -43,7 +43,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)init.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: init.c,v 1.38 2006/03/19 18:43:56 otto Exp $"; +static char rcsid[] = "$OpenBSD: init.c,v 1.39 2006/06/22 00:25:22 deraadt Exp $"; #endif #endif /* not lint */ @@ -120,6 +120,7 @@ state_func_t multi_user(void); state_func_t clean_ttys(void); state_func_t catatonia(void); state_func_t death(void); +state_func_t hard_death(void); state_func_t nice_death(void); enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT; @@ -243,11 +244,13 @@ main(int argc, char *argv[]) handle(badsys, SIGSYS, 0); handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGXCPU, SIGXFSZ, 0); - handle(transition_handler, SIGHUP, SIGTERM, SIGTSTP, SIGUSR1, 0); + handle(transition_handler, SIGHUP, SIGTERM, SIGTSTP, SIGUSR1, + SIGUSR2, 0); handle(alrm_handler, SIGALRM, 0); sigfillset(&mask); delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, - SIGXCPU, SIGXFSZ, SIGHUP, SIGTERM, SIGUSR1, SIGTSTP, SIGALRM, 0); + SIGXCPU, SIGXFSZ, SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, + SIGTSTP, SIGALRM, 0); sigprocmask(SIG_SETMASK, &mask, NULL); memset(&sa, 0, sizeof sa); sigemptyset(&sa.sa_mask); @@ -1149,6 +1152,9 @@ transition_handler(int sig) case SIGUSR1: requested_transition = nice_death; break; + case SIGUSR2: + requested_transition = hard_death; + break; case SIGTSTP: requested_transition = catatonia; break; @@ -1281,6 +1287,19 @@ alrm_handler(int sig) clang = 1; } +int death_howto = RB_HALT; + +/* + * Bring the system down nicely, then we must powerdown because something + * is very wrong. + */ +state_func_t +hard_death(void) +{ + death_howto |= RB_POWERDOWN; + return nice_death(); +} + /* * Bring the system down to single user nicely, after run the shutdown script. */ @@ -1291,7 +1310,6 @@ nice_death(void) int i; pid_t pid; static const int death_sigs[3] = { SIGHUP, SIGTERM, SIGKILL }; - int howto = RB_HALT; int status; for (sp = sessions; sp; sp = sp->se_next) { @@ -1334,7 +1352,7 @@ nice_death(void) default: waitpid(pid, &status, 0); if (WIFEXITED(status) && WEXITSTATUS(status) == 2) - howto |= RB_POWERDOWN; + death_howto |= RB_POWERDOWN; } } @@ -1356,7 +1374,7 @@ nice_death(void) warning("some processes would not die; ps axl advised"); die: - reboot(howto); + reboot(death_howto); /* ... and if that fails.. oh well */ return (state_func_t) single_user; |