Commit d686d8a9 authored by Lennart Poettering's avatar Lennart Poettering
Browse files

cgroup: by default, duplicate service cgroup in the cpu hierarchy

parent 74fe1fe3
......@@ -46,7 +46,7 @@ int cgroup_bonding_realize(CGroupBonding *b) {
b->realized = true;
if (b->only_us && b->clean_up)
if (b->ours)
cg_trim(b->controller, b->path, false);
return 0;
......@@ -57,7 +57,7 @@ int cgroup_bonding_realize_list(CGroupBonding *first) {
int r;
LIST_FOREACH(by_unit, b, first)
if ((r = cgroup_bonding_realize(b)) < 0)
if ((r = cgroup_bonding_realize(b)) < 0 && b->essential)
return r;
return 0;
......@@ -71,16 +71,18 @@ void cgroup_bonding_free(CGroupBonding *b) {
LIST_REMOVE(CGroupBonding, by_unit, b->unit->meta.cgroup_bondings, b);
assert_se(f = hashmap_get(b->unit->meta.manager->cgroup_bondings, b->path));
LIST_REMOVE(CGroupBonding, by_path, f, b);
if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) {
assert_se(f = hashmap_get(b->unit->meta.manager->cgroup_bondings, b->path));
LIST_REMOVE(CGroupBonding, by_path, f, b);
if (f)
hashmap_replace(b->unit->meta.manager->cgroup_bondings, b->path, f);
else
hashmap_remove(b->unit->meta.manager->cgroup_bondings, b->path);
if (f)
hashmap_replace(b->unit->meta.manager->cgroup_bondings, b->path, f);
else
hashmap_remove(b->unit->meta.manager->cgroup_bondings, b->path);
}
}
if (b->realized && b->only_us && b->clean_up) {
if (b->realized && b->ours) {
if (cgroup_bonding_is_empty(b) > 0)
cg_delete(b->controller, b->path);
......@@ -103,7 +105,7 @@ void cgroup_bonding_free_list(CGroupBonding *first) {
void cgroup_bonding_trim(CGroupBonding *b, bool delete_root) {
assert(b);
if (b->realized && b->only_us && b->clean_up)
if (b->realized && b->ours)
cg_trim(b->controller, b->path, delete_root);
}
......@@ -132,22 +134,19 @@ int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid) {
int r;
LIST_FOREACH(by_unit, b, first)
if ((r = cgroup_bonding_install(b, pid)) < 0)
if ((r = cgroup_bonding_install(b, pid)) < 0 && b->essential)
return r;
return 0;
}
int cgroup_bonding_kill(CGroupBonding *b, int sig, Set *s) {
int r;
assert(b);
assert(sig >= 0);
if ((r = cgroup_bonding_realize(b)) < 0)
return r;
assert(b->realized);
/* Don't kill cgroups that aren't ours */
if (!b->realized || !b->ours)
return 0;
return cg_kill_recursive(b->controller, b->path, sig, true, false, s);
}
......@@ -196,7 +195,7 @@ int cgroup_bonding_is_empty(CGroupBonding *b) {
return 1;
/* It's not only us using this cgroup, so we just don't know */
return b->only_us ? 0 : -EAGAIN;
return b->ours ? 0 : -EAGAIN;
}
int cgroup_bonding_is_empty_list(CGroupBonding *first) {
......@@ -372,7 +371,7 @@ Unit* cgroup_unit_by_pid(Manager *m, pid_t pid) {
if (!b->unit)
continue;
if (b->only_us)
if (b->ours)
return b->unit;
}
......@@ -409,7 +408,7 @@ pid_t cgroup_bonding_search_main_pid(CGroupBonding *b) {
assert(b);
if (!b->only_us)
if (!b->ours)
return 0;
if ((r = cg_enumerate_processes(b->controller, b->path, &f)) < 0)
......
......@@ -39,11 +39,12 @@ struct CGroupBonding {
/* For the Manager::cgroup_bondings hashmap */
LIST_FIELDS(CGroupBonding, by_path);
/* When shutting down, remove cgroup? */
bool clean_up:1;
/* When shutting down, remove cgroup? Are our own tasks the
* only ones in this group?*/
bool ours:1;
/* When our tasks are the only ones in this group */
bool only_us:1;
/* If we cannot create this group, or add a process to it, is this fatal? */
bool essential:1;
/* This cgroup is realized */
bool realized:1;
......
......@@ -488,7 +488,7 @@ static int mount_load(Unit *u) {
if ((r = mount_add_target_links(m)) < 0)
return r;
if ((r = unit_add_default_cgroup(u)) < 0)
if ((r = unit_add_default_cgroups(u)) < 0)
return r;
if (m->meta.default_dependencies)
......
......@@ -1055,7 +1055,7 @@ static int service_load(Unit *u) {
if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
return r;
if ((r = unit_add_default_cgroup(u)) < 0)
if ((r = unit_add_default_cgroups(u)) < 0)
return r;
#ifdef HAVE_SYSV_COMPAT
......
......@@ -344,7 +344,7 @@ static int socket_load(Unit *u) {
if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
return r;
if ((r = unit_add_default_cgroup(u)) < 0)
if ((r = unit_add_default_cgroups(u)) < 0)
return r;
if (s->meta.default_dependencies)
......
......@@ -289,7 +289,7 @@ static int swap_load(Unit *u) {
if ((r = swap_add_target_links(s)) < 0)
return r;
if ((r = unit_add_default_cgroup(u)) < 0)
if ((r = unit_add_default_cgroups(u)) < 0)
return r;
if (s->meta.default_dependencies)
......
......@@ -1682,7 +1682,6 @@ char *unit_dbus_path(Unit *u) {
}
int unit_add_cgroup(Unit *u, CGroupBonding *b) {
CGroupBonding *l;
int r;
assert(u);
......@@ -1697,12 +1696,16 @@ int unit_add_cgroup(Unit *u, CGroupBonding *b) {
/* Ensure this hasn't been added yet */
assert(!b->unit);
l = hashmap_get(u->meta.manager->cgroup_bondings, b->path);
LIST_PREPEND(CGroupBonding, by_path, l, b);
if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) {
CGroupBonding *l;
if ((r = hashmap_replace(u->meta.manager->cgroup_bondings, b->path, l)) < 0) {
LIST_REMOVE(CGroupBonding, by_path, l, b);
return r;
l = hashmap_get(u->meta.manager->cgroup_bondings, b->path);
LIST_PREPEND(CGroupBonding, by_path, l, b);
if ((r = hashmap_replace(u->meta.manager->cgroup_bondings, b->path, l)) < 0) {
LIST_REMOVE(CGroupBonding, by_path, l, b);
return r;
}
}
LIST_PREPEND(CGroupBonding, by_unit, u->meta.cgroup_bondings, b);
......@@ -1767,8 +1770,7 @@ int unit_add_cgroup_from_text(Unit *u, const char *name) {
b->controller = controller;
b->path = path;
b->only_us = false;
b->clean_up = false;
b->ours = false;
if ((r = unit_add_cgroup(u, b)) < 0)
goto fail;
......@@ -1783,35 +1785,51 @@ fail:
return r;
}
int unit_add_default_cgroup(Unit *u) {
CGroupBonding *b;
int unit_add_default_cgroups(Unit *u) {
CGroupBonding *b = NULL;
int r = -ENOMEM;
const char * const default_controllers[] = {
SYSTEMD_CGROUP_CONTROLLER,
"cpu",
NULL
};
const char * const*c;
assert(u);
/* Adds in the default cgroup data, if it wasn't specified yet */
/* Adds in the default cgroups, if it wasn't specified yet */
if (unit_get_default_cgroup(u))
return 0;
STRV_FOREACH(c, default_controllers) {
if (!(b = new0(CGroupBonding, 1)))
return -ENOMEM;
if (cgroup_bonding_find_list(u->meta.cgroup_bondings, *c))
continue;
if (!(b->path = default_cgroup_path(u)))
goto fail;
if (!(b = new0(CGroupBonding, 1)))
return -ENOMEM;
b->clean_up = true;
b->only_us = true;
if (!(b->path = default_cgroup_path(u)))
goto fail;
if ((r = unit_add_cgroup(u, b)) < 0)
goto fail;
if (!(b->controller = strdup(*c)))
goto fail;
b->ours = true;
b->essential = c == default_controllers; /* the first one is essential */
if ((r = unit_add_cgroup(u, b)) < 0)
goto fail;
b = NULL;
}
return 0;
fail:
free(b->path);
free(b->controller);
free(b);
if (b) {
free(b->path);
free(b->controller);
free(b);
}
return r;
}
......
......@@ -414,7 +414,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c);
int unit_add_cgroup(Unit *u, CGroupBonding *b);
int unit_add_cgroup_from_text(Unit *u, const char *name);
int unit_add_default_cgroup(Unit *u);
int unit_add_default_cgroups(Unit *u);
CGroupBonding* unit_get_default_cgroup(Unit *u);
int unit_choose_id(Unit *u, const char *name);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment