X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fcgroup.c;h=5a1c3adacd19af3f8ff2c67ebcb98ea7ab2e53cd;hb=3731acf1acfb4a6eb68374a5b137f3b368f63381;hp=79467a82cea8ea4ac0c3a659017488067dded84f;hpb=4ad490007b70e6ac18d3cb04fa2ed92eba1451fa;p=elogind.git diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 79467a82c..5a1c3adac 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -114,7 +114,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { LIST_FOREACH(device_weights, w, c->blockio_device_weights) fprintf(f, - "%sBlockIOWeight=%s %lu", + "%sBlockIODeviceWeight=%s %lu", prefix, w->path, w->weight); @@ -389,6 +389,10 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { if (!path) return -ENOMEM; + r = hashmap_put(u->manager->cgroup_unit, path, u); + if (r < 0) + return r; + /* First, create our own group */ r = cg_create_with_mask(mask, path); if (r < 0) @@ -410,7 +414,7 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { return 0; } -static void unit_realize_cgroup_now(Unit *u) { +static int unit_realize_cgroup_now(Unit *u) { CGroupControllerMask mask; assert(u); @@ -425,14 +429,14 @@ static void unit_realize_cgroup_now(Unit *u) { if (u->cgroup_realized && u->cgroup_mask == mask) - return; + return 0; /* First, realize parents */ if (UNIT_ISSET(u->slice)) unit_realize_cgroup_now(UNIT_DEREF(u->slice)); /* And then do the real work */ - unit_create_cgroups(u, mask); + return unit_create_cgroups(u, mask); } static void unit_add_to_cgroup_queue(Unit *u) { @@ -451,8 +455,9 @@ unsigned manager_dispatch_cgroup_queue(Manager *m) { while ((i = m->cgroup_queue)) { assert(i->in_cgroup_queue); - unit_realize_cgroup_now(i); - cgroup_context_apply(unit_get_cgroup_context(i), i->cgroup_mask, i->cgroup_path); + if (unit_realize_cgroup_now(i) >= 0) + cgroup_context_apply(unit_get_cgroup_context(i), i->cgroup_mask, i->cgroup_path); + n++; } @@ -484,14 +489,15 @@ static void unit_queue_siblings(Unit *u) { } } -void unit_realize_cgroup(Unit *u) { +int unit_realize_cgroup(Unit *u) { CGroupContext *c; + int r; assert(u); c = unit_get_cgroup_context(u); if (!c) - return; + return 0; /* So, here's the deal: when realizing the cgroups for this * unit, we need to first create all parents, but there's more @@ -508,10 +514,13 @@ void unit_realize_cgroup(Unit *u) { unit_queue_siblings(u); /* And realize this one now */ - unit_realize_cgroup_now(u); + r = unit_realize_cgroup_now(u); /* And apply the values */ - cgroup_context_apply(c, u->cgroup_mask, u->cgroup_path); + if (r >= 0) + cgroup_context_apply(c, u->cgroup_mask, u->cgroup_path); + + return r; } void unit_destroy_cgroup(Unit *u) { @@ -522,14 +531,17 @@ void unit_destroy_cgroup(Unit *u) { if (!u->cgroup_path) return; - r = cg_trim_with_mask(u->cgroup_mask, u->cgroup_path, true); + r = cg_trim_with_mask(u->cgroup_mask, u->cgroup_path, !unit_has_name(u, SPECIAL_ROOT_SLICE)); if (r < 0) - log_error("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r)); + log_debug("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r)); + + hashmap_remove(u->manager->cgroup_unit, u->cgroup_path); free(u->cgroup_path); u->cgroup_path = NULL; u->cgroup_realized = false; u->cgroup_mask = 0; + } pid_t unit_search_main_pid(Unit *u) { @@ -626,8 +638,11 @@ int manager_setup_cgroup(Manager *m) { } /* 4. Realize the system slice and put us in there */ - a = strappenda(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE); - r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, a, 0); + if (m->running_as == SYSTEMD_SYSTEM) { + a = strappenda(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE); + r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, a, 0); + } else + r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, 0); if (r < 0) { log_error("Failed to create root cgroup hierarchy: %s", strerror(-r)); return r; @@ -716,13 +731,16 @@ int manager_notify_cgroup_empty(Manager *m, const char *cgroup) { assert(m); assert(cgroup); - r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, true); - if (r == 0) - return 0; - u = manager_get_unit_by_cgroup(m, cgroup); - if (u && UNIT_VTABLE(u)->notify_cgroup_empty) - UNIT_VTABLE(u)->notify_cgroup_empty(u); + if (u) { + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true); + if (r > 0) { + if (UNIT_VTABLE(u)->notify_cgroup_empty) + UNIT_VTABLE(u)->notify_cgroup_empty(u); + + unit_add_to_gc_queue(u); + } + } return 0; }