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.hroma...@oracle.com>
---
 src/api.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/src/api.c b/src/api.c
index d16b79c8e8e1..666ce33b4527 100644
--- 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
-- 
2.25.3



_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to