From: Franck Bui Date: Thu, 16 Sep 2021 16:46:04 +0000 (+0200) Subject: watchdog: configuring a timeout value might not be supported by the HW X-Git-Tag: v250-rc1~510^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ef1d5f3c5c613b9fa75d6a69bbc51a79361e28cc;p=thirdparty%2Fsystemd.git watchdog: configuring a timeout value might not be supported by the HW In that case we should hanlde this case more gracefully by reusing the programmed value. Fixes: #20683 --- diff --git a/src/shared/watchdog.c b/src/shared/watchdog.c index 3f4effddb51..44974aa6338 100644 --- a/src/shared/watchdog.c +++ b/src/shared/watchdog.c @@ -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(); }