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