]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api.c: Add function to read the cgroup.subtree_control file
authorTom Hromatka <tom.hromatka@oracle.com>
Wed, 23 Sep 2020 16:41:00 +0000 (10:41 -0600)
committerTom Hromatka <tom.hromatka@oracle.com>
Thu, 15 Oct 2020 19:43:09 +0000 (13:43 -0600)
Add a function, cgroupv2_get_subtree_control(), that verifies
if a controller is enabled in the cgroup.subtree_control file
for the requested path.

This function will be used in the next commit - "api.c: Add function
to check if a controller is enabled for a cgroup v2 cgroup" - to
determine if the requested cgroup v2 controller is enabled for a
cgroup.  This is a required check to ensure that the
cgclassify/cgexec operation will succeed.

Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
src/api.c
src/libcgroup-internal.h

index 274718bbe8f4ed1985cdb8126eeddbbbab28ad75..88042f95a51c3b655683858c23d8cf95dd3b3e27 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -1884,6 +1884,72 @@ err:
        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)
+{
+       char *path_copy = NULL, *saveptr = NULL, *token, *ret_c;
+       int ret, error = ECGROUPNOTMOUNTED;
+       char buffer[FILENAME_MAX];
+       FILE *fp = NULL;
+
+       if (!path || !ctrl_name || !enabled)
+               return ECGOTHER;
+
+       *enabled = false;
+
+       path_copy = (char *)malloc(FILENAME_MAX);
+       if (!path_copy)
+               goto out;
+
+       ret = snprintf(path_copy, FILENAME_MAX, "%s/%s", path,
+                      CGV2_SUBTREE_CTRL_FILE);
+       if (ret < 0)
+               goto out;
+
+       fp = fopen(path_copy, "re");
+       if (!fp) {
+               cgroup_warn("Warning: fopen failed\n");
+               last_errno = errno;
+               goto out;
+       }
+
+       ret_c = fgets(buffer, sizeof(buffer), fp);
+       if (ret_c == NULL)
+               /* The subtree control file is empty */
+               goto out;
+
+       /* remove the trailing newline */
+       ret_c[strlen(ret_c) - 1] = '\0';
+
+       /* Split the enabled controllers by " " and evaluate if the requested
+        * controller is enabled.
+        */
+       token = strtok_r(buffer, " ", &saveptr);
+       do {
+               if (strncmp(ctrl_name, token, FILENAME_MAX) == 0) {
+                       error = 0;
+                       *enabled = true;
+                       break;
+               }
+       } while ((token = strtok_r(NULL, " ", &saveptr)));
+
+out:
+       if (path_copy)
+               free(path_copy);
+       if (fp)
+               fclose(fp);
+
+       return error;
+}
+
 /**
  * Enable/Disable a controller in the cgroup v2 subtree_control file
  *
index 72ddc19ea6e56133127079ac77df53d5f11792f2..b834202dcf6b07a58e0ddbae2c56fa3cb2e8e3d5 100644 (file)
@@ -347,6 +347,9 @@ int cgroup_build_tasks_procs_path(char * const path,
                                  size_t path_sz, const char * const cg_name,
                                  const char * const ctrl_name);
 
+int cgroupv2_get_subtree_control(const char *path,
+                                const char *ctrl_name,
+                                bool * const enabled);
 #endif /* UNIT_TEST */
 
 __END_DECLS