--- Begin Message ---
Hi!
We have a lot of PRs (5451, 9066, 10035) complaining the lack
of running /etc/rc.shutdown from shutdown(8)/reboot(8).
In fact, there are two ways to cleanly (with /etc/rc.shutdown)
reboot the system:
- send init(8) SIGINT signal;
- run shutdown(8) without ``-r'' and ``-h'' switches, so it
will send init(8) SIGINT signal.
On the other hand, there is no easy (single-step) way to run
/etc/rc.shutdown and then halt plus optionally power-off the
system.
The patch below (mostly from PR#5451) removes this limitation
by adding two new features to init(8):
- when init(8) receives SIGUSR1, it will act like in SIGINT
case, but will call reboot(RB_HALT);
- when init(8) receives SIGUSR2, it will act like in SIGINT
case, but will call reboot(RB_HALT|RB_POWEROFF).
Also, when compiled with -DCOMPAT_SYSV_INIT, it is now possible
to emulate SysV's init(8) behaviour.
I have tested it on my 3.2-STABLE, and it works like a charm.
Very handy!!!
Could you please review it?
Thanks,
--
Ruslan Ermilov Sysadmin and DBA of the
r...@ucb.crimea.ua United Commercial Bank
+380.652.247.647 Simferopol, Ukraine
http://www.FreeBSD.org The Power To Serve
http://www.oracle.com Enabling The Information Age
Index: Makefile
===================================================================
RCS file: /usr/FreeBSD-CVS/src/sbin/init/Makefile,v
retrieving revision 1.15
diff -u -r1.15 Makefile
--- Makefile 1998/01/20 10:39:56 1.15
+++ Makefile 1999/06/11 20:14:19
@@ -6,6 +6,7 @@
BINMODE=500
INSTALLFLAGS=-fschg
CFLAGS+=-DDEBUGSHELL -DSECURE -DLOGIN_CAP
+CFLAGS+=-DCOMPAT_SYSV_INIT
.if exists(${.CURDIR}/../../secure) && !defined(NOCRYPT) && !defined(NOSECURE)
DISTRIBUTION=des
Index: init.c
===================================================================
RCS file: /usr/FreeBSD-CVS/src/sbin/init/init.c,v
retrieving revision 1.31
diff -u -r1.31 init.c
--- init.c 1998/07/22 05:45:11 1.31
+++ init.c 1999/06/11 20:28:59
@@ -132,6 +132,7 @@
#define TRUE 1
int Reboot = FALSE;
+int howto = RB_AUTOBOOT;
int devfs;
@@ -203,9 +204,44 @@
errx(1, "%s", strerror(EPERM));
/* System V users like to reexec init. */
- if (getpid() != 1)
- errx(1, "already running");
-
+ if (getpid() != 1) {
+#ifdef COMPAT_SYSV_INIT
+ /* So give them what they want */
+ if (argc > 1) {
+ if (strlen(argv[1]) == 1) {
+ register char state = *argv[1];
+ register int sig;
+
+ switch (state) {
+ case '0': /* halt + poweroff */
+ sig = SIGUSR2;
+ break;
+ case '1': /* single user */
+ case 's':
+ sig = SIGTERM;
+ break;
+ case '6': /* reboot */
+ sig = SIGINT;
+ break;
+ case 'q': /* re-read /etc/ttys */
+ sig = SIGHUP;
+ break;
+ case 'c': /* block further logins */
+ sig = SIGTSTP;
+ break;
+ default:
+ goto usage;
+ }
+ kill(1, sig);
+ _exit(0);
+ } else
+usage:
+ errx(1, "invalid level ``%s''\n"
+ "usage: init [016cqs]", argv[1]);
+ } else
+#endif
+ errx(1, "already running");
+ }
/*
* Note that this does NOT open a file...
* Does 'init' deserve its own facility number?
@@ -259,11 +295,13 @@
handle(badsys, SIGSYS, 0);
handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV,
SIGBUS, SIGXCPU, SIGXFSZ, 0);
- handle(transition_handler, SIGHUP, SIGINT, SIGTERM, SIGTSTP, 0);
+ handle(transition_handler, SIGHUP, SIGINT, SIGTERM, SIGTSTP,
+ SIGUSR1, SIGUSR2, 0);
handle(alrm_handler, SIGALRM, 0);
sigfillset(&mask);
delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
- SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGALRM, 0);
+ SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGALRM,
+ SIGUSR1, SIGUSR2, 0);
sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
@@ -598,7 +636,7 @@
sync();
alarm(2);
pause();
- reboot(RB_AUTOBOOT);
+ reboot(howto);
_exit(0);
}
@@ -1238,6 +1276,10 @@
case SIGHUP:
requested_transition = clean_ttys;
break;
+ case SIGUSR2:
+ howto = RB_POWEROFF;
+ case SIGUSR1:
+ howto |= RB_HALT;
case SIGINT:
Reboot = TRUE;
case SIGTERM:
--- End Message ---