From: Kamalesh Babulal Date: Wed, 8 Feb 2023 09:40:23 +0000 (+0530) Subject: api: cg_build_path_locked() - support default systemd delegate scope X-Git-Tag: v3.1.0~215 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4ec9a941ec0d1a92934a97a4226bb1fe14a34aa;p=thirdparty%2Flibcgroup.git api: cg_build_path_locked() - support default systemd delegate scope Add support to build cgroup path to the default systemd slice/scope cgroup, if setdefault is set in the systemd configuration of the cgconfig.conf. $ cat /etc/cgconfig.conf ... systemd { slice = database.slice; scope = db.scope; setdefault = yes; <-- set cgroup root path to '/sys/fs/cgroup/database.slice/db.scope/' } systemd { slice = database.slice; scope = house_keeping.scope; pid = 3241; } systemd { slice = others.slice; scope = server.scope; } cg_build_path() constructs the cgroup path to the mount point of the given cgroup controller. With the support for the default systemd scope, the default cgroup path for the controller, appends the slice/scope name, making it the default cgroup root. Allowing the users to set their default cgroup path from '/sys/fs/cgroup/' to '/sys/fs/cgroup///', while using the libcgroup tools, allowing them to work on the delegated cgroup hierarchy. Signed-off-by: Kamalesh Babulal Signed-off-by: Tom Hromatka --- diff --git a/src/api.c b/src/api.c index 3123c12a..ff79b344 100644 --- a/src/api.c +++ b/src/api.c @@ -1690,8 +1690,34 @@ char *cg_build_path_locked(const char *name, char *path, const char *type) * cg_mount_table[i].mount.path + '/' + cg_namespace_table[i] + '/' */ int i, ret, len = (FILENAME_MAX * 2) + 2; - char *_path; + char *tmp_systemd_default_cgroup, *_path = NULL; + /* + * systemd_default_cgroup can't be clobbered. The user may pass + * multiple cgroups, hence use temporary variable for manipulations + * for example: + * cgget -g cpu:/ -g cpu:cgrp1 -g cpu:/cgrp2 + */ + tmp_systemd_default_cgroup = calloc(1, (sizeof(char) * len)); + if (!tmp_systemd_default_cgroup) { + cgroup_err("Failed to allocate memory for tmp_systemd_default_cgroup\n"); + goto out; + } + +#ifdef WITH_SYSTEMD + /* + * If the user specifies the name as /, they are + * effectively overriding the systemd_default_cgroup but if the name + * is "/", the cgroup root path is systemd_default_cgroup + */ + if (strlen(systemd_default_cgroup) && name && name[0] == '/' && name[1] != '\0') + tmp_systemd_default_cgroup[0] = '\0'; + else + snprintf(tmp_systemd_default_cgroup, len, "%s/", systemd_default_cgroup); + + /* allocate more space for systemd_default_cgroup + '/' */ + len += (FILENAME_MAX + 1); +#endif /* * Recent gcc are unhappy when sizeof(dest) <= sizeof(src) with * snprintf()'s. Alternative is to use multiple strncpy()/strcat(), @@ -1701,7 +1727,7 @@ char *cg_build_path_locked(const char *name, char *path, const char *type) _path = malloc(len); if (!_path) { cgroup_err("Failed to allocate memory for _path\n"); - return NULL; + goto out; } /* @@ -1711,7 +1737,8 @@ char *cg_build_path_locked(const char *name, char *path, const char *type) * any controller. */ if (!type && strlen(cg_cgroup_v2_mount_path) > 0) { - ret = snprintf(_path, len, "%s/", cg_cgroup_v2_mount_path); + ret = snprintf(_path, len, "%s/%s", cg_cgroup_v2_mount_path, + tmp_systemd_default_cgroup); if (ret >= FILENAME_MAX) cgroup_dbg("filename too long: %s", _path); @@ -1745,10 +1772,11 @@ char *cg_build_path_locked(const char *name, char *path, const char *type) cg_mount_table[i].version == CGROUP_V2)) { if (cg_namespace_table[i]) - ret = snprintf(_path, len, "%s/%s/", cg_mount_table[i].mount.path, - cg_namespace_table[i]); + ret = snprintf(_path, len, "%s/%s%s/", cg_mount_table[i].mount.path, + tmp_systemd_default_cgroup, cg_namespace_table[i]); else - ret = snprintf(_path, len, "%s/", cg_mount_table[i].mount.path); + ret = snprintf(_path, len, "%s/%s", cg_mount_table[i].mount.path, + tmp_systemd_default_cgroup); if (ret >= FILENAME_MAX) cgroup_dbg("filename too long: %s", _path); @@ -1775,6 +1803,9 @@ out: if (_path) free(_path); + if (tmp_systemd_default_cgroup) + free(tmp_systemd_default_cgroup); + return path; }