return 0;
}
-static bool scope_check_gc(Unit *u) {
- assert(u);
-
- /* Never clean up scopes that still have a process around,
- * even if the scope is formally dead. */
-
- if (!u->cgroup_path)
- return false;
-
- return cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path) <= 0;
-}
-
static void scope_notify_cgroup_empty_event(Unit *u) {
Scope *s = SCOPE(u);
assert(u);
.active_state = scope_active_state,
.sub_state_to_string = scope_sub_state_to_string,
- .check_gc = scope_check_gc,
-
.sigchld_event = scope_sigchld_event,
.reset_failed = scope_reset_failed,
assert(s);
- /* Never clean up services that still have a process around,
- * even if the service is formally dead. */
- if (cgroup_good(s) > 0 ||
- main_pid_good(s) > 0 ||
+ /* Never clean up services that still have a process around, even if the service is formally dead. Note that
+ * unit_check_gc() already checked our cgroup for us, we just check our two additional PIDs, too, in case they
+ * have moved outside of the cgroup. */
+
+ if (main_pid_good(s) > 0 ||
control_pid_good(s) > 0)
return true;
bool unit_check_gc(Unit *u) {
UnitActiveState state;
+ int r;
assert(u);
assert_not_reached("Unknown garbage collection mode");
}
+ if (u->cgroup_path) {
+ /* If the unit has a cgroup, then check whether there's anything in it. If so, we should stay
+ * around. Units with active processes should never be collected. */
+
+ r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path);
+ if (r < 0)
+ log_unit_debug_errno(u, r, "Failed to determine whether cgroup %s is empty: %m", u->cgroup_path);
+ if (r <= 0)
+ return true;
+ }
+
if (UNIT_VTABLE(u)->check_gc)
if (UNIT_VTABLE(u)->check_gc(u))
return true;