From: Tom Hromatka Date: Tue, 21 Feb 2023 21:17:58 +0000 (-0700) Subject: api: Don't return an error when no cgroups are enabled X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=279187d7d39b2be0f86069e6b8d63cc29809309d;p=thirdparty%2Flibcgroup.git 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) --- 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; }