Refactor, simplify registration of built-in watchdog daemon

This patch not only greatly simplifies the registration of the built-in
watchdog daemon, it also fixes a nasty race condition with an external
watchdog daemon.  The INIT_CMD_WDOG_HELLO could reach finit in reversed
order, leading to the built-in daemon shutting down, but finit killing
the just registered external daemon.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2017-11-19 16:48:32 +01:00
1 parent e0fb2b036d
commit 3c800f6508
3 files changed
+14 -49

No files matched your search

+1 -1
View File
@@ -390,7 +390,7 @@ int main(int argc, char* argv[])
/*
* Start built-in watchdog as soon as possible, if enabled
*/
watchdog(argv[0]);
wdogpid = watchdog(argv[0]);
/* Set hostname as soon as possible, for syslog et al. */
set_hostname(&hostname);
+11 -46
View File
@@ -21,54 +21,17 @@
* THE SOFTWARE.
*/
#include <paths.h>
#include <signal.h>
#include <sys/un.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/watchdog.h>
#include "finit.h"
#include "helpers.h"
#include "util.h"
#include "log.h"
#include "watchdog.h"
int running = 1;
int handover = 0;
static int notify(void)
{
int sd, result = 255;
ssize_t len;
struct sockaddr_un sun = {
.sun_family = AF_UNIX,
.sun_path = INIT_SOCKET,
};
struct init_request rq;
sd = socket(AF_UNIX, SOCK_STREAM, 0);
if (-1 == sd)
return -1;
if (connect(sd, (struct sockaddr*)&sun, sizeof(sun)) == -1)
goto bye;
rq.cmd = INIT_CMD_WDOG_HELLO;
rq.magic = INIT_MAGIC;
rq.runlevel = getpid();
len = sizeof(rq);
if (write(sd, &rq, len) != len)
goto bye;
if (read(sd, &rq, len) != len)
goto bye;
result = 0;
bye:
close(sd);
return result;
}
static void sighandler(int signo)
{
if (signo == SIGTERM)
@@ -95,27 +58,27 @@ static int init(char *progname, char *devnode, int timeout)
static int loop(int fd)
{
int done = 0;
int dummy = 0;
while (running) {
do_sleep(1);
ioctl(fd, WDIOC_KEEPALIVE, &done);
if (!done && !notify())
done = 1;
ioctl(fd, WDIOC_KEEPALIVE, &dummy);
}
if (handover) {
ioctl(fd, WDIOC_KEEPALIVE, &done);
ioctl(fd, WDIOC_KEEPALIVE, &dummy);
return !write(fd, "V", 1);
}
return 0;
}
void watchdog(char *progname)
int watchdog(char *progname)
{
if (fork() == 0) {
int pid;
pid = fork();
if (pid == 0) {
int fd, ret;
fd = init(progname, WDT_DEVNODE, WDT_TIMEOUT);
@@ -129,6 +92,8 @@ void watchdog(char *progname)
_exit(ret);
}
return pid;
}
/**
+2 -2
View File
@@ -27,9 +27,9 @@
#define WDT_TIMEOUT 3
#ifdef BUILTIN_WATCHDOG
void watchdog(char *progname);
int watchdog(char *progname);
#else
#define watchdog(progname)
#define watchdog(progname) 0
#endif /* BUILTIN_WATCHDOG */
/**