From 09928421ea3718e96dee3c5cd2b1427dea557986 Mon Sep 17 00:00:00 2001 From: msizanoen Date: Tue, 18 Mar 2025 12:47:21 +0700 Subject: [PATCH] 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 85d00912c0fa08c80785d18a6818e7d92d40743e) (cherry picked from commit 4bf37df99c905d21cf0febde59190d885ad201dc) --- src/core/cgroup.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) 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) { -- 2.47.3