From 0ffdfe7d6863e6d479323d90c222f2dcae2ff057 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Mon, 27 Sep 2021 10:51:28 +0200 Subject: [PATCH] watchdog: handle timeout programming errors more safely If an error happened while the timeout value was being programmed, the error was ignored and the watchdog module used the new timeout value whereas the watchdog device was left with the previous one. Now in cases of error, the device is now disabled and closed if it wasn't opened already otherwise the previous timeout value is kept so the device is still pinged at correct intervals. --- src/shared/watchdog.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/shared/watchdog.c b/src/shared/watchdog.c index b6fddd193f..4de6003039 100644 --- a/src/shared/watchdog.c +++ b/src/shared/watchdog.c @@ -96,8 +96,8 @@ static int update_timeout(void) { 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)); + return log_error_errno(r, "Failed to set timeout to %s: %m", + FORMAT_TIMESPAN(watchdog_timeout, 0)); log_info("Modifying watchdog timeout is not supported, reusing the programmed timeout."); watchdog_timeout = USEC_INFINITY; @@ -107,7 +107,7 @@ static int update_timeout(void) { 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"); + return log_error_errno(errno, "Failed to query watchdog HW timeout: %m"); } r = watchdog_set_enable(true); @@ -122,6 +122,7 @@ static int update_timeout(void) { static int open_watchdog(void) { struct watchdog_info ident; const char *fn; + int r; if (watchdog_fd >= 0) return 0; @@ -139,7 +140,11 @@ static int open_watchdog(void) { ident.firmware_version, fn); - return update_timeout(); + r = update_timeout(); + if (r < 0) + watchdog_close(true); + + return r; } int watchdog_set_device(const char *path) { @@ -156,6 +161,8 @@ int watchdog_set_device(const char *path) { } int watchdog_setup(usec_t timeout) { + usec_t previous_timeout; + int r; /* timeout=0 closes the device whereas passing timeout=USEC_INFINITY * opens it (if needed) without configuring any particular timeout and @@ -175,12 +182,17 @@ int watchdog_setup(usec_t timeout) { /* Initialize the watchdog timeout with the caller value. This value is * going to be updated by update_timeout() with the closest value * supported by the driver */ + previous_timeout = watchdog_timeout; watchdog_timeout = timeout; if (watchdog_fd < 0) return open_watchdog(); - return update_timeout(); + r = update_timeout(); + if (r < 0) + watchdog_timeout = previous_timeout; + + return r; } usec_t watchdog_runtime_wait(void) {