]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api.c: Add cgroup v2 support to cgroup_create_cgroup() 11/head
authorTom Hromatka <tom.hromatka@oracle.com>
Wed, 29 Jul 2020 16:52:49 +0000 (16:52 +0000)
committerTom Hromatka <tom.hromatka@oracle.com>
Wed, 29 Jul 2020 20:05:10 +0000 (20:05 +0000)
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.hromatka@oracle.com>
src/api.c

index 666ce33b45276aa1870f55aaf0c8d99268281bed..8d9c8d17f3ca2d6af0a8c5c1a419d5649751c60b 100644 (file)
--- 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);