From 1021b21bc6f8dd522b46116e8598b17f9f93f1b7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 Jun 2013 01:46:27 +0200 Subject: [PATCH] login: add an api to determine the slice a PID is located in to libsystemd-login --- src/login/libsystemd-login.sym | 5 ++++ src/login/sd-login.c | 10 +++++++ src/shared/cgroup-util.c | 51 ++++++++++++++++++++++++++++++++-- src/shared/cgroup-util.h | 2 ++ src/systemd/sd-login.h | 5 +++- src/test/test-cgroup-util.c | 8 ++++-- 6 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym index 925fb9109..417dbb18d 100644 --- a/src/login/libsystemd-login.sym +++ b/src/login/libsystemd-login.sym @@ -75,3 +75,8 @@ LIBSYSTEMD_LOGIN_203 { global: sd_get_machine_names; } LIBSYSTEMD_LOGIN_202; + +LIBSYSTEMD_LOGIN_204 { +global: + sd_pid_get_slice; +} LIBSYSTEMD_LOGIN_203; diff --git a/src/login/sd-login.c b/src/login/sd-login.c index 875d134ef..06587921c 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -72,6 +72,16 @@ _public_ int sd_pid_get_machine_name(pid_t pid, char **name) { return cg_pid_get_machine_name(pid, name); } +_public_ int sd_pid_get_slice(pid_t pid, char **slice) { + + if (pid < 0) + return -EINVAL; + if (!slice) + return -EINVAL; + + return cg_pid_get_slice(pid, slice); +} + _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { if (pid < 0) diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 05d026a58..9cbc64a54 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1227,11 +1227,11 @@ int cg_path_decode_unit(const char *cgroup, char **unit){ } static const char *skip_slices(const char *p) { - size_t n; - /* Skips over all slice assignments */ for (;;) { + size_t n; + p += strspn(p, "/"); n = strcspn(p, "/"); @@ -1475,6 +1475,53 @@ int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) { return cg_path_get_owner_uid(cgroup, uid); } +int cg_path_get_slice(const char *p, char **slice) { + const char *e = NULL; + size_t m = 0; + + assert(p); + assert(slice); + + for (;;) { + size_t n; + + p += strspn(p, "/"); + + n = strcspn(p, "/"); + if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0) { + char *s; + + if (!e) + return -ENOENT; + + s = strndup(e, m); + if (!s) + return -ENOMEM; + + *slice = s; + return 0; + } + + e = p; + m = n; + + p += n; + } +} + +int cg_pid_get_slice(pid_t pid, char **slice) { + _cleanup_free_ char *cgroup = NULL; + int r; + + assert(slice); + + r = cg_pid_get_path_shifted(pid, NULL, &cgroup); + if (r < 0) + return r; + + return cg_path_get_slice(cgroup, slice); +} + int cg_controller_from_attr(const char *attr, char **controller) { const char *dot; char *c; diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 0485c11ad..2d00bb3ff 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -90,6 +90,7 @@ 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_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); int cg_pid_get_path_shifted(pid_t pid, char **root, char **cgroup); @@ -98,6 +99,7 @@ int cg_pid_get_owner_uid(pid_t pid, uid_t *uid); int cg_pid_get_unit(pid_t pid, char **unit); int cg_pid_get_user_unit(pid_t pid, char **unit); int cg_pid_get_machine_name(pid_t pid, char **machine); +int cg_pid_get_slice(pid_t pid, char **slice); int cg_path_decode_unit(const char *cgroup, char **unit); diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h index 4855e327a..e37aeda2b 100644 --- a/src/systemd/sd-login.h +++ b/src/systemd/sd-login.h @@ -72,9 +72,12 @@ int sd_pid_get_unit(pid_t pid, char **unit); int sd_pid_get_user_unit(pid_t pid, char **unit); /* Get machine name from PID, for processes assigned to VM or - * container. This will return an error for non-service processes. */ + * container. This will return an error for non-machine processes. */ int sd_pid_get_machine_name(pid_t pid, char **name); +/* Get slice name from PID. */ +int sd_pid_get_slice(pid_t pid, char **name); + /* Get state from uid. Possible states: offline, lingering, online, active, closing */ int sd_uid_get_state(uid_t uid, char**state); diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index aea8a7a1c..f6317e5d3 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -134,7 +134,7 @@ static void test_proc(void) { assert_se(d); FOREACH_DIRENT(de, d, break) { - _cleanup_free_ char *path = NULL, *path_shifted = NULL, *session = NULL, *unit = NULL, *user_unit = NULL, *machine = NULL, *prefix = NULL; + _cleanup_free_ char *path = NULL, *path_shifted = NULL, *session = NULL, *unit = NULL, *user_unit = NULL, *machine = NULL, *prefix = NULL, *slice = NULL; pid_t pid; uid_t uid = (uid_t) -1; @@ -156,8 +156,9 @@ static void test_proc(void) { cg_pid_get_unit(pid, &unit); cg_pid_get_user_unit(pid, &user_unit); cg_pid_get_machine_name(pid, &machine); + cg_pid_get_slice(pid, &slice); - printf("%lu\t%s\t%s\t%s\t%lu\t%s\t%s\t%s\t%s\n", + printf("%lu\t%s\t%s\t%s\t%lu\t%s\t%s\t%s\t%s\t%s\n", (unsigned long) pid, path, prefix, @@ -166,7 +167,8 @@ static void test_proc(void) { session, unit, user_unit, - machine); + machine, + slice); } } -- 2.30.2