summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cgroup.c39
-rw-r--r--src/cgroup.h9
-rw-r--r--src/mount.c2
-rw-r--r--src/service.c2
-rw-r--r--src/socket.c2
-rw-r--r--src/swap.c2
-rw-r--r--src/unit.c66
-rw-r--r--src/unit.h2
8 files changed, 71 insertions, 53 deletions
diff --git a/src/cgroup.c b/src/cgroup.c
index 57c9c9e99e..64082d0dc6 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 d6d5c86f10..89854ff34e 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 4094eef43d..077ab9160f 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 0234151700..429b53d4f8 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 9662066c13..cb38ab3d69 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 6de79280c9..ec9f157b15 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 edc636412d..bfb1dd644e 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 fbe88c2c79..9eda138fb7 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);