]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
watchdog: configuring a timeout value might not be supported by the HW
authorFranck Bui <fbui@suse.com>
Thu, 16 Sep 2021 16:46:04 +0000 (18:46 +0200)
committerFranck Bui <fbui@suse.com>
Wed, 13 Oct 2021 06:51:13 +0000 (08:51 +0200)
In that case we should hanlde this case more gracefully by reusing the
programmed value.

Fixes: #20683
src/shared/watchdog.c

index 3f4effddb51c9d2807848c4c99e66af1dd735c2c..44974aa633861776188502c86b3e8e319ae076c5 100644 (file)
@@ -40,6 +40,20 @@ static int watchdog_set_enable(bool enable) {
         return 0;
 }
 
+static int watchdog_get_timeout(void) {
+        int sec = 0;
+
+        assert(watchdog_fd > 0);
+
+        if (ioctl(watchdog_fd, WDIOC_GETTIMEOUT, &sec) < 0)
+                return -errno;
+
+        assert(sec > 0);
+        watchdog_timeout = sec * USEC_PER_SEC;
+
+        return 0;
+}
+
 static int watchdog_set_timeout(void) {
         usec_t t;
         int sec;
@@ -51,15 +65,11 @@ static int watchdog_set_timeout(void) {
         sec = MIN(t, (usec_t) INT_MAX); /* Saturate */
 
         if (ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &sec) < 0)
-                return log_warning_errno(errno, "Failed to set timeout to %is, ignoring: %m", sec);
+                return -errno;
 
-        /* Just in case the driver is buggy */
-        assert(sec > 0);
-
-        /* watchdog_timeout stores the timeout used by the HW */
+        assert(sec > 0);/*  buggy driver ? */
         watchdog_timeout = sec * USEC_PER_SEC;
 
-        log_info("Set hardware watchdog to %s.", FORMAT_TIMESPAN(watchdog_timeout, 0));
         return 0;
 }
 
@@ -86,13 +96,24 @@ static int update_timeout(void) {
                 return watchdog_set_enable(false);
 
         r = watchdog_set_timeout();
-        if (r < 0)
-                return r;
+        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.");
+
+                r = watchdog_get_timeout();
+                if (r < 0)
+                        return log_warning_errno(errno, "Failed to query watchdog HW timeout, ignoring: %m");
+        }
 
         r = watchdog_set_enable(true);
         if (r < 0)
                 return r;
 
+        log_info("Watchdog running with a timeout of %s.", FORMAT_TIMESPAN(watchdog_timeout, 0));
+
         return watchdog_ping_now();
 }