Add support for registering a watchdog daemon

This patch adds initial support for registering a watchdog daemon with
Finit.  Needed for situations when you want the system to actually be
rebooted by the watchdog timer (WDT) circuitry rather than the kernel.

The initctl API has been extended with a INIT_CMD_WDOG_HELLO command
that is used to both register and "ping" Finit periodically.  As long as
Finit responds (with an ACK) the watchdog daemon knows Finit is alive.

At shutdown Finit stops all services (except kernel threads and daemons
marked with @ in the first character of their process name) and, if a
watchdog has registered, SIGPWR is sent to it when Finit has finished
unmounting etc., just prior to kernel reboot/halt/poweroff.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson
2016-10-24 00:02:19 +02:00
parent 5cde809909
commit 6cb3d86cd1
4 changed files with 25 additions and 0 deletions
+13
View File
@@ -323,6 +323,19 @@ static void cb(uev_t *w, void *UNUSED(arg), int UNUSED(events))
_d("Client failed reading ACK");
goto leave;
case INIT_CMD_WDOG_HELLO:
if (rq.runlevel <= 0) {
result = 1;
break;
}
if (wdogpid > 0 && wdogpid != rq.runlevel) {
kill(wdogpid, SIGTERM);
do_sleep(1);
}
wdogpid = rq.runlevel;
break;
default:
_d("Unsupported cmd: %d", rq.cmd);
break;
+1
View File
@@ -50,6 +50,7 @@
int debug = 0;
int quiet = QUIET_MODE; /* Delayed disable of silent mode. */
int silent = SILENT_MODE; /* Completely silent, including boot */
int wdogpid = 0; /* No watchdog by default */
int runlevel = 0; /* Bootstrap 'S' */
int cfglevel = RUNLEVEL; /* Fallback if no configured runlevel */
int prevlevel = -1;
+2
View File
@@ -67,6 +67,7 @@
#define INIT_CMD_QUERY_INETD 14
#define INIT_CMD_EMIT 15
#define INIT_CMD_GET_RUNLEVEL 16
#define INIT_CMD_WDOG_HELLO 128 /* Watchdog register and hello */
#define INIT_CMD_NACK 254
#define INIT_CMD_ACK 255
@@ -81,6 +82,7 @@ struct init_request {
extern int debug;
extern int quiet;
extern int silent;
extern int wdogpid;
extern int runlevel;
extern int cfglevel;
extern int prevlevel;
+9
View File
@@ -194,6 +194,15 @@ void do_shutdown(shutop_t op)
/* Call mdadm to mark any RAID array(s) as clean before halting. */
mdadm_wait();
/* Wait here until the WDT reboots, or timeout */
if (wdogpid) {
int timeout = 10;
print(kill(wdogpid, SIGPWR) == 1, "Pending watchdog reboot");
while (timeout--)
do_sleep(1);
}
_d("%s", op == SHUT_REBOOT ? "Rebooting" : "Halting");
if (op == SHUT_REBOOT)
reboot(RB_AUTOBOOT);