diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 792d10cd514..ff988626d44 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -5124,6 +5124,7 @@ static int unit_cgroup_freezer_kernel_state(Unit *u, FreezerState *ret) { int unit_cgroup_freezer_action(Unit *u, FreezerAction action) { _cleanup_free_ char *path = NULL; FreezerState current, next, objective; + bool action_in_progress = false; int r; assert(u); @@ -5138,14 +5139,21 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) { CGroupRuntime *crt = unit_get_cgroup_runtime(u); if (!crt || !crt->cgroup_path) /* No realized cgroup = nothing to freeze */ - goto skip; + goto finish; r = unit_cgroup_freezer_kernel_state(u, ¤t); if (r < 0) return r; - if (current == objective) - goto skip; + if (current == objective) { + if (objective == FREEZER_FROZEN) + goto finish; + + /* Skip thaw only if no freeze operation was in flight */ + if (IN_SET(u->freezer_state, FREEZER_RUNNING, FREEZER_THAWING)) + goto finish; + } else + action_in_progress = true; if (next == freezer_state_finish(next)) { /* We're directly transitioning into a finished state, which in theory means that @@ -5177,12 +5185,13 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) { if (r < 0) return r; - unit_set_freezer_state(u, next); - return 1; /* Wait for cgroup event before replying */ +finish: + if (action_in_progress) + unit_set_freezer_state(u, next); + else + unit_set_freezer_state(u, freezer_state_finish(next)); -skip: - unit_set_freezer_state(u, freezer_state_finish(next)); - return 0; + return action_in_progress; } int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name) {