From: Lennart Poettering Date: Wed, 17 Nov 2010 20:27:53 +0000 (+0100) Subject: cgroup: by default, duplicate service cgroup in the cpu hierarchy X-Git-Tag: v13~18 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=d686d8a97bd7945af0a61504392d01a3167b576f;hp=74fe1fe36e35a26d764f1e3119d5f6d014db573c cgroup: by default, duplicate service cgroup in the cpu hierarchy --- diff --git a/src/cgroup.c b/src/cgroup.c index 57c9c9e99..64082d0dc 100644 --- a/src/cgroup.c +++ b/src/cgroup.c @@ -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) diff --git a/src/cgroup.h b/src/cgroup.h index d6d5c86f1..89854ff34 100644 --- a/src/cgroup.h +++ b/src/cgroup.h @@ -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; diff --git a/src/mount.c b/src/mount.c index 4094eef43..077ab9160 100644 --- a/src/mount.c +++ b/src/mount.c @@ -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) diff --git a/src/service.c b/src/service.c index 023415170..429b53d4f 100644 --- a/src/service.c +++ b/src/service.c @@ -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 diff --git a/src/socket.c b/src/socket.c index 9662066c1..cb38ab3d6 100644 --- a/src/socket.c +++ b/src/socket.c @@ -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) diff --git a/src/swap.c b/src/swap.c index 6de79280c..ec9f157b1 100644 --- a/src/swap.c +++ b/src/swap.c @@ -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) diff --git a/src/unit.c b/src/unit.c index edc636412..bfb1dd644 100644 --- a/src/unit.c +++ b/src/unit.c @@ -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; } diff --git a/src/unit.h b/src/unit.h index fbe88c2c7..9eda138fb 100644 --- a/src/unit.h +++ b/src/unit.h @@ -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);