cgroup: if a controller is not available don't try to create cgroups in its hierarchy
This commit is contained in:
parent
80172751b7
commit
3474ae3c7e
|
@ -334,7 +334,8 @@ int manager_setup_cgroup(Manager *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. Show data */
|
/* 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));
|
log_error("Cannot find cgroup mount point: %s", strerror(-r));
|
||||||
goto finish;
|
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);
|
log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path);
|
||||||
|
|
||||||
/* 3. Install agent */
|
/* 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));
|
log_warning("Failed to install release agent, ignoring: %s", strerror(-r));
|
||||||
else if (r > 0)
|
else if (r > 0)
|
||||||
log_debug("Installed release agent.");
|
log_debug("Installed release agent.");
|
||||||
|
|
|
@ -43,7 +43,8 @@ int cg_create(const char *controller, const char *path) {
|
||||||
assert(controller);
|
assert(controller);
|
||||||
assert(path);
|
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;
|
return r;
|
||||||
|
|
||||||
r = mkdir_parents(fs, 0755);
|
r = mkdir_parents(fs, 0755);
|
||||||
|
|
|
@ -502,14 +502,47 @@ finish:
|
||||||
return ret;
|
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) {
|
int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) {
|
||||||
const char *p;
|
const char *p;
|
||||||
char *t;
|
|
||||||
static __thread bool good = false;
|
static __thread bool good = false;
|
||||||
|
|
||||||
assert(controller);
|
assert(controller);
|
||||||
assert(fs);
|
assert(fs);
|
||||||
|
|
||||||
|
if (isempty(controller))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (_unlikely_(!good)) {
|
if (_unlikely_(!good)) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -521,38 +554,30 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
|
||||||
good = true;
|
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))
|
if (isempty(controller))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* This is a very minimal lookup from controller names to
|
p = normalize_controller(controller);
|
||||||
* 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. */
|
|
||||||
|
|
||||||
if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
|
/* Check if this controller actually really exists */
|
||||||
p = "systemd";
|
cc = alloca(sizeof("/sys/fs/cgroup/") + strlen(p));
|
||||||
else if (startswith(controller, "name="))
|
strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p);
|
||||||
p = controller + 5;
|
if (access(cc, F_OK) < 0)
|
||||||
else
|
return -errno;
|
||||||
p = controller;
|
|
||||||
|
|
||||||
if (path && suffix)
|
return join_path(p, path, suffix, fs);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
|
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(path);
|
||||||
assert(pid >= 0);
|
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;
|
return r;
|
||||||
|
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
|
|
|
@ -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_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(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_get_by_pid(const char *controller, pid_t pid, char **path);
|
||||||
|
|
||||||
int cg_trim(const char *controller, const char *path, bool delete_root);
|
int cg_trim(const char *controller, const char *path, bool delete_root);
|
||||||
|
|
Loading…
Reference in a new issue