]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api: Don't return an error when no cgroups are enabled
authorTom Hromatka <tom.hromatka@oracle.com>
Tue, 21 Feb 2023 21:17:58 +0000 (14:17 -0700)
committerTom Hromatka <tom.hromatka@oracle.com>
Wed, 22 Feb 2023 16:35:44 +0000 (09:35 -0700)
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 <justinisrael@gmail.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
(cherry picked from commit 7c99c8a385c5946c8873313b8c99cc9b5cf25bfd)

src/api.c

index a944b73afd84d3f88057811b0e3828d46f839fda..ad08bd3706704b1ef0fb38e1a0cdb1ced8bf7f35 100644 (file)
--- 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;
        }