References: bsc#1178736 Allow restart of xenwatchdogd in case it terminated unexpectetly. Index: xen-4.19.0-testing/tools/misc/xenwatchdogd.c =================================================================== --- xen-4.19.0-testing.orig/tools/misc/xenwatchdogd.c +++ xen-4.19.0-testing/tools/misc/xenwatchdogd.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #define WDOG_MIN_TIMEOUT 2 #define WDOG_MIN_SLEEP 1 @@ -29,9 +31,11 @@ static xc_interface *h; static volatile bool safeexit = false; static volatile bool done = false; +static const char id_file[] = "/run/xenwatchdog_id.txt"; -static void daemonize(void) +static void daemonize(const char *str) { + const char *err_str = ""; switch (fork()) { case -1: err(EXIT_FAILURE, "fork"); @@ -40,7 +44,9 @@ static void daemonize(void) default: exit(EXIT_SUCCESS); } - umask(0); +#define err(x,s) do { err_str = (s); goto out; } while (0) + openlog(str, LOG_CONS, LOG_DAEMON); + umask(~(S_IRUSR|S_IWUSR)); if (setsid() < 0) err(EXIT_FAILURE, "setsid"); if (chdir("/") < 0) @@ -51,6 +57,10 @@ static void daemonize(void) err(EXIT_FAILURE, "reopen stdout"); if(freopen("/dev/null", "w", stderr) == NULL) err(EXIT_FAILURE, "reopen stderr"); + return; +out: + syslog(LOG_ERR, "%s: %m", err_str); + exit(1); } static void catch_exit(int sig) @@ -62,6 +72,7 @@ static void catch_usr1(int sig) { safeexit = true; done = true; + unlink(id_file); } static void __attribute__((noreturn)) usage(int exit_code) @@ -98,10 +109,12 @@ static int parse_secs(const char *arg, c int main(int argc, char **argv) { + FILE *f; int id; int t, s; int ret; bool daemon = true; + const char *err_str = ""; for ( ;; ) { @@ -160,7 +173,7 @@ int main(int argc, char **argv) s = t / 2; if (daemon) - daemonize(); + daemonize(basename(argv[0])); h = xc_interface_open(NULL, NULL, 0); if (h == NULL) @@ -177,9 +190,25 @@ int main(int argc, char **argv) if (signal(SIGUSR1, &catch_usr1) == SIG_ERR) err(EXIT_FAILURE, "signal"); - id = xc_watchdog(h, 0, t); - if (id <= 0) - err(EXIT_FAILURE, "xc_watchdog setup"); + f = fopen(id_file, "r"); + if (f) { + if (fscanf(f, "%d", &id) != 1) + id = -1; + if (id <= 0) + err(EXIT_FAILURE, "xc_watchdog setup"); + syslog(LOG_INFO, "reusing id %d", id); + fclose(f); + } else { + id = xc_watchdog(h, 0, t); + syslog(LOG_INFO, "obtained id %d", id); + if (id <= 0) + err(EXIT_FAILURE, "xc_watchdog setup"); + f = fopen(id_file, "w"); + if (f) { + fprintf(f, "%d\n", id); + fclose(f); + } + } while (!done) { sleep(s); @@ -191,4 +220,8 @@ int main(int argc, char **argv) // Zero seconds timeout will disarm the watchdog timer xc_watchdog(h, id, safeexit ? 0 : WDOG_EXIT_TIMEOUT); return 0; + +out: + syslog(LOG_ERR, "%s: %m", err_str); + exit(EXIT_FAILURE); }