diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2017-06-16 16:53:00 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@parabola.nu> | 2018-08-16 21:55:16 -0400 |
commit | c78e01b44da66f9e57a74b4b15fa2890b852b43f (patch) | |
tree | b54d7a219dde93411f24a54823de56b16fb89eca | |
parent | aa4ec7c7ad44dcfb26ccf2cfc01bf3a2ad4b4a0c (diff) |
cgroup-util: Split out cg_pid_get_path_internal()
The name is a bit if a misnomer, because it doesn't work with a PID, but
with an already-opened /proc/${pid}/cgroup 'FILE*'.
It lets us bypass the controller=NULL and
controller=SYSTEMD_CGROUP_CONTROLLER special cases of cg_pid_get_path(), so
that we can directly check the cgroup v2 hierarchy; even if systemd isn't
using it (useful if we're doing work with a container that does use the v2
hierarchy). It also requires the caller to have already fopen()ed the
cgroup file (useful so that we can read from an fd passed over a socket).
-rw-r--r-- | src/basic/cgroup-util.c | 40 | ||||
-rw-r--r-- | src/basic/cgroup-util.h | 1 |
2 files changed, 34 insertions, 7 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index cb3e95bb3e..19db958c31 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -983,11 +983,17 @@ int cg_get_xattr(const char *controller, const char *path, const char *name, voi return (int) n; } +/** + * Returns the cgroup path of the process under the hierarchy specified by @controller: + * + * controller : whichever hierarchy has @controller bound to it (with a special case for the + * SYSTEMD_CGROUP_CONTROLLER ("_systemd") pseudo-controller) + * + * controller == NULL : equivalent to SYSTEMD_CGROUP_CONTROLLER + */ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { _cleanup_fclose_ FILE *f = NULL; - char line[LINE_MAX]; - const char *fs, *controller_str; - size_t cs = 0; + const char *fs, *controller_str = NULL; int unified; assert(path); @@ -1007,8 +1013,6 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { controller_str = SYSTEMD_CGROUP_CONTROLLER_LEGACY; else controller_str = controller; - - cs = strlen(controller_str); } fs = procfs_file_alloca(pid, "cgroup"); @@ -1016,6 +1020,28 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { if (!f) return errno == ENOENT ? -ESRCH : -errno; + return cg_pid_get_path_internal(controller_str, f, path); +} + +/** + * NB: The meaning of @controller is different here than for cg_pid_get_path(): + * + * controller : the cgroup v1 hierarchy with @controller bound to it + * controller == NULL : the cgroup v2 (unified) hierarchy + */ +int cg_pid_get_path_internal(const char *controller, FILE *f, char **path) { + char line[LINE_MAX]; + size_t cs = 0; + + assert(path); + assert(f); + + if (controller && !cg_controller_is_valid(controller)) + return -EINVAL; + + if (controller) + cs = strlen(controller); + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); FOREACH_LINE(line, f, return -errno) { @@ -1023,7 +1049,7 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { truncate_nl(line); - if (unified) { + if (!controller) { e = startswith(line, "0:"); if (!e) continue; @@ -1048,7 +1074,7 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { *e = 0; FOREACH_WORD_SEPARATOR(word, k, l, ",", state) - if (k == cs && memcmp(word, controller_str, cs) == 0) { + if (k == cs && memcmp(word, controller, cs) == 0) { found = true; break; } diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index 82999337db..6a840c328f 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -156,6 +156,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs); int cg_pid_get_path(const char *controller, pid_t pid, char **path); +int cg_pid_get_path_internal(const char *controller, FILE *f, char **path); int cg_trim(const char *controller, const char *path, bool delete_root); |