From: Tom Hromatka Date: Fri, 27 Jan 2023 20:24:31 +0000 (-0700) Subject: systemd: Add cgroup_create_scope2() X-Git-Tag: v3.1.0~237 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a1ec6c4ec58710451ef73a2043fdfb192028babc;p=thirdparty%2Flibcgroup.git systemd: Add cgroup_create_scope2() 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 Reviewed-by: Kamalesh Babulal --- diff --git a/include/libcgroup/systemd.h b/include/libcgroup/systemd.h index f12772ab..17efa51c 100644 --- a/include/libcgroup/systemd.h +++ b/include/libcgroup/systemd.h @@ -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 diff --git a/src/libcgroup.map b/src/libcgroup.map index ce6c0546..07bd7816 100644 --- a/src/libcgroup.map +++ b/src/libcgroup.map @@ -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; diff --git a/src/systemd.c b/src/systemd.c index cbd36c25..8cd108a5 100644 --- a/src/systemd.c +++ b/src/systemd.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #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; +}