summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2017-06-16 16:53:00 -0400
committerLuke Shumaker <lukeshu@parabola.nu>2018-08-16 21:55:16 -0400
commitc78e01b44da66f9e57a74b4b15fa2890b852b43f (patch)
treeb54d7a219dde93411f24a54823de56b16fb89eca
parentaa4ec7c7ad44dcfb26ccf2cfc01bf3a2ad4b4a0c (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.c40
-rw-r--r--src/basic/cgroup-util.h1
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);