core/cgroup: Properly handle aborting a pending freeze operation

We must thaw the cgroup even if cgroup.events/frozen=0 if a freeze
operation is in flight as it means the cgroup is already partially
frozen.

Fixes #37590.
Fixes #38337.

(cherry picked from commit 85d00912c0)
(cherry picked from commit 4bf37df99c)
This commit is contained in:
msizanoen authored and Zbigniew Jędrzejewski-Szmek committed 2025-07-29 13:08:03 +02:00
1 parent 71e09b0a4f
commit 09928421ea
1 file changed
+17 -8
+17 -8
View File
@@ -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, &current);
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) {