From: Quentin Deslandes Date: Thu, 26 Jan 2023 18:39:08 +0000 (+0100) Subject: core: add cg_path_get_unit_path() X-Git-Tag: v253-rc3~19^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ee164216d38bc7ca51e040b90bdc96ed7518df37;p=thirdparty%2Fsystemd.git core: add cg_path_get_unit_path() From a given cgroup path, cg_path_get_unit() allows to retrieve the unit's name. Although, this removes the path to the unit's cgroup, preventing the result to be used to fetch xattrs. Introduce cg_path_get_unit_path() which provides the path to the unit's cgroup. This function behave similarly to cg_path_get_unit() (checking the validity and escaping the unit's name). --- diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index a8e4a1bb2d2..feda5969390 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -1198,6 +1198,28 @@ int cg_path_get_unit(const char *path, char **ret) { return 0; } +int cg_path_get_unit_path(const char *path, char **ret) { + _cleanup_free_ char *path_copy = NULL; + char *unit_name; + + assert(path); + assert(ret); + + path_copy = strdup(path); + if (!path_copy) + return -ENOMEM; + + unit_name = (char *)skip_slices(path_copy); + unit_name[strcspn(unit_name, "/")] = 0; + + if (!unit_name_is_valid(cg_unescape(unit_name), UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) + return -ENXIO; + + *ret = TAKE_PTR(path_copy); + + return 0; +} + int cg_pid_get_unit(pid_t pid, char **unit) { _cleanup_free_ char *cgroup = NULL; int r; diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index c9aae5abf62..b69f1683dbe 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -261,6 +261,7 @@ int cg_path_get_cgroupid(const char *path, uint64_t *ret); int cg_path_get_session(const char *path, char **session); int cg_path_get_owner_uid(const char *path, uid_t *uid); int cg_path_get_unit(const char *path, char **unit); +int cg_path_get_unit_path(const char *path, char **unit); int cg_path_get_user_unit(const char *path, char **unit); int cg_path_get_machine_name(const char *path, char **machine); int cg_path_get_slice(const char *path, char **slice); diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index 0b286ed8e45..cdf911926ca 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -63,6 +63,33 @@ TEST(path_get_unit) { check_p_g_u("/user.slice/user-1000.slice/user@.service/server.service", -ENXIO, NULL); } +static void check_p_g_u_p(const char *path, int code, const char *result) { + _cleanup_free_ char *unit_path = NULL; + int r; + + r = cg_path_get_unit_path(path, &unit_path); + printf("%s: %s → %s %d expected %s %d\n", __func__, path, unit_path, r, strnull(result), code); + assert_se(r == code); + assert_se(streq_ptr(unit_path, result)); +} + +TEST(path_get_unit_path) { + check_p_g_u_p("/system.slice/foobar.service/sdfdsaf", 0, "/system.slice/foobar.service"); + check_p_g_u_p("/system.slice/getty@tty5.service", 0, "/system.slice/getty@tty5.service"); + check_p_g_u_p("/system.slice/getty@tty5.service/aaa/bbb", 0, "/system.slice/getty@tty5.service"); + check_p_g_u_p("/system.slice/getty@tty5.service/", 0, "/system.slice/getty@tty5.service"); + check_p_g_u_p("/system.slice/getty@tty6.service/tty5", 0, "/system.slice/getty@tty6.service"); + check_p_g_u_p("sadfdsafsda", -ENXIO, NULL); + check_p_g_u_p("/system.slice/getty####@tty6.service/xxx", -ENXIO, NULL); + check_p_g_u_p("/system.slice/system-waldo.slice/foobar.service/sdfdsaf", 0, "/system.slice/system-waldo.slice/foobar.service"); + check_p_g_u_p("/system.slice/system-waldo.slice/_cpu.service/sdfdsaf", 0, "/system.slice/system-waldo.slice/_cpu.service"); + check_p_g_u_p("/system.slice/system-waldo.slice/_cpu.service", 0, "/system.slice/system-waldo.slice/_cpu.service"); + check_p_g_u_p("/user.slice/user-1000.slice/user@1000.service/server.service", 0, "/user.slice/user-1000.slice/user@1000.service"); + check_p_g_u_p("/user.slice/user-1000.slice/user@.service/server.service", -ENXIO, NULL); + check_p_g_u_p("/user.slice/_user-1000.slice/user@1000.service/foobar.slice/foobar@pie.service", 0, "/user.slice/_user-1000.slice/user@1000.service"); + check_p_g_u_p("/_session-2.scope/_foobar@pie.service/pa/po", 0, "/_session-2.scope"); +} + static void check_p_g_u_u(const char *path, int code, const char *result) { _cleanup_free_ char *unit = NULL; int r;