]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api.c: Add function to recursively manage the cgroup v2 subtree
authorTom Hromatka <tom.hromatka@oracle.com>
Wed, 29 Jul 2020 16:46:44 +0000 (16:46 +0000)
committerTom Hromatka <tom.hromatka@oracle.com>
Wed, 29 Jul 2020 18:44:02 +0000 (18:44 +0000)
This commit adds the function cgroupv2_subtree_control_recursive().
cgroupv2_subtree_control_recursive() creates a cgroup hierarchy with
the subtree_control enabled in each parent cgroup for the requested
cgroup controller.

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

index d16b79c8e8e131d5fa634c5c326cafb7c7e682d1..666ce33b45276aa1870f55aaf0c8d99268281bed 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -1885,6 +1885,66 @@ out:
        return error;
 }
 
+/**
+ * Recursively enable/disable a controller in the cgv2 subtree_control file
+ *
+ * @param path Directory that contains the subtree_control file
+ * @param ctrl_name Name of the controller to be enabled/disabled
+ * @param enable Enable/Disable the given controller
+ */
+STATIC int cgroupv2_subtree_control_recursive(char *path,
+                                             const char *ctrl_name,
+                                             bool enable)
+{
+       char *path_copy, *tmp_path, *stok_buff = NULL;
+       bool found_mount = false;
+       size_t mount_len;
+       int i, error = 0;
+
+       for (i = 0; cg_mount_table[i].name[0] != '\0'; i++) {
+               if (strncmp(cg_mount_table[i].name, ctrl_name,
+                   sizeof(cg_mount_table[i].name)) == 0) {
+                       found_mount = true;
+                       break;
+               }
+       }
+
+       if (!found_mount)
+               return ECGROUPSUBSYSNOTMOUNTED;
+
+       path_copy = strdup(path);
+       if (!path_copy)
+               return ECGOTHER;
+
+       /* Null terminate the path_copy to match the string length of the
+        * controller mount.  We'll incrementally build up the string,
+        * subdir by subdir, and enable the subtree control file each step
+        * of the way
+        */
+       mount_len = strlen(cg_mount_table[i].mount.path);
+       path_copy[mount_len] = '\0';
+
+       tmp_path = strtok_r(&path[mount_len], "/", &stok_buff);
+       do {
+               if (tmp_path) {
+                       strcat(path_copy, "/");
+                       strcat(path_copy, tmp_path);
+               }
+
+               error = cg_create_control_group(path_copy);
+               if (error)
+                       goto out;
+
+               error = cgroupv2_subtree_control(path_copy, ctrl_name, enable);
+               if (error)
+                       goto out;
+       } while ((tmp_path = strtok_r(NULL, "/", &stok_buff)));
+
+out:
+       free(path_copy);
+       return error;
+}
+
 /** cgroup_modify_cgroup modifies the cgroup control files.
  * struct cgroup *cgroup: The name will be the cgroup to be modified.
  * The values will be the values to be modified, those not mentioned