Hi, hackers!

While the -core is busy to review/approve this patch,
I would like to know your opinion.  What do you think
of it?


Thanks,
-- 
Ruslan Ermilov          Sysadmin and DBA of the
r...@ucb.crimea.ua      United Commercial Bank,
r...@freebsd.org                FreeBSD committer,
+380.652.247.647        Simferopol, Ukraine

http://www.FreeBSD.org  The Power To Serve
http://www.oracle.com   Enabling The Information Age
--- 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 ---

Reply via email to