mirror of
https://github.com/systemd/systemd.git
synced 2026-11-06 05:17:24 +00:00
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 commit85d00912c0) (cherry picked from commit4bf37df99c)
This commit is contained in:
1 parent
71e09b0a4f
commit
09928421ea
1 file changed
+17
-8
+17
-8
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user