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);
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
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) {