diff options
author | iedowse <iedowse@FreeBSD.org> | 2001-03-20 17:22:48 +0000 |
---|---|---|
committer | iedowse <iedowse@FreeBSD.org> | 2001-03-20 17:22:48 +0000 |
commit | 04ec7b65a28eac8f1623d24f0a478deb1a074faa (patch) | |
tree | d5a9ec258638f7230d121581993469f85df44d82 | |
parent | 9bcd26813064f6ad798ad3a0be8d673b7ee02aed (diff) | |
download | FreeBSD-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.
-rw-r--r-- | sbin/reboot/reboot.c | 42 |
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; +} |