diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-04-14 02:15:13 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-04-16 18:59:07 +0200 |
commit | 3474ae3c7e1981301d0b35bc89d759ca13f06e8f (patch) | |
tree | 077a731a876821609751b1abcbe654cdfa6f288e /src/shared/cgroup-util.c | |
parent | 80172751b7a678834c1a453ae28c0eb333958250 (diff) |
cgroup: if a controller is not available don't try to create cgroups in its hierarchy
Diffstat (limited to 'src/shared/cgroup-util.c')
-rw-r--r-- | src/shared/cgroup-util.c | 82 |
1 files changed, 54 insertions, 28 deletions
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 86f354dbe7..b2fb324a18 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -502,14 +502,47 @@ finish: return ret; } +static const char *normalize_controller(const char *controller) { + + if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) + return "systemd"; + else if (startswith(controller, "name=")) + return controller + 5; + else + return controller; +} + +static int join_path(const char *controller, const char *path, const char *suffix, char **fs) { + char *t; + + if (path && suffix) + t = join("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL); + else if (path) + t = join("/sys/fs/cgroup/", controller, "/", path, NULL); + else if (suffix) + t = join("/sys/fs/cgroup/", controller, "/", suffix, NULL); + else + t = join("/sys/fs/cgroup/", controller, NULL); + + if (!t) + return -ENOMEM; + + path_kill_slashes(t); + + *fs = t; + return 0; +} + int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) { const char *p; - char *t; static __thread bool good = false; assert(controller); assert(fs); + if (isempty(controller)) + return -EINVAL; + if (_unlikely_(!good)) { int r; @@ -521,38 +554,30 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch good = true; } - if (isempty(controller)) - return -EINVAL; + p = normalize_controller(controller); - /* This is a very minimal lookup from controller names to - * paths. Since we have mounted most hierarchies ourselves - * should be kinda safe, but eventually we might want to - * extend this to have a fallback to actually check - * /proc/mounts. Might need caching then. */ + return join_path(p, path, suffix, fs); +} - if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) - p = "systemd"; - else if (startswith(controller, "name=")) - p = controller + 5; - else - p = controller; +int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) { + const char *p; + char *cc; - if (path && suffix) - t = join("/sys/fs/cgroup/", p, "/", path, "/", suffix, NULL); - else if (path) - t = join("/sys/fs/cgroup/", p, "/", path, NULL); - else if (suffix) - t = join("/sys/fs/cgroup/", p, "/", suffix, NULL); - else - t = join("/sys/fs/cgroup/", p, NULL); + assert(controller); + assert(fs); - if (!t) - return -ENOMEM; + if (isempty(controller)) + return -EINVAL; - path_kill_slashes(t); + p = normalize_controller(controller); - *fs = t; - return 0; + /* Check if this controller actually really exists */ + cc = alloca(sizeof("/sys/fs/cgroup/") + strlen(p)); + strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p); + if (access(cc, F_OK) < 0) + return -errno; + + return join_path(p, path, suffix, fs); } static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { @@ -646,7 +671,8 @@ int cg_attach(const char *controller, const char *path, pid_t pid) { assert(path); assert(pid >= 0); - if ((r = cg_get_path(controller, path, "tasks", &fs)) < 0) + r = cg_get_path_and_check(controller, path, "tasks", &fs); + if (r < 0) return r; if (pid == 0) |