]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
cgroups: detect and record cgroup2 freezer support
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 26 Jan 2021 14:28:39 +0000 (15:28 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 26 Jan 2021 14:35:54 +0000 (15:35 +0100)
Cc: stable-4.0
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/cgroups/cgfsng.c
src/lxc/cgroups/cgroup.h

index c6d05c37685b038e0d9973f2967c8391491c7a0d..4e8512360bc663c53bda0636af0044cd06cfdcad 100644 (file)
@@ -157,12 +157,24 @@ static struct hierarchy *get_hierarchy(struct cgroup_ops *ops, const char *contr
                                return ops->hierarchies[i];
 
                        continue;
-               } else if (pure_unified_layout(ops) &&
-                          strcmp(controller, "devices") == 0) {
-                       if (ops->unified->bpf_device_controller)
-                               return ops->unified;
+               }
 
-                       break;
+               /*
+                * Handle controllers with significant implementation changes
+                * from cgroup to cgroup2.
+                */
+               if (pure_unified_layout(ops)) {
+                       if (strcmp(controller, "devices") == 0) {
+                               if (ops->unified->bpf_device_controller)
+                                       return ops->unified;
+
+                               break;
+                       } else if (strcmp(controller, "freezer") == 0) {
+                               if (ops->unified->freezer_controller)
+                                       return ops->unified;
+
+                               break;
+                       }
                }
 
                if (string_in_list(ops->hierarchies[i]->controllers, controller))
@@ -1653,6 +1665,27 @@ __cgfsng_ops static void cgfsng_payload_finalize(struct cgroup_ops *ops)
                if (!is_unified_hierarchy(h))
                        close_prot_errno_disarm(h->cgfd_con);
        }
+
+       /*
+        * The checking for freezer support should obviously be done at cgroup
+        * initialization time but that doesn't work reliable. The freezer
+        * controller has been demoted (rightly so) to a simple file located in
+        * each non-root cgroup. At the time when the container is created we
+        * might still be located in /sys/fs/cgroup and so checking for
+        * cgroup.freeze won't tell us anything because this file doesn't exist
+        * in the root cgroup. We could then iterate through /sys/fs/cgroup and
+        * find an already existing cgroup and then check within that cgroup
+        * for the existence of cgroup.freeze but that will only work on
+        * systemd based hosts. Other init systems might not manage cgroups and
+        * so no cgroup will exist. So we defer until we have created cgroups
+        * for our container which means we check here.
+        */
+        if (pure_unified_layout(ops) &&
+            !faccessat(ops->unified->cgfd_con, "cgroup.freeze", F_OK,
+                       AT_SYMLINK_NOFOLLOW)) {
+               TRACE("Unified hierarchy supports freezer");
+               ops->unified->freezer_controller = 1;
+        }
 }
 
 /* cgroup-full:* is done, no need to create subdirs */
index b8a4d0f5bfa5847cdb23471b2eec4647b0d193f8..7d95dfd35356bc974d067c90d23e3d9557744eba 100644 (file)
@@ -89,6 +89,7 @@ struct hierarchy {
 
        /* cgroup2 only */
        unsigned int bpf_device_controller:1;
+       unsigned int freezer_controller:1;
 
        /* container cgroup fd */
        int cgfd_con;