From 279187d7d39b2be0f86069e6b8d63cc29809309d Mon Sep 17 00:00:00 2001 From: Tom Hromatka Date: Tue, 21 Feb 2023 14:17:58 -0700 Subject: [PATCH] api: Don't return an error when no cgroups are enabled Don't return an error, ECGROUPNOTEXIST (50002), from cgroup_get_cgroup() when no controllers are enabled in a cgroup v2 cgroup. Simple reproducer: sudo mkdir -p /sys/fs/cgroup/foo/bar #!/usr/bin/env python3 from libcgroup import Cgroup, Version cg = Cgroup('foo/bar', Version.CGROUP_V2) cg.get() print(cg) Prior to this change, the above python code returned ECGROUPNOTEXIST in the cg.get() line. Now it successfully completes, but no controllers are populated. Reported-by: Justin Israel Signed-off-by: Tom Hromatka (cherry picked from commit 7c99c8a385c5946c8873313b8c99cc9b5cf25bfd) --- src/api.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/api.c b/src/api.c index a944b73a..ad08bd37 100644 --- a/src/api.c +++ b/src/api.c @@ -3552,6 +3552,7 @@ int cgroup_get_cgroup(struct cgroup *cgroup) { struct dirent *ctrl_dir = NULL; int initial_controller_cnt; + int controller_cnt = 0; char *control_path = NULL; char path[FILENAME_MAX]; DIR *dir = NULL; @@ -3644,8 +3645,10 @@ int cgroup_get_cgroup(struct cgroup *cgroup) * and we've made it this far, then they are explicitly * interested in this controller and we should not remove it. */ - if (initial_controller_cnt == 0) + if (initial_controller_cnt == 0) { + controller_cnt++; continue; + } } else if (error) { goto unlock_error; } @@ -3667,6 +3670,8 @@ int cgroup_get_cgroup(struct cgroup *cgroup) goto unlock_error; } + controller_cnt++; + while ((ctrl_dir = readdir(dir)) != NULL) { /* Skip over non regular files */ if (ctrl_dir->d_type != DT_REG) @@ -3707,8 +3712,14 @@ int cgroup_get_cgroup(struct cgroup *cgroup) } } - /* Check if the group really exists or not */ - if (!cgroup->index) { + /* + * Check if the group really exists or not. The cgroup->index controller count can't + * be used in this case because cgroup v2 allows controllers to be enabled/disabled in + * the subtree_control file. Rather, cgroup_get_cgroup() tracks the number of possible + * controllers in the controller_cnt variable and uses that to determine if the cgroup + * exists or not. + */ + if (!controller_cnt) { error = ECGROUPNOTEXIST; goto unlock_error; } -- 2.47.2