This commit adds cgroup v2 support go cgroup_create_cgroup().
If the controller is mounted via cgroup v2, then the
subtree_control file in the parent directory will be updated
to enable the controller in children cgroups.  The tasks
file is only updated for cgroup v1 mounts.

Here's an example of creating a cgroup hierarchy in a single command:
        sudo cgcreate -g io:a/b/c/d

The above cgcreate example is equivalent to:
        mkdir -p {root_cg}/a/b/c/d
        echo +io > {root_cg}/cgroup.subtree_control
        echo +io > {root_cg}/a/cgroup.subtree_control
        echo +io > {root_cg}/a/b/cgroup.subtree_control
        echo +io > {root_cg}/a/b/c/cgroup.subtree_control

Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com>
---
 src/api.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/api.c b/src/api.c
index 666ce33b4527..8d9c8d17f3ca 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2118,6 +2118,7 @@ err:
  */
 int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership)
 {
+       enum cg_version_t version;
        char *fts_path[2];
        char *base = NULL;
        char *path = NULL;
@@ -2154,6 +2155,29 @@ int cgroup_create_cgroup(struct cgroup *cgroup, int 
ignore_ownership)
                                cgroup->controller[k]->name))
                        continue;
 
+               error = cgroup_get_controller_version(
+                       cgroup->controller[k]->name, &version);
+               if (error)
+                       goto err;
+
+               if (version == CGROUP_V2) {
+                       char *parent, *dname;
+
+                       parent = strdup(path);
+                       if (!parent) {
+                               error = ECGOTHER;
+                               goto err;
+                       }
+
+                       dname = dirname(parent);
+
+                       error = cgroupv2_subtree_control_recursive(dname,
+                                       cgroup->controller[k]->name, true);
+                       free(parent);
+                       if (error)
+                               goto err;
+               }
+
                error = cg_create_control_group(path);
                if (error)
                        goto err;
@@ -2187,7 +2211,7 @@ int cgroup_create_cgroup(struct cgroup *cgroup, int 
ignore_ownership)
                if (error)
                        goto err;
 
-               if (!ignore_ownership) {
+               if (!ignore_ownership && version == CGROUP_V1) {
                        error = cgroup_chown_chmod_tasks(base,
                                        cgroup->tasks_uid, cgroup->tasks_gid,
                                        cgroup->task_fperm);
-- 
2.25.3



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

Reply via email to