From: Tom Hromatka Date: Fri, 3 Mar 2023 17:02:50 +0000 (-0700) Subject: api: Read cgroup.controllers in cgroup_get_cgroup() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e057674f75d096df6ccdeed39ac5e251aa27dc0a;p=thirdparty%2Flibcgroup.git api: Read cgroup.controllers in cgroup_get_cgroup() 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 Reviewed-by: Kamalesh Babulal (cherry picked from commit 856ee1af70e7bac2a31be4f555543b0f6d2a133f) --- diff --git a/src/api.c b/src/api.c index 43464fe6..ccee6317 100644 --- 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 diff --git a/tests/ftests/051-sudo-cgroup_get_cgroup.py b/tests/ftests/051-sudo-cgroup_get_cgroup.py index 9814eeca..9b2725b3 100755 --- a/tests/ftests/051-sudo-cgroup_get_cgroup.py +++ b/tests/ftests/051-sudo-cgroup_get_cgroup.py @@ -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 diff --git a/tests/ftests/052-sudo-cgroup_attach_task.py b/tests/ftests/052-sudo-cgroup_attach_task.py index aeb26b12..aa20ac3e 100755 --- a/tests/ftests/052-sudo-cgroup_attach_task.py +++ b/tests/ftests/052-sudo-cgroup_attach_task.py @@ -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 diff --git a/tests/ftests/053-sudo-cgroup_attach_task_pid.py b/tests/ftests/053-sudo-cgroup_attach_task_pid.py index 0e5010d6..563235b3 100755 --- a/tests/ftests/053-sudo-cgroup_attach_task_pid.py +++ b/tests/ftests/053-sudo-cgroup_attach_task_pid.py @@ -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 diff --git a/tests/ftests/072-pybindings-cgroup_get_cgroup.py b/tests/ftests/072-pybindings-cgroup_get_cgroup.py index 1907d583..952855c4 100755 --- a/tests/ftests/072-pybindings-cgroup_get_cgroup.py +++ b/tests/ftests/072-pybindings-cgroup_get_cgroup.py @@ -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) diff --git a/tests/ftests/cgroup.py b/tests/ftests/cgroup.py index 557db831..50da99e7 100644 --- a/tests/ftests/cgroup.py +++ b/tests/ftests/cgroup.py @@ -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: