cgroup: if a controller is not available don't try to create cgroups in its hierarchy

This commit is contained in:
Lennart Poettering 2012-04-14 02:15:13 +02:00
parent 80172751b7
commit 3474ae3c7e
4 changed files with 62 additions and 32 deletions

View File

@ -334,7 +334,8 @@ int manager_setup_cgroup(Manager *m) {
}
/* 2. Show data */
if ((r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path)) < 0) {
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path);
if (r < 0) {
log_error("Cannot find cgroup mount point: %s", strerror(-r));
goto finish;
}
@ -342,7 +343,8 @@ int manager_setup_cgroup(Manager *m) {
log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path);
/* 3. Install agent */
if ((r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH)) < 0)
r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH);
if (r < 0)
log_warning("Failed to install release agent, ignoring: %s", strerror(-r));
else if (r > 0)
log_debug("Installed release agent.");

View File

@ -43,7 +43,8 @@ int cg_create(const char *controller, const char *path) {
assert(controller);
assert(path);
if ((r = cg_get_path(controller, path, NULL, &fs)) < 0)
r = cg_get_path_and_check(controller, path, NULL, &fs);
if (r < 0)
return r;
r = mkdir_parents(fs, 0755);

View File

@ -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;
}
p = normalize_controller(controller);
return join_path(p, path, suffix, fs);
}
int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) {
const char *p;
char *cc;
assert(controller);
assert(fs);
if (isempty(controller))
return -EINVAL;
/* 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. */
p = normalize_controller(controller);
if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
p = "systemd";
else if (startswith(controller, "name="))
p = controller + 5;
else
p = controller;
/* 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;
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);
if (!t)
return -ENOMEM;
path_kill_slashes(t);
*fs = t;
return 0;
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)

View File

@ -48,6 +48,7 @@ int cg_join_spec(const char *controller, const char *path, char **spec);
int cg_fix_path(const char *path, char **result);
int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs);
int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs);
int cg_get_by_pid(const char *controller, pid_t pid, char **path);
int cg_trim(const char *controller, const char *path, bool delete_root);