Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/sbin/shutdown pullup from trunk (approved by thorpej):



details:   https://anonhg.NetBSD.org/src/rev/99547c27185d
branches:  netbsd-1-5
changeset: 488603:99547c27185d
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Thu Jul 20 18:48:57 2000 +0000

description:
pullup from trunk (approved by thorpej):
wait only finite time for completition of /etc/rc.shutdown - default is
300 seconds, that value is adjustable by new -T flag
Mention addition of shutdown hooks and -T option in HISTORY, slighly adjust
  also description of -D flag and move it where it alhabetically belongs.

This fixes bin/10637.

diffstat:

 sbin/shutdown/shutdown.8 |  38 +++++++++++++++++++------
 sbin/shutdown/shutdown.c |  70 +++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 92 insertions(+), 16 deletions(-)

diffs (212 lines):

diff -r 3eaa0262009d -r 99547c27185d sbin/shutdown/shutdown.8
--- a/sbin/shutdown/shutdown.8  Thu Jul 20 16:54:49 2000 +0000
+++ b/sbin/shutdown/shutdown.8  Thu Jul 20 18:48:57 2000 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: shutdown.8,v 1.17 1998/10/29 20:12:56 bad Exp $
+.\"    $NetBSD: shutdown.8,v 1.17.10.1 2000/07/20 18:48:57 jdolecek Exp $
 .\"
 .\" Copyright (c) 1988, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -33,7 +33,7 @@
 .\"
 .\"     @(#)shutdown.8 8.2 (Berkeley) 4/27/95
 .\"
-.Dd January 20, 1998
+.Dd July 20, 2000
 .Dt SHUTDOWN 8
 .Os
 .Sh NAME
@@ -42,6 +42,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl Ddfhknpr
+.Op Fl T Ar timeout
 .Ar time
 .Op Ar message ... | Ar -
 .Sh DESCRIPTION
@@ -69,6 +70,13 @@
 .Fl d
 also implies
 .Fl r .
+.It Fl D
+Prevents
+.Nm
+from detaching from the tty with
+.Xr fork 2
+and
+.Xr exit 3 .
 .It Fl f
 .Nm
 arranges, in the manner of
@@ -110,12 +118,12 @@
 .Nm
 execs
 .Xr reboot 8 .
-.It Fl D
-Prevents
-.Nm
-from detaching from the tty with
-.Xr fork 2 /
-.Xr exit 3 .
+.It Fl T
+Timeout in seconds to wait for
+.Pa /etc/rc.shutdown
+to finish. After
+this period, the script is killed and system shutdown proceeds.
+Default is 300 seconds (5 minutes).
 .It Ar time
 .Ar Time
 is the time at which
@@ -169,8 +177,12 @@
 Next a message is printed announcing the start of the system shutdown hooks.
 Then the shutdown hooks in
 .Pa /etc/rc.shutdown
-are run.
-And a message is printed indicating that they have completed.
+are run. If they don't complete within timeout (see
+.Fl T ,
+default 5 minutes), the script is killed and
+.Nm
+proceeds with system shutdown.
+In either case, a message is printed indicating that they have completed.
 After a short delay a terminate
 signal is then sent to
 .Xr init 8
@@ -204,3 +216,9 @@
 .Nm
 command appeared in
 .Bx 4.0 .
+Running of shutdown hooks in
+.Pa /etc/rc.shutdown
+and
+.Fl T
+option have been added in
+.Nx 1.5 .
diff -r 3eaa0262009d -r 99547c27185d sbin/shutdown/shutdown.c
--- a/sbin/shutdown/shutdown.c  Thu Jul 20 16:54:49 2000 +0000
+++ b/sbin/shutdown/shutdown.c  Thu Jul 20 18:48:57 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: shutdown.c,v 1.35 1999/10/31 13:24:05 is Exp $ */
+/*     $NetBSD: shutdown.c,v 1.35.6.1 2000/07/20 18:48:57 jdolecek Exp $       */
 
 /*
  * Copyright (c) 1988, 1990, 1993
@@ -43,7 +43,7 @@
 #if 0
 static char sccsid[] = "@(#)shutdown.c 8.4 (Berkeley) 4/28/95";
 #else
-__RCSID("$NetBSD: shutdown.c,v 1.35 1999/10/31 13:24:05 is Exp $");
+__RCSID("$NetBSD: shutdown.c,v 1.35.6.1 2000/07/20 18:48:57 jdolecek Exp $");
 #endif
 #endif /* not lint */
 
@@ -51,6 +51,7 @@
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/syslog.h>
+#include <sys/wait.h>
 
 #include <ctype.h>
 #include <err.h>
@@ -90,7 +91,11 @@
 #undef M
 #undef S
 
+/* time to wait for rc.shutdown to finish - 5 minutes by default */
+#define RCSHUTDOWN_TIMEOUT             (5 * 60)        
+
 static time_t offset, shuttime;
+static int rcshutdown_timeout = RCSHUTDOWN_TIMEOUT;
 static int dofast, dohalt, doreboot, killflg, mbuflen, nofork, nosync, dodump;
 static int dopowerdown;
 static const char *whom;
@@ -122,7 +127,7 @@
        if (geteuid())
                errx(1, "NOT super-user");
 #endif
-       while ((ch = getopt(argc, argv, "Ddfhknpr")) != -1)
+       while ((ch = getopt(argc, argv, "?DdfhknprT:")) != -1)
                switch (ch) {
                case 'd':
                        dodump = 1;
@@ -148,6 +153,11 @@
                case 'r':
                        doreboot = 1;
                        break;
+               case 'T':
+                       rcshutdown_timeout = (int) strtol(optarg, &endp, 10);
+                       if (*endp != '\0' || rcshutdown_timeout <= 0)
+                               errx(1, "invalid timeout value - must be positive number");
+                       break;
                case '?':
                default:
                        usage();
@@ -482,10 +492,58 @@
 void
 dorcshutdown()
 {
+       pid_t rc_pid, outpid;
+       time_t end_time;
+       int status;
+
        (void)printf("\r\nAbout to run shutdown hooks...\r\n");
-       (void)system(__CONCAT(". ", _PATH_RCSHUTDOWN));
+
+       rc_pid = fork();
+       switch (rc_pid) {
+       case -1:
+               /* error forking */
+               warn("dorcshutdown: fork");
+               break;
+       case 0:
+               /* child */
+               execl("/bin/sh", "sh", "-c", __CONCAT(". ", _PATH_RCSHUTDOWN),
+                               NULL);
+               err(1, "exec of '/bin/sh -c \". %s\" failed",
+                       _PATH_RCSHUTDOWN);
+               /* NOTREACHED */
+               break;
+       default:
+               /* parent */
+               end_time = time(NULL) + rcshutdown_timeout;
+               outpid = 0;
+               do {
+                       outpid = waitpid(rc_pid, &status, WNOHANG);
+                       if (outpid == rc_pid) {
+                               /* child exited */
+                               break;
+                       } else if (outpid == 0) {
+                               /* child not terminated yet */
+                               sleep(2);
+                       } else {
+                               /* an error occurred */
+                               warn("dorcshutdown: waitpid");
+                               break;
+                       }
+               } while(time(NULL) < end_time);
+
+               /* if rc.shutdown didn't exit within timeout, print warning */
+               if (outpid == 0) {
+                       warnx("%s didn't exit within timeout %ds, killed",
+                                _PATH_RCSHUTDOWN, rcshutdown_timeout);
+               }
+
+               /* if child did not exit voluntarily, kill it now */
+               if (outpid != rc_pid)
+                       (void) kill(rc_pid, SIGKILL);
+       }
+
+       (void)printf("\r\nDone running shutdown hooks.\r\n");
        (void)sleep(5);         /* Give operator a chance to abort this. */
-       (void)printf("\r\nDone running shutdown hooks.\r\n");
 }
 
 #define        FSMSG   "fastboot file for fsck\n"
@@ -547,6 +605,6 @@
 {
 
        (void)fprintf(stderr,
-           "usage: shutdown [-Ddfhknpr] time [message ... | -]\n");
+           "usage: shutdown [-Ddfhknpr] [-T timeout] time [message ... | -]\n");
        exit(1);
 }



Home | Main Index | Thread Index | Old Index