]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
systemd: Add cgroup_create_scope2()
authorTom Hromatka <tom.hromatka@oracle.com>
Fri, 27 Jan 2023 21:08:25 +0000 (14:08 -0700)
committerTom Hromatka <tom.hromatka@oracle.com>
Fri, 27 Jan 2023 21:08:25 +0000 (14:08 -0700)
Add cgroup_create_scope2() as a wrapper function around
cgroup_create_scope().  cgroup_create_scope2() is more libcgroup-ish
and utilizes struct cgroup rather than systemd-style parameters.

Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
Reviewed-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
(cherry picked from commit a1ec6c4ec58710451ef73a2043fdfb192028babc)

include/libcgroup/systemd.h
src/libcgroup.map
src/systemd.c

index f12772ab235ddbc308a378a55eba7ebc6b53e646..17efa51c7585f3e8f6d6d4dcbc042720bf5b1e6b 100644 (file)
@@ -54,6 +54,21 @@ int cgroup_set_default_scope_opts(struct cgroup_systemd_scope_opts * const opts)
 int cgroup_create_scope(const char * const scope_name, const char * const slice_name,
                        const struct cgroup_systemd_scope_opts * const opts);
 
+/**
+ * Create a systemd scope
+ *
+ * @param cgroup
+ * @param ignore_ownership When nonzero, all errors are ignored when setting owner of the group
+ *     owner of the group and/or its tasks file
+ * @param opts Scope creation options structure instance
+ *
+ * @return 0 on success and > 0 on error
+ *
+ * @note The cgroup->name field should be of the form "foo.slice/bar.scope"
+ */
+int cgroup_create_scope2(struct cgroup *cgroup, int ignore_ownership,
+                        const struct cgroup_systemd_scope_opts * const opts);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index ce6c0546411c8e74b7725c419fe8a2f1fd4b56fb..07bd7816105d57dde9a06307108d2a060c6af7a1 100644 (file)
@@ -154,4 +154,5 @@ CGROUP_3.0 {
        cgroup_get_controller_count;
        cgroup_get_controller_by_index;
        cgroup_get_controller_name;
+       cgroup_create_scope2;
 } CGROUP_2.0;
index cbd36c25ab3697d45b221e042a8447afd1f99943..8cd108a59ac8c92d39f9e8fb7dcf76c6aa120c30 100644 (file)
@@ -10,6 +10,8 @@
 #include <libcgroup.h>
 #include <unistd.h>
 #include <assert.h>
+#include <stdlib.h>
+#include <libgen.h>
 #include <errno.h>
 
 #define USEC_PER_SEC 1000000
@@ -281,3 +283,60 @@ out:
 
        return ret;
 }
+
+int cgroup_create_scope2(struct cgroup *cgroup, int ignore_ownership,
+                        const struct cgroup_systemd_scope_opts * const opts)
+{
+       char *copy1 = NULL, *copy2 = NULL, *slash, *slice_name, *scope_name;
+       int ret = 0;
+
+       if (!cgroup)
+               return ECGROUPNOTALLOWED;
+
+       slash = strstr(cgroup->name, "/");
+       if (!slash) {
+               cgroup_err("cgroup name does not contain a slash: %s\n", cgroup->name);
+               return ECGINVAL;
+       }
+
+       slash = strstr(slash + 1, "/");
+       if (slash) {
+               cgroup_err("cgroup name contains more than one slash: %s\n", cgroup->name);
+               return ECGINVAL;
+       }
+
+       copy1 = strdup(cgroup->name);
+       if (!copy1) {
+               ret = ECGOTHER;
+               goto err;
+       }
+
+       scope_name = basename(copy1);
+
+       copy2 = strdup(cgroup->name);
+       if (!copy2) {
+               ret = ECGOTHER;
+               goto err;
+       }
+
+       slice_name = dirname(copy2);
+
+       ret = cgroup_create_scope(scope_name, slice_name, opts);
+       if (ret)
+               goto err;
+
+       /*
+        * Utilize cgroup_create_cgroup() to assign the requested owner/group and permissions.
+        * cgroup_create_cgroup() can gracefully handle EEXIST if the cgroup already exists, so
+        * we can reuse its ownership logic without penalty.
+        */
+       ret = cgroup_create_cgroup(cgroup, ignore_ownership);
+
+err:
+       if (copy1)
+               free(copy1);
+       if (copy2)
+               free(copy2);
+
+       return ret;
+}