diff options
-rw-r--r-- | src/core/cgroup.c | 22 | ||||
-rw-r--r-- | src/core/manager.c | 42 | ||||
-rw-r--r-- | src/core/manager.h | 3 |
3 files changed, 56 insertions, 11 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c index fe7c80fdbc..cebead5eb5 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1836,6 +1836,10 @@ int unit_pick_cgroup_path(Unit *u) { return 0; } +static int cg_v1_errno_to_log_level(int r) { + return r == -EROFS ? LOG_DEBUG : LOG_WARNING; +} + static int unit_update_cgroup( Unit *u, CGroupMask target_mask, @@ -1893,16 +1897,30 @@ static int unit_update_cgroup( * We perform migration also with whole slices for cases when users don't care about leave * granularity. Since delegated_mask is subset of target mask, we won't trim slice subtree containing * delegated units. + * + * If we're in an nspawn container and using legacy cgroups, the controller hierarchies are mounted + * read-only into the container. We skip migration/trim in this scenario since it would fail + * regardless with noisy "Read-only filesystem" warnings. */ if (cg_all_unified() == 0) { r = cg_migrate_v1_controllers(u->manager->cgroup_supported, migrate_mask, u->cgroup_path, migrate_callback, u); if (r < 0) - log_unit_warning_errno(u, r, "Failed to migrate controller cgroups from %s, ignoring: %m", u->cgroup_path); + log_unit_full_errno( + u, + cg_v1_errno_to_log_level(r), + r, + "Failed to migrate controller cgroups from %s, ignoring: %m", + u->cgroup_path); is_root_slice = unit_has_name(u, SPECIAL_ROOT_SLICE); r = cg_trim_v1_controllers(u->manager->cgroup_supported, ~target_mask, u->cgroup_path, !is_root_slice); if (r < 0) - log_unit_warning_errno(u, r, "Failed to delete controller cgroups %s, ignoring: %m", u->cgroup_path); + log_unit_full_errno( + u, + cg_v1_errno_to_log_level(r), + r, + "Failed to delete controller cgroups %s, ignoring: %m", + u->cgroup_path); } /* Set attributes */ 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_; |