On Thursday 06 November 2008 18:37, Vladimir Dronnikov wrote:
> > > Why then many people are coming here with "my reboot doesn't work" then?
> 
> BB reboot indeed doesn't work with runsvdir run as init.

How do you propose to make it work? What should it do
on the receipt of reboot signal?

> Either should I 
> disable reboot applet (thus losing reboot -f capability) and write reboot
> script or should I stop using runsvdir? I want to get the most from BB thus
> both the ways are unacceptable.

> To work the problem around I propose to teach runsvdir'ed init to call a
> hook script, say, /etc/reboot to perform system pre-reboot housekeeping.

I have an idea. As it stands now runsvdir has SIGHUP and SIGTERM handlers,
and we just added SIGUSR1 and SIGUSR2 if runsvdir is run under PID 1.

Getting it to handle reboot amounts simply to running a script
on any of these signals, wait for it to finish, and then
do what runsvdir does now (i.e. exit) if we are not PID 1,
else continue running. as init exiting is a bad idea.

If you want to use runsvdir as init, you run it as

runsvdir [-P] -s SCRIPT /dir

(perhaps exec'ing this command at the end of some sort
of startup script).

See attached patch. Testing...

# echo $$; exec ./busybox runsvdir ./z -s /bin/echo
17479

Simulating reboot request (in another xterm):

# kill -TERM 17479

In first xterm, "script" /bin/echo runs and prints "15"
(signo of SIGTERM), and then runsvdir exits.
--
vda
diff -d -urpN busybox.5/runit/runsvdir.c busybox.6/runit/runsvdir.c
--- busybox.5/runit/runsvdir.c	2008-10-31 03:36:16.000000000 +0100
+++ busybox.6/runit/runsvdir.c	2008-11-06 23:18:18.000000000 +0100
@@ -107,7 +107,7 @@ static NOINLINE pid_t runsv(const char *
 	}
 	if (pid == 0) {
 		/* child */
-		if (option_mask32) /* -P option? */
+		if (option_mask32 & 1) /* -P option? */
 			setsid();
 /* man execv:
  * "Signals set to be caught by the calling process image
@@ -217,17 +217,20 @@ int runsvdir_main(int argc UNUSED_PARAM,
 	time_t last_mtime = 0;
 	int wstat;
 	int curdir;
-	int pid;
+	pid_t pid;
 	unsigned deadline;
 	unsigned now;
 	unsigned stampcheck;
 	int i;
 	int need_rescan = 1;
+	char *opt_s_argv[3];
 
 	INIT_G();
 
 	opt_complementary = "-1";
-	getopt32(argv, "P");
+	opt_s_argv[0] = NULL;
+	opt_s_argv[2] = NULL;
+	getopt32(argv, "Ps:", &opt_s_argv[0]);
 	argv += optind;
 
 	bb_signals(0
@@ -335,7 +338,6 @@ int runsvdir_main(int argc UNUSED_PARAM,
 		pfd[0].revents = 0;
 #endif
 		deadline = (need_rescan ? 1 : 5);
- do_sleep:
 		sig_block(SIGCHLD);
 #if ENABLE_FEATURE_RUNSVDIR_LOG
 		if (rplog)
@@ -357,27 +359,37 @@ int runsvdir_main(int argc UNUSED_PARAM,
 			}
 		}
 #endif
+		if (!bb_got_signal)
+			continue;
+
+		/* -s SCRIPT: useful if we are init.
+		 * In this case typically script never returns,
+		 * it halts/powers off/reboots the system. */
+		if (opt_s_argv[0]) {
+			/* Single parameter: signal# */
+			opt_s_argv[1] = utoa(bb_got_signal);
+			pid = spawn(opt_s_argv);
+			if (pid > 0) {
+				/* Remebering to wait for _any_ children,
+				 * not just pid */
+				while (wait(NULL) != pid)
+					continue;
+			}
+		}
+
 		switch (bb_got_signal) {
-		case 0: /* we are not signaled, business as usual */
-			break;
 		case SIGHUP:
 			for (i = 0; i < svnum; i++)
 				if (sv[i].pid)
 					kill(sv[i].pid, SIGTERM);
-			/* fall through */
-		case SIGTERM:
-			/* exit, unless we are init */
-			if (getpid() != 1)
-				goto ret;
-		default:
-			/* so we are init. do not exit,
-			 * and pause respawning - we may be rebooting
-			 * (but SIGHUP is not a reboot, make short pause) */
-			deadline = (SIGHUP == bb_got_signal) ? 5 : 60;
-			bb_got_signal = 0;
-			goto do_sleep;
+			/* Fall through */
+		default: /* SIGTERM (or SIGUSRn if we are init) */
+			/* Exit unless we are init */
+			if (getpid() == 1)
+				break;
+			return (SIGHUP == bb_got_signal) ? 111 : EXIT_SUCCESS;
 		}
-	}
- ret:
-	return (SIGHUP == bb_got_signal) ? 111 : EXIT_SUCCESS;
+
+		bb_got_signal = 0;
+	} /* for (;;) */
 }
_______________________________________________
busybox mailing list
busybox@busybox.net
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to