From c1a08a76ab6761eee9d537c0e0fb6252a4961b14 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Fri, 17 Sep 2021 10:34:35 +0200 Subject: [PATCH] watchdog: pass USEC_INFINITY to watchdog_setup() to reuse the programmed timeout value This patch changes the meaning of USEC_INFINITY value for the watchdog module. Previously passing this value was a NOP. It now has a special meaning: it requests the watchdog module to read the programmed timeout value and reuse it for pinging the device. This is mostly useful when the watchdog is started by the firmware and there's no way to reconfigure the timeout with a different value afterwards. "RuntimeWatchdogSec=infinity" in system.conf can now be used rather than putting an arbitrary value that PID1 will fail to set (even if it still felt back to the programmed timeout). Please note that "infinity" is not supposed to restore the default value of the firmware. If the value is changed after booting then "infinity" would simply reuse the current programmed value. IOW it's a NOP unless the watchdog was previously closed and in that case it will be reopened and the last programmed value reused. --- src/shared/watchdog.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/shared/watchdog.c b/src/shared/watchdog.c index 44974aa6338..1b5239888f1 100644 --- a/src/shared/watchdog.c +++ b/src/shared/watchdog.c @@ -15,8 +15,8 @@ #include "watchdog.h" static int watchdog_fd = -1; -static char *watchdog_device = NULL; -static usec_t watchdog_timeout = USEC_INFINITY; +static char *watchdog_device; +static usec_t watchdog_timeout; /* USEC_INFINITY → don't change timeout */ static usec_t watchdog_last_ping = USEC_INFINITY; static int watchdog_set_enable(bool enable) { @@ -89,20 +89,23 @@ static int update_timeout(void) { if (watchdog_fd < 0) return 0; - if (watchdog_timeout == USEC_INFINITY) - return 0; if (watchdog_timeout == 0) return watchdog_set_enable(false); - r = watchdog_set_timeout(); - if (r < 0) { - if (!ERRNO_IS_NOT_SUPPORTED(r)) - return log_warning_errno(r, "Failed to set timeout to %s, ignoring: %m", - FORMAT_TIMESPAN(watchdog_timeout, 0)); + if (watchdog_timeout != USEC_INFINITY) { + r = watchdog_set_timeout(); + if (r < 0) { + if (!ERRNO_IS_NOT_SUPPORTED(r)) + return log_warning_errno(r, "Failed to set timeout to %s, ignoring: %m", + FORMAT_TIMESPAN(watchdog_timeout, 0)); - log_info("Modifying watchdog timeout is not supported, reusing the programmed timeout."); + log_info("Modifying watchdog timeout is not supported, reusing the programmed timeout."); + watchdog_timeout = USEC_INFINITY; + } + } + if (watchdog_timeout == USEC_INFINITY) { r = watchdog_get_timeout(); if (r < 0) return log_warning_errno(errno, "Failed to query watchdog HW timeout, ignoring: %m"); @@ -164,11 +167,6 @@ int watchdog_setup(usec_t timeout) { * supported by the driver */ watchdog_timeout = timeout; - /* If we didn't open the watchdog yet and didn't get any explicit - * timeout value set, don't do anything */ - if (watchdog_fd < 0 && watchdog_timeout == USEC_INFINITY) - return 0; - if (watchdog_fd < 0) return open_watchdog(); @@ -194,7 +192,7 @@ usec_t watchdog_runtime_wait(void) { int watchdog_ping(void) { usec_t ntime; - if (!timestamp_is_set(watchdog_timeout)) + if (watchdog_timeout == 0) return 0; if (watchdog_fd < 0) @@ -239,5 +237,5 @@ void watchdog_close(bool disarm) { /* Once closed, pinging the device becomes a NOP and we request a new * call to watchdog_setup() to open the device again. */ - watchdog_timeout = USEC_INFINITY; + watchdog_timeout = 0; }