diff --git a/src/core/manager.c b/src/core/manager.c index 1f1450b97c..4b215a6176 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2937,8 +2937,10 @@ int manager_loop(Manager *m) { usec_t wait_usec, watchdog_usec; watchdog_usec = manager_get_watchdog(m, WATCHDOG_RUNTIME); - if (timestamp_is_set(watchdog_usec)) + if (m->runtime_watchdog_running) (void) watchdog_ping(); + else if (timestamp_is_set(watchdog_usec)) + manager_retry_runtime_watchdog(m); if (!ratelimit_below(&rl)) { /* Yay, something is going seriously wrong, pause a little */ @@ -3408,14 +3410,18 @@ void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout) { if (t == WATCHDOG_RUNTIME) if (!timestamp_is_set(m->watchdog_overridden[WATCHDOG_RUNTIME])) { - if (timestamp_is_set(timeout)) + if (timestamp_is_set(timeout)) { r = watchdog_set_timeout(&timeout); - else + + if (r >= 0) + m->runtime_watchdog_running = true; + } else { watchdog_close(true); + m->runtime_watchdog_running = false; + } } - if (r >= 0) - m->watchdog[t] = timeout; + m->watchdog[t] = timeout; } int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout) { @@ -3433,18 +3439,36 @@ int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout) { usec_t *p; p = timestamp_is_set(timeout) ? &timeout : &m->watchdog[t]; - if (timestamp_is_set(*p)) + if (timestamp_is_set(*p)) { r = watchdog_set_timeout(p); - else + + if (r >= 0) + m->runtime_watchdog_running = true; + } else { watchdog_close(true); + m->runtime_watchdog_running = false; + } } - if (r >= 0) - m->watchdog_overridden[t] = timeout; + m->watchdog_overridden[t] = timeout; return 0; } +void manager_retry_runtime_watchdog(Manager *m) { + int r = 0; + + assert(m); + + if (timestamp_is_set(m->watchdog_overridden[WATCHDOG_RUNTIME])) + r = watchdog_set_timeout(&m->watchdog_overridden[WATCHDOG_RUNTIME]); + else + r = watchdog_set_timeout(&m->watchdog[WATCHDOG_RUNTIME]); + + if (r >= 0) + m->runtime_watchdog_running = true; +} + static void manager_deserialize_uid_refs_one_internal( Manager *m, Hashmap** uid_refs, diff --git a/src/core/manager.h b/src/core/manager.h index d22c801da8..19df889dd8 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -241,6 +241,8 @@ struct Manager { usec_t watchdog[_WATCHDOG_TYPE_MAX]; usec_t watchdog_overridden[_WATCHDOG_TYPE_MAX]; + bool runtime_watchdog_running; /* Whether the runtime HW watchdog was started, so we know if we still need to get the real timeout from the hardware */ + dual_timestamp timestamps[_MANAGER_TIMESTAMP_MAX]; /* Data specific to the device subsystem */ @@ -562,6 +564,7 @@ ManagerTimestamp manager_timestamp_initrd_mangle(ManagerTimestamp s); usec_t manager_get_watchdog(Manager *m, WatchdogType t); void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout); int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout); +void manager_retry_runtime_watchdog(Manager *m); const char* oom_policy_to_string(OOMPolicy i) _const_; OOMPolicy oom_policy_from_string(const char *s) _pure_;