]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
watchdog: ensure configured timeout is used instead of USEC_INFINITY
authorHolger Assmann <h.assmann@pengutronix.de>
Tue, 9 Jan 2024 14:05:19 +0000 (15:05 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 10 Jan 2024 19:14:38 +0000 (19:14 +0000)
In some rare cases, a watchdog driver might neither be able to change
the watchdog timeout value, nor read it from the hardware at runtime.

With an otherwise functional watchdog setup, this constellation worked
until systemd v249. Since then, systemd ends up ignoring the timeout
defined by the system.conf and rather uses USEC_INFINITY. Consequently,
the watchdog is not pinged anymore and eventually resets the system.

We therefore want to ensure that the system keeps running with the
originally configured timeout.

src/shared/watchdog.c

index 4c1a96871832fe45fcb2b22f1d15c3553b903af3..2d79f7147a8cef9750045ade46a558191d4154a6 100644 (file)
@@ -261,12 +261,15 @@ static int update_pretimeout(void) {
 
 static int update_timeout(void) {
         int r;
+        usec_t previous_timeout;
 
         assert(watchdog_timeout > 0);
 
         if (watchdog_fd < 0)
                 return 0;
 
+        previous_timeout = watchdog_timeout;
+
         if (watchdog_timeout != USEC_INFINITY) {
                 r = watchdog_set_timeout();
                 if (r < 0) {
@@ -281,8 +284,12 @@ static int update_timeout(void) {
 
         if (watchdog_timeout == USEC_INFINITY) {
                 r = watchdog_read_timeout();
-                if (r < 0)
-                        return log_error_errno(r, "Failed to query watchdog HW timeout: %m");
+                if (r < 0) {
+                        if (!ERRNO_IS_NOT_SUPPORTED(r))
+                                return log_error_errno(r, "Failed to query watchdog HW timeout: %m");
+                        log_info("Reading watchdog timeout is not supported, reusing the configured timeout.");
+                        watchdog_timeout = previous_timeout;
+                }
         }
 
         /* If the watchdog timeout was changed, the pretimeout could have been