Date: Tue, 29 Sep 2009 23:07:30 -0700 From: Ryan Rogers <webmaster@doghouserepair.com> To: Ivan Voras <ivoras@freebsd.org> Cc: =?ISO-8859-1?Q?Dag-Erling_Sm=F8rgr?= =?ISO-8859-1?Q?av?= <des@des.no>, Doug Barton <dougb@freebsd.org>, Robert Watson <rwatson@freebsd.org>, freebsd-current@freebsd.org Subject: Re: [PATCH] Shutdown cooloff feature Message-ID: <4AC2F5A2.4020006@doghouserepair.com> In-Reply-To: <9bbcef730909291146s5fb64bfdy7e5081dd4c804e27@mail.gmail.com> References: <4AC141B0.4090705@delphij.net> <alpine.BSF.2.00.0909291245080.91454@fledge.watson.org> <h9st65$eni$1@ger.gmane.org> <86ws3iexl3.fsf@ds4.des.no> <h9t09n$qhl$1@ger.gmane.org> <86ske5gav0.fsf@ds4.des.no> <alpine.BSF.2.00.0909291542190.94746@fledge.watson.org> <4AC247DC.4010502@FreeBSD.org> <9bbcef730909291146s5fb64bfdy7e5081dd4c804e27@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Ivan Voras wrote:
> 2009/9/29 Doug Barton <dougb@freebsd.org>:
>> Robert Watson wrote:
>>> I could be convinced by an argument that reboot and shutdown -r should
>>> be the same,
>> I have asked for this several times in the past but don't have the
>> time to generate the patches myself. I think halt should be treated
>> similarly as well. We just had a case (I believe on -stable) where a
>> user was using 'halt' thinking that it would do the same thing as
>> 'shutdown now' but was easier to type. He was having corruption in his
>> ldap db because it wasn't being shut down cleanly.
>>
>> That said, I agree with the posters that have said that there should
>> be overrides to halt and shutdown to force the old behavior.
>
> ... which probably uses BDB so it's as easy to "corrupt" as sneezing :)
>
> But yes, what I'd wish is that the default behaviour of all (shutdown,
> reboot, halt) be as "shutdown" is now, and introducting a command line
> switch (I see "-f" is not taken) for the odd emergency case when the
> old behaviour is needed. I'd also advocate "halt" meaning "shutdown
> -p", i.e. shutdown with poweroff instead of just stopping the kernel,
> which is mostly useless.
Attached is a patch which should do this. "reboot" sends a SIGINT to
init, while "halt" sends a SIGUSR2. Adding "-f" to either just does
what it would have done pre-patch.
[-- Attachment #2 --]
--- sbin/reboot/reboot.c.orig 2009-09-29 22:29:39.172648998 -0700
+++ sbin/reboot/reboot.c 2009-09-29 22:41:28.438914656 -0700
@@ -65,7 +65,7 @@
main(int argc, char *argv[])
{
const struct passwd *pw;
- int ch, howto, i, fd, lflag, nflag, qflag, sverrno;
+ int ch, howto, i, fd, fflag, lflag, nflag, qflag, sverrno;
u_int pageins;
const char *p, *user, *kernel = NULL;
@@ -74,12 +74,15 @@
howto = RB_HALT;
} else
howto = 0;
- lflag = nflag = qflag = 0;
- while ((ch = getopt(argc, argv, "dk:lnpq")) != -1)
+ fflag = lflag = nflag = qflag = 0;
+ while ((ch = getopt(argc, argv, "dfk:lnpq")) != -1)
switch(ch) {
case 'd':
howto |= RB_DUMP;
break;
+ case 'f':
+ fflag = 1;
+ break;
case 'k':
kernel = optarg;
break;
@@ -142,71 +145,78 @@
}
logwtmp("~", "shutdown", "");
- /*
- * Do a sync early on, so disks start transfers while we're off
- * killing processes. Don't worry about writes done before the
- * processes die, the reboot system call syncs the disks.
- */
- if (!nflag)
- sync();
-
- /*
- * Ignore signals that we can get as a result of killing
- * parents, group leaders, etc.
- */
- (void)signal(SIGHUP, SIG_IGN);
- (void)signal(SIGINT, SIG_IGN);
- (void)signal(SIGQUIT, SIG_IGN);
- (void)signal(SIGTERM, SIG_IGN);
- (void)signal(SIGTSTP, SIG_IGN);
-
- /*
- * If we're running in a pipeline, we don't want to die
- * after killing whatever we're writing to.
- */
- (void)signal(SIGPIPE, SIG_IGN);
-
- /* Just stop init -- if we fail, we'll restart it. */
- if (kill(1, SIGTSTP) == -1)
- err(1, "SIGTSTP init");
-
- /* Send a SIGTERM first, a chance to save the buffers. */
- if (kill(-1, SIGTERM) == -1 && errno != ESRCH)
- err(1, "SIGTERM processes");
-
- /*
- * 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. If there is a lot of
- * paging activity then wait longer, up to a maximum of approx
- * 60 seconds.
- */
- sleep(2);
- for (i = 0; i < 20; i++) {
- pageins = get_pageins();
+ if (!fflag) {
+ if (dohalt)
+ (void)kill(1, SIGUSR2);
+ else
+ (void)kill(1, SIGINT);
+ } else {
+ /*
+ * Do a sync early on, so disks start transfers while we're off
+ * killing processes. Don't worry about writes done before the
+ * processes die, the reboot system call syncs the disks.
+ */
if (!nflag)
sync();
- sleep(3);
- if (get_pageins() == pageins)
- break;
- }
- for (i = 1;; ++i) {
- if (kill(-1, SIGKILL) == -1) {
- if (errno == ESRCH)
+ /*
+ * Ignore signals that we can get as a result of killing
+ * parents, group leaders, etc.
+ */
+ (void)signal(SIGHUP, SIG_IGN);
+ (void)signal(SIGINT, SIG_IGN);
+ (void)signal(SIGQUIT, SIG_IGN);
+ (void)signal(SIGTERM, SIG_IGN);
+ (void)signal(SIGTSTP, SIG_IGN);
+
+ /*
+ * If we're running in a pipeline, we don't want to die
+ * after killing whatever we're writing to.
+ */
+ (void)signal(SIGPIPE, SIG_IGN);
+
+ /* Just stop init -- if we fail, we'll restart it. */
+ if (kill(1, SIGTSTP) == -1)
+ err(1, "SIGTSTP init");
+
+ /* Send a SIGTERM first, a chance to save the buffers. */
+ if (kill(-1, SIGTERM) == -1 && errno != ESRCH)
+ err(1, "SIGTERM processes");
+
+ /*
+ * 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. If there is a lot of
+ * paging activity then wait longer, up to a maximum of approx
+ * 60 seconds.
+ */
+ sleep(2);
+ for (i = 0; i < 20; i++) {
+ pageins = get_pageins();
+ if (!nflag)
+ sync();
+ sleep(3);
+ if (get_pageins() == pageins)
break;
- goto restart;
}
- if (i > 5) {
- (void)fprintf(stderr,
- "WARNING: some process(es) wouldn't die\n");
- break;
+
+ for (i = 1;; ++i) {
+ if (kill(-1, SIGKILL) == -1) {
+ if (errno == ESRCH)
+ break;
+ goto restart;
+ }
+ if (i > 5) {
+ (void)fprintf(stderr,
+ "WARNING: some process(es) wouldn't die\n");
+ break;
+ }
+ (void)sleep(2 * i);
}
- (void)sleep(2 * i);
- }
- reboot(howto);
- /* FALLTHROUGH */
+ reboot(howto);
+ /* FALLTHROUGH */
+ }
restart:
sverrno = errno;
@@ -218,7 +228,7 @@
static void
usage()
{
- (void)fprintf(stderr, "usage: %s [-%slnpq] [-k kernel]\n",
+ (void)fprintf(stderr, "usage: %s [-%sflnpq] [-k kernel]\n",
getprogname(), dohalt ? "" : "d");
exit(1);
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4AC2F5A2.4020006>
