]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
manager: Improve freeze/thaw for unrealized cgroup
authorAdrian Vovk <adrianvovk@gmail.com>
Mon, 22 Apr 2024 21:21:58 +0000 (17:21 -0400)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 23 Apr 2024 10:27:38 +0000 (12:27 +0200)
This is a follow-up for e50bfc89cefd4aafedaf2a7eacbf8b5ed80b134e

In that commit, we made Freeze/Thaw work with unrealized cgroups.
However, the unit was left in a strange state: it would be frozen by the
kernel but systemd would be unaware, and it remained possible to try and
realize the cgroup while the unit is supposed to be frozen. This commit
fixes the state tracking and prevents cgroups from being realized when
the unit is frozen.

src/core/cgroup.c

index 47f028fbe0711403cea34a3204fafc1c3badc4e3..d1f01e971817899c43c47b92fe86179eef86505c 100644 (file)
@@ -2866,6 +2866,9 @@ static int unit_update_cgroup(
         if (!UNIT_HAS_CGROUP_CONTEXT(u))
                 return 0;
 
+        if (u->freezer_state != FREEZER_RUNNING)
+                return log_unit_error_errno(u, SYNTHETIC_ERRNO(EBUSY), "Cannot realize cgroup for frozen unit.");
+
         /* Figure out our cgroup path */
         r = unit_pick_cgroup_path(u);
         if (r < 0)
@@ -5126,12 +5129,15 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) {
         if (!cg_freezer_supported())
                 return 0;
 
-        CGroupRuntime *crt = unit_get_cgroup_runtime(u);
-        if (!crt || !crt->cgroup_realized)
-                return 0; /* No cgroup = nothing running to freeze */
-
         unit_next_freezer_state(u, action, &next, &target);
 
+        CGroupRuntime *crt = unit_get_cgroup_runtime(u);
+        if (!crt || !crt->cgroup_realized) {
+                /* No realized cgroup = nothing to freeze */
+                u->freezer_state = freezer_state_finish(next);
+                return 0;
+        }
+
         r = unit_cgroup_freezer_kernel_state(u, &current);
         if (r < 0)
                 return r;