1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-10 05:18:17 +03:00

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.
This commit is contained in:
Franck Bui 2021-09-27 10:51:28 +02:00
parent b3aa73e4de
commit 0ffdfe7d68

View File

@ -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) {