On Wednesday 29 October 2008 03:48, Denys Vlasenko wrote:
> + // kill survived services
> + killall(SIGKILL);
> + sync(); sleep(1);
> + // umount -a
> + // ???
> + // reboot
> + reboot(
> + (SIGUSR1 == bb_got_signal) ? RB_HALT_SYSTEM :
> + (SIGUSR2 == bb_got_signal) ? RB_POWER_OFF :
> + RB_AUTOBOOT
> + );
>
> Do we really want to hard-reboot without remounting RO
> or unmounting filesystems?
>
> What if user disagrees with our reboot sequence (needs bigger delays,
> wants to free lop devices, etc?). Yes, he can code up "different reboot"
> himself, as a shell script. But this exact *our* sequence can be set up
> exactly the same way as a shell script, no need to patch runsvdir! Right?
In order to facilitatte this, we just need to make sure
we do not crash kernel by exiting. kernel doesn't like
init exiting. How about attached patch?
--
vda
diff -d -urpN busybox.5/runit/runsvdir.c busybox.6/runit/runsvdir.c
--- busybox.5/runit/runsvdir.c 2008-10-26 02:02:35.000000000 +0200
+++ busybox.6/runit/runsvdir.c 2008-10-29 04:27:00.000000000 +0100
@@ -115,10 +115,16 @@ static void runsv(int no, const char *na
/* child */
if (set_pgrp)
setsid();
+/* man execv:
+ * Signals set to be caught by the calling process image
+ * shall be set to the default action in the new process image.
+ * Therefore, we do not need this: */
+#if 0
bb_signals(0
- + (1 << SIGHUP)
- + (1 << SIGTERM)
+ | (1 << SIGHUP)
+ | (1 << SIGTERM)
, SIG_DFL);
+#endif
execvp(prog[0], prog);
fatal2_cannot("start runsv ", name);
}
@@ -227,7 +233,19 @@ int runsvdir_main(int argc UNUSED_PARAM,
set_pgrp = getopt32(argv, "P");
argv += optind;
- bb_signals_recursive((1 << SIGTERM) | (1 << SIGHUP), record_signo);
+ bb_signals(0
+ | (1 << SIGTERM)
+ | (1 << SIGHUP)
+ /* For busybox's init, SIGTERM == reboot,
+ * SIGUSR1 == halt
+ * SIGUSR2 == poweroff
+ * so we need to intercept SIGUSRn too
+ * Note that we do not implement actual reboot
+ * (killall(TERM) + umount, etc), we just pause
+ * respawing and avoid exiting (-> making kernel oops).
+ * The user is responsible for the rest. */
+ | (getpid() == 1 ? ((1 << SIGUSR1) | (1 << SIGUSR2)) : 0)
+ , record_signo);
svdir = *argv++;
#if ENABLE_FEATURE_RUNSVDIR_LOG
@@ -256,7 +274,7 @@ int runsvdir_main(int argc UNUSED_PARAM,
rplog = NULL;
warnx("log service disabled");
}
-run:
+ run:
#endif
curdir = open_read(".");
if (curdir == -1)
@@ -319,8 +337,9 @@ run:
}
pfd[0].revents = 0;
#endif
- sig_block(SIGCHLD);
deadline = (need_rescan ? 1 : 5);
+ do_sleep:
+ sig_block(SIGCHLD);
#if ENABLE_FEATURE_RUNSVDIR_LOG
if (rplog)
poll(pfd, 1, deadline*1000);
@@ -333,11 +352,11 @@ run:
if (pfd[0].revents & POLLIN) {
char ch;
while (read(logpipe.rd, &ch, 1) > 0) {
- if (ch) {
- for (i = 6; i < rploglen; i++)
- rplog[i-1] = rplog[i];
- rplog[rploglen-1] = ch;
- }
+ if (ch < ' ')
+ ch = ' ';
+ for (i = 6; i < rploglen; i++)
+ rplog[i-1] = rplog[i];
+ rplog[rploglen-1] = ch;
}
}
#endif
@@ -346,11 +365,18 @@ run:
for (i = 0; i < svnum; i++)
if (sv[i].pid)
kill(sv[i].pid, SIGTERM);
- // N.B. fall through
+ /* fall through */
case SIGTERM:
- _exit((SIGHUP == bb_got_signal) ? 111 : EXIT_SUCCESS);
+ /* exit, unless we are init */
+ if (getpid() != 1)
+ break;
+ default:
+ /* so we are init. do not exit,
+ * and pause respawning - we may be rebooting... */
+ bb_got_signal = 0;
+ deadline = 60;
+ goto do_sleep;
}
}
- /* not reached */
- return 0;
+ return (SIGHUP == bb_got_signal) ? 111 : EXIT_SUCCESS;
}
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox