]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api: Read cgroup.controllers in cgroup_get_cgroup()
authorTom Hromatka <tom.hromatka@oracle.com>
Fri, 3 Mar 2023 17:02:50 +0000 (10:02 -0700)
committerTom Hromatka <tom.hromatka@oracle.com>
Tue, 28 Mar 2023 17:08:35 +0000 (11:08 -0600)
In cgroup_get_cgroup(), use the cgroup.controllers file
(rather than cgroup.subtree_control) to determine which
controllers are enabled.

To reduce code duplication, refactor cgroupv2_get_subtree_control()
to support reading both files.

Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
Reviewed-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
(cherry picked from commit 856ee1af70e7bac2a31be4f555543b0f6d2a133f)

src/api.c
tests/ftests/051-sudo-cgroup_get_cgroup.py
tests/ftests/052-sudo-cgroup_attach_task.py
tests/ftests/053-sudo-cgroup_attach_task_pid.py
tests/ftests/072-pybindings-cgroup_get_cgroup.py
tests/ftests/cgroup.py

index 43464fe6c7824eb18678db9ddbd84f5b362ea728..ccee631746ec891861ec33b1a95de65570f3943a 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -2363,16 +2363,19 @@ err:
 }
 
 /**
- * Check if the requested cgroup controller is enabled on this subtree
+ * Check if the requested cgroup controller is enabled in the specified file
  *
  * @param path Cgroup directory
  * @param ctrl_name Name of the controller to check
  * @param output parameter that indicates whether the controller is enabled
+ * @param file to open and parse
+ *     0 = cgroup.subtree_control
+ *     1 = cgroup.controllers
  */
