};
_cleanup_strv_free_ char **env_block = NULL;
+ usec_t watchdog_timer = 0;
size_t pos = 7;
int r;
- usec_t watchdog_timer = 0;
assert(shutdown_verb);
assert(!command_line[pos]);
else if (streq(shutdown_verb, "kexec"))
watchdog_timer = arg_kexec_watchdog;
- if (timestamp_is_set(watchdog_timer)) {
- /* If we reboot or kexec let's set the shutdown watchdog and tell the shutdown binary to
- * repeatedly ping it */
- r = watchdog_setup(watchdog_timer);
- watchdog_close(r < 0);
+ /* If we reboot or kexec let's set the shutdown watchdog and tell the
+ * shutdown binary to repeatedly ping it */
+ r = watchdog_setup(watchdog_timer);
+ watchdog_close(r < 0);
- /* Tell the binary how often to ping, ignore failure */
- (void) strv_extendf(&env_block, "WATCHDOG_USEC="USEC_FMT, watchdog_timer);
+ /* Tell the binary how often to ping, ignore failure */
+ (void) strv_extendf(&env_block, "WATCHDOG_USEC="USEC_FMT, watchdog_timer);
- if (arg_watchdog_device)
- (void) strv_extendf(&env_block, "WATCHDOG_DEVICE=%s", arg_watchdog_device);
- } else
- watchdog_close(true);
+ if (arg_watchdog_device)
+ (void) strv_extendf(&env_block, "WATCHDOG_DEVICE=%s", arg_watchdog_device);
/* Avoid the creation of new processes forked by the kernel; at this
* point, we will not listen to the signals anyway */
return;
if (t == WATCHDOG_RUNTIME)
- if (!timestamp_is_set(m->watchdog_overridden[WATCHDOG_RUNTIME])) {
- if (timestamp_is_set(timeout))
- (void) watchdog_setup(timeout);
- else
- watchdog_close(true);
- }
+ if (!timestamp_is_set(m->watchdog_overridden[WATCHDOG_RUNTIME]))
+ (void) watchdog_setup(timeout);
m->watchdog[t] = timeout;
}
if (t == WATCHDOG_RUNTIME) {
usec_t usec = timestamp_is_set(timeout) ? timeout : m->watchdog[t];
- if (timestamp_is_set(usec))
- (void) watchdog_setup(usec);
- else
- watchdog_close(true);
+ (void) watchdog_setup(usec);
}
m->watchdog_overridden[t] = timeout;
static int watchdog_fd = -1;
static char *watchdog_device;
-static usec_t watchdog_timeout; /* USEC_INFINITY → don't change timeout */
+static usec_t watchdog_timeout; /* 0 → close device and USEC_INFINITY → don't change timeout */
static usec_t watchdog_last_ping = USEC_INFINITY;
static int watchdog_set_enable(bool enable) {
static int update_timeout(void) {
int r;
+ assert(watchdog_timeout > 0);
+
if (watchdog_fd < 0)
return 0;
- if (watchdog_timeout == 0)
- return watchdog_set_enable(false);
-
if (watchdog_timeout != USEC_INFINITY) {
r = watchdog_set_timeout();
if (r < 0) {
int watchdog_setup(usec_t timeout) {
+ /* timeout=0 closes the device whereas passing timeout=USEC_INFINITY
+ * opens it (if needed) without configuring any particular timeout and
+ * thus reuses the programmed value (therefore it's a nop if the device
+ * is already opened).
+ */
+
+ if (timeout == 0) {
+ watchdog_close(true);
+ return 0;
+ }
+
/* Let's shortcut duplicated requests */
- if (watchdog_fd >= 0 && watchdog_timeout == timeout)
+ if (watchdog_fd >= 0 && (timeout == watchdog_timeout || timeout == USEC_INFINITY))
return 0;
/* Initialize the watchdog timeout with the caller value. This value is
}
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 = 0;
+
if (watchdog_fd < 0)
return;
}
watchdog_fd = safe_close(watchdog_fd);
-
- /* Once closed, pinging the device becomes a NOP and we request a new
- * call to watchdog_setup() to open the device again. */
- watchdog_timeout = 0;
}