diff --git a/sbin/init/init.8 b/sbin/init/init.8 index 71e318427d82..50caf0c58104 100644 --- a/sbin/init/init.8 +++ b/sbin/init/init.8 @@ -229,6 +229,15 @@ This hook is used by and .Xr halt 8 . .Pp +.Nm Init +will terminate all possible processes (again, it will not wait +for deadlocked processes) and reboot the machine if sent the interrupt +.Pq Dv INT +signal, i.e. +.Dq Li "kill \-INT 1". +This is useful for shutting the machine down cleanly from inside the kernel +or from X when the machines appears to be hung. +.Pp The role of .Nm init is so critical that if it dies, the system will reboot itself diff --git a/sbin/init/init.c b/sbin/init/init.c index cd5914a96881..413fa5e0aeba 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -59,6 +59,7 @@ static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 7/15/93"; #include #include #include +#include #ifdef __STDC__ #include @@ -114,6 +115,7 @@ state_func_t catatonia __P((void)); state_func_t death __P((void)); enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT; +int reboot = FALSE; void transition __P((state_t)); state_t requested_transition = runcom; @@ -229,11 +231,11 @@ main(argc, argv) handle(badsys, SIGSYS, 0); handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGXCPU, SIGXFSZ, 0); - handle(transition_handler, SIGHUP, SIGTERM, SIGTSTP, 0); + handle(transition_handler, SIGHUP, SIGINT, SIGTERM, SIGTSTP, 0); handle(alrm_handler, SIGALRM, 0); sigfillset(&mask); delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, - SIGXCPU, SIGXFSZ, SIGHUP, SIGTERM, SIGTSTP, SIGALRM, 0); + SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGALRM, 0); sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; @@ -560,6 +562,15 @@ single_user() if (getsecuritylevel() > 0) setsecuritylevel(0); + if (reboot) { + /* Instead of going single user, let's halt the machine */ + sync(); + alarm(2); + pause(); + reboot(RB_AUTOBOOT); + _exit(0); + } + if ((pid = fork()) == 0) { /* * Start the single user session. @@ -1129,6 +1140,8 @@ transition_handler(sig) case SIGHUP: requested_transition = clean_ttys; break; + case SIGINT: + reboot = TRUE; case SIGTERM: requested_transition = death; break;