-STATIC int cgroupv2_get_subtree_control(const char *path, const char *ctrl_name,
-                                       bool * const enabled)
+STATIC int __cgroupv2_get_enabled(const char *path, const char *ctrl_name,
+                                 bool * const enabled, int file_enum)
 {
-       char *path_copy = NULL, *saveptr = NULL, *token, *ret_c;
+       char *path_copy = NULL, *saveptr = NULL, *token, *ret_c, *filename;
        int ret, error = ECGROUPNOTMOUNTED;
        char buffer[FILENAME_MAX];
        FILE *fp = NULL;
@@ -2382,13 +2385,24 @@ STATIC int cgroupv2_get_subtree_control(const char *path, const char *ctrl_name,
 
        *enabled = false;
 
+       switch (file_enum) {
+       case 0: /* cgroup.subtree_control */
+               filename = CGV2_SUBTREE_CTRL_FILE;
+               break;
+       case 1: /* cgroup.controllers */
+               filename = CGV2_CONTROLLERS_FILE;
+               break;
+       default:
+               return ECGINVAL;
+       }
+
        path_copy = (char *)malloc(FILENAME_MAX);
        if (!path_copy) {
                error = ECGOTHER;
                goto out;
        }
 
-       ret = snprintf(path_copy, FILENAME_MAX, "%s/%s", path, CGV2_SUBTREE_CTRL_FILE);
+       ret = snprintf(path_copy, FILENAME_MAX, "%s/%s", path, filename);
        if (ret < 0) {
                error = ECGOTHER;
                goto out;
@@ -2432,6 +2446,31 @@ out:
        return error;
 }
 
+/**
+ * Check if the requested cgroup controller is enabled on this subtree
+ *
+ * @param path Cgroup directory
+ * @param ctrl_name Name of the controller to check
+ * @param output parameter that indicates whether the controller is enabled
+ */
+STATIC int cgroupv2_get_subtree_control(const char *path, const char *ctrl_name,
+                                       bool * const enabled)
+{
+       return __cgroupv2_get_enabled(path, ctrl_name, enabled, 0);
+}
+/**
+ * Check if the requested cgroup controller is enabled in this cgroup's cgroup.controllers file
+ *
+ * @param path Cgroup directory
+ * @param ctrl_name Name of the controller to check
+ * @param output parameter that indicates whether the controller is enabled
+ */
+static int cgroupv2_get_controllers(const char *path, const char *ctrl_name,
+                                   bool * const enabled)
+{
+       return __cgroupv2_get_enabled(path, ctrl_name, enabled, 1);
+}
+
 /**
  * Enable/Disable a controller in the cgroup v2 subtree_control file
  *
@@ -3663,8 +3702,8 @@ int cgroup_get_cgroup(struct cgroup *cgroup)
                } else { /* cgroup v2 */
                        bool enabled;
 
-                       error = cgroupv2_get_subtree_control(path, cg_mount_table[i].name,
-                                                            &enabled);
+                       error = cgroupv2_get_controllers(path, cg_mount_table[i].name,
+                                                        &enabled);
                        if (error == ECGROUPNOTMOUNTED) {
                                /*
                                 * This controller isn't enabled.  Only hide it from the
index 9814eeca6cca14d87ec950413b8a3be9b601acf8..9b2725b30d8b2cd27543581c578b5a7d138cd7be 100755 (executable)
@@ -14,7 +14,7 @@ import consts
 import sys
 import os
 
-CGNAME = '051cgnewcg'
+CGNAME = '051cgnewcg/childcg'
 
 # Which controller isn't all that important, but it is important that we
 # have a cgroup v2 controller
index aeb26b1294f529155718532336c0cb8d0104c4f5..aa20ac3e1fe5e2b7102f79f1d46419932d6e594b 100755 (executable)
@@ -50,7 +50,7 @@ def test(config):
     cause = None
 
     cg = Cgroup(CGNAME, Version.CGROUP_V2)
-    cg.get()
+    cg.add_controller(CONTROLLER)
     cg.attach()
 
     found = False
index 0e5010d698ae486d5bb3d81e420e2ca3818f7417..563235b30e86dda7eb976c6251c7a40d2e99a06e 100755 (executable)
@@ -15,7 +15,7 @@ import consts
 import sys
 import os
 
-CGNAME = '052cgattachcg'
+CGNAME = '053cgattachcg'
 
 # Which controller isn't all that important, but it is important that we
 # have a cgroup v2 controller
@@ -52,7 +52,7 @@ def test(config):
     child_pid = config.process.create_process(config)
 
     cg = Cgroup(CGNAME, Version.CGROUP_V2)
-    cg.get()
+    cg.add_controller(CONTROLLER)
     cg.attach(child_pid)
 
     found = False
index 1907d58352370ce2b95ea0a31f707b72c3845b05..952855c4bbeff64bfb508bf13c8714c9c2e542f1 100755 (executable)
@@ -14,10 +14,11 @@ import ftests
 import sys
 import os
 
-CGNAME = '072cggetcg'
+
+CGNAME = '072cggetcg/childcg'
 CONTROLLERS = ['cpu', 'memory', 'io', 'pids']
 
-CGNAME2 = '072cggetcg2/childcg'
+CGNAME2 = '{}/grandchildcg'.format(CGNAME)
 
 def prereqs(config):
     result = consts.TEST_PASSED
@@ -101,7 +102,9 @@ def test(config):
     # Test 5 - Create a parent/child cgroup with no controllers enabled.  Ensure the user can get
     # the cgroup with no errors.  .get() should populate zero cgroups
     #
+    CgroupCli.subtree_control(config, CGNAME, CONTROLLERS, enable=False, ignore_systemd=True)
     CgroupCli.create(config, None, CGNAME2)
+
     cgempty = Cgroup(CGNAME2, Version.CGROUP_V2)
     cgempty.get()
 
@@ -115,7 +118,6 @@ def test(config):
 
 
 def teardown(config):
-    CgroupCli.delete(config, CONTROLLERS, CGNAME)
     CgroupCli.delete(config, CONTROLLERS, CGNAME2, recursive=True)
 
 
index 557db8311af7d82e71c0fe78870189e381dfb382..50da99e718cab71c82771335e8d7d1466bf5f599 100644 (file)
@@ -1064,7 +1064,7 @@ class Cgroup(object):
         ctrl_path = Cgroup.__get_controller_mount_point_v2(ctrl_name)
         parent_cgname = os.path.dirname(cgroup_name)
 
-        subtree_path = os.path.join(ctrl_path, parent_cgname, 'cgroup.subtree_control')
+        subtree_path = os.path.join(ctrl_path, parent_cgname, 'cgroup.controllers')
         cmd = ['cat', subtree_path]
 
         if config.args.container: