summaryrefslogtreecommitdiffstats
path: root/sbin/reboot
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2001-03-20 17:22:48 +0000
committeriedowse <iedowse@FreeBSD.org>2001-03-20 17:22:48 +0000
commit04ec7b65a28eac8f1623d24f0a478deb1a074faa (patch)
treed5a9ec258638f7230d121581993469f85df44d82 /sbin/reboot
parent9bcd26813064f6ad798ad3a0be8d673b7ee02aed (diff)
downloadFreeBSD-src-04ec7b65a28eac8f1623d24f0a478deb1a074faa.zip
FreeBSD-src-04ec7b65a28eac8f1623d24f0a478deb1a074faa.tar.gz
Reboot(8) normally waits 5 seconds after sending SIGTERMs to all
processes and then sends SIGKILLs. If a lot of processes are swapped out, this delay may not be long enough, so processes such as an X server may be killed before they have had time to clean up properly. Make this delay more dynamic by waiting up to 60 seconds for swap page-in activity to end. While I'm here, ANSIfy and remove a `register' specifier.
Diffstat (limited to 'sbin/reboot')
-rw-r--r--sbin/reboot/reboot.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c
index be3c81b..9dae03d 100644
--- a/sbin/reboot/reboot.c
+++ b/sbin/reboot/reboot.c
@@ -47,6 +47,7 @@ static const char rcsid[] =
#include <sys/reboot.h>
#include <sys/types.h>
+#include <sys/sysctl.h>
#include <signal.h>
#include <err.h>
#include <errno.h>
@@ -57,18 +58,17 @@ static const char rcsid[] =
#include <string.h>
#include <unistd.h>
-void usage __P((void));
+void usage(void);
+u_int get_pageins(void);
int dohalt;
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(int argc, char *argv[])
{
- register int i;
struct passwd *pw;
- int ch, howto, lflag, nflag, qflag, pflag, sverrno;
+ int ch, howto, i, lflag, nflag, qflag, pflag, sverrno;
+ u_int pageins;
char *p, *user;
if (strstr((p = rindex(*argv, '/')) ? p + 1 : *argv, "halt")) {
@@ -152,12 +152,19 @@ main(argc, argv)
/*
* After the processes receive the signal, start the rest of the
* buffers on their way. Wait 5 seconds between the SIGTERM and
- * the SIGKILL to give everybody a chance.
+ * the SIGKILL to give everybody a chance. If there is a lot of
+ * paging activity then wait longer, up to a maximum of approx
+ * 60 seconds.
*/
sleep(2);
- if (!nflag)
- sync();
- sleep(3);
+ for (i = 0; i < 20; i++) {
+ pageins = get_pageins();
+ if (!nflag)
+ sync();
+ sleep(3);
+ if (get_pageins() == pageins)
+ break;
+ }
for (i = 1;; ++i) {
if (kill(-1, SIGKILL) == -1) {
@@ -190,3 +197,18 @@ usage()
dohalt ? "halt" : "reboot");
exit(1);
}
+
+u_int
+get_pageins()
+{
+ u_int pageins;
+ size_t len;
+
+ len = sizeof(pageins);
+ if (sysctlbyname("vm.stats.vm.v_swappgsin", &pageins, &len, NULL, 0)
+ != 0) {
+ warnx("v_swappgsin");
+ return (0);
+ }
+ return pageins;
+}
OpenPOWER on IntegriCloud