Skip site navigation (1)Skip section navigation (2)
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
This is a multi-part message in MIME format.
--------------070401030707050509080304
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

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.

--------------070401030707050509080304
Content-Type: text/x-diff;
 name="reboot.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="reboot.diff"

--- 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);
 }

--------------070401030707050509080304--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4AC2F5A2.4020006>