diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-04-29 20:22:36 -0300 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-04-30 08:36:01 -0300 |
commit | 8af8afd6b3a34d1218826f55ada8ece8b4e36fed (patch) | |
tree | 2158894c31fed3ad2543623beedce46451a44b52 /src/shared | |
parent | 5f1dac6bf605871615b35891a3966fa474db5b20 (diff) |
cgroup: make cg_pid_get_path() work properly for co-mounted controllers and normalized named hierarchies
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/cgroup-util.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 016080f65b..1366f5865f 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -736,24 +736,27 @@ int cg_set_task_access( } int cg_pid_get_path(const char *controller, pid_t pid, char **path) { - char fs[sizeof("/proc/") - 1 + DECIMAL_STR_MAX(pid_t) + sizeof("/cgroup")]; _cleanup_fclose_ FILE *f = NULL; char line[LINE_MAX]; + const char *fs; size_t cs; assert(path); assert(pid >= 0); - if (controller && !cg_controller_is_valid(controller, true)) - return -EINVAL; + if (controller) { + if (!cg_controller_is_valid(controller, true)) + return -EINVAL; - if (!controller) + controller = normalize_controller(controller); + } else controller = SYSTEMD_CGROUP_CONTROLLER; if (pid == 0) - pid = getpid(); + fs = "/proc/self/cgroup"; + else + fs = procfs_file_alloca(pid, "cgroup"); - sprintf(fs, "/proc/%lu/cgroup", (unsigned long) pid); f = fopen(fs, "re"); if (!f) return errno == ENOENT ? -ESRCH : -errno; @@ -761,7 +764,10 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { cs = strlen(controller); FOREACH_LINE(line, f, return -errno) { - char *l, *p; + char *l, *p, *w, *e; + size_t k; + char *state; + bool found = false; truncate_nl(line); @@ -770,13 +776,31 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { continue; l++; - if (!strneq(l, controller, cs)) + e = strchr(l, ':'); + if (!e) continue; - if (l[cs] != ':') + *e = 0; + + FOREACH_WORD_SEPARATOR(w, k, l, ",", state) { + + if (k == cs && memcmp(w, controller, cs) == 0) { + found = true; + break; + } + + if (k == 5 + cs && + memcmp(w, "name=", 5) == 0 && + memcmp(w+5, controller, cs) == 0) { + found = true; + break; + } + } + + if (!found) continue; - p = strdup(l + cs + 1); + p = strdup(e + 1); if (!p) return -ENOMEM; |