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;
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;
}
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();
}