summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/cgroup.c22
-rw-r--r--src/core/manager.c42
-rw-r--r--src/core/manager.h3
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_;