sig.c: Use watchdogd to reboot system

This patch reorders the shutdown/reboot handler slightly and fixes
a bug in sleep().  It seems the sleep() syscall was interrupted by
receiving lots of SIGCHLD.  Unsurprisingly since we just sent all
processes SIGTERM, but unfortunate since that was too short time
to deliver SIGTERM to watchdogd.

We now call sleep() again, as long as it returns a non-zero value,
until at most two (2) seconds have passed.  During this time we
basically pend for watchdogd to do its job and let the WDT reboot
the system.  If the two second timeout passes we send SIGKILL and
forcibly reboot(RB_AUTOBOOT) the system.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson
2013-05-19 18:00:31 +02:00
parent b212babc87
commit f277166354
+12 -3
View File
@@ -49,6 +49,12 @@
static int stopped = 0;
/* Signal safe sleep ... we get a lot of SIGCHLD at reboot */
void do_sleep(unsigned int sec)
{
while ((sec = sleep(sec)))
;
}
void do_shutdown (int sig)
{
@@ -57,12 +63,15 @@ void do_shutdown (int sig)
if (sdown)
run_interactive(sdown, "Calling shutdown hook: %s", sdown);
/* Call all shutdown hooks before rebooting... */
plugin_run_hooks(HOOK_SHUTDOWN);
/* Here is where we signal watchdogd to do a forced reset for us */
_d("Sending SIGTERM to all processes.");
kill(-1, SIGTERM);
sleep(1);
/* Call all shutdown hooks, this is the last call before rebooting... */
plugin_run_hooks(HOOK_SHUTDOWN);
/* Wait for WDT to timeout, should be no more than ~1 sec. */
do_sleep(2);
_d("Sending SIGKILL to remaining processes.");
kill(-1, SIGKILL);