1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-28 11:55:44 +03:00

watchdog: pass USEC_INFINITY to watchdog_setup() to reuse the programmed timeout value

This patch changes the meaning of USEC_INFINITY value for the watchdog
module.

Previously passing this value was a NOP. It now has a special meaning: it
requests the watchdog module to read the programmed timeout value and reuse it
for pinging the device.

This is mostly useful when the watchdog is started by the firmware and there's
no way to reconfigure the timeout with a different value
afterwards. "RuntimeWatchdogSec=infinity" in system.conf can now be used rather
than putting an arbitrary value that PID1 will fail to set (even if it still
felt back to the programmed timeout).

Please note that "infinity" is not supposed to restore the default value of the
firmware. If the value is changed after booting then "infinity" would simply
reuse the current programmed value. IOW it's a NOP unless the watchdog was
previously closed and in that case it will be reopened and the last programmed
value reused.
This commit is contained in:
Franck Bui 2021-09-17 10:34:35 +02:00
parent ef1d5f3c5c
commit c1a08a76ab

View File

@ -15,8 +15,8 @@
#include "watchdog.h"
static int watchdog_fd = -1;
static char *watchdog_device = NULL;
static usec_t watchdog_timeout = USEC_INFINITY;
static char *watchdog_device;
static usec_t watchdog_timeout; /* USEC_INFINITY → don't change timeout */
static usec_t watchdog_last_ping = USEC_INFINITY;
static int watchdog_set_enable(bool enable) {
@ -89,20 +89,23 @@ static int update_timeout(void) {
if (watchdog_fd < 0)
return 0;
if (watchdog_timeout == USEC_INFINITY)
return 0;
if (watchdog_timeout == 0)
return watchdog_set_enable(false);
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));
if (watchdog_timeout != USEC_INFINITY) {
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));
log_info("Modifying watchdog timeout is not supported, reusing the programmed timeout.");
log_info("Modifying watchdog timeout is not supported, reusing the programmed timeout.");
watchdog_timeout = USEC_INFINITY;
}
}
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");
@ -164,11 +167,6 @@ int watchdog_setup(usec_t timeout) {
* supported by the driver */
watchdog_timeout = timeout;
/* If we didn't open the watchdog yet and didn't get any explicit
* timeout value set, don't do anything */
if (watchdog_fd < 0 && watchdog_timeout == USEC_INFINITY)
return 0;
if (watchdog_fd < 0)
return open_watchdog();
@ -194,7 +192,7 @@ usec_t watchdog_runtime_wait(void) {
int watchdog_ping(void) {
usec_t ntime;
if (!timestamp_is_set(watchdog_timeout))
if (watchdog_timeout == 0)
return 0;
if (watchdog_fd < 0)
@ -239,5 +237,5 @@ void watchdog_close(bool disarm) {
/* Once closed, pinging the device becomes a NOP and we request a new
* call to watchdog_setup() to open the device again. */
watchdog_timeout = USEC_INFINITY;
watchdog_timeout = 0;
}