X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=unit.c;h=036c01648c6e017ee4d832e67d74a20e1c359fe9;hb=24e61ac49db6add10ffa448f42202245fb883b96;hp=39c9e5e7e83d86156ca6440a67bbf8ddae706c97;hpb=2e478a46c3754ede1a7af57b961056a2a375a799;p=elogind.git diff --git a/unit.c b/unit.c index 39c9e5e7e..036c01648 100644 --- a/unit.c +++ b/unit.c @@ -260,6 +260,8 @@ void unit_free(Unit *u) { /* Detach from next 'bigger' objects */ + cgroup_bonding_free_list(u->meta.cgroup_bondings); + SET_FOREACH(t, u->meta.names, i) hashmap_remove_value(u->meta.manager->units, t, u); @@ -369,12 +371,12 @@ const char *unit_description(Unit *u) { } void unit_dump(Unit *u, FILE *f, const char *prefix) { - char *t; UnitDependency d; Iterator i; char *p2; const char *prefix2; + CGroupBonding *b; assert(u); @@ -413,6 +415,10 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), unit_id(other)); } + LIST_FOREACH(by_unit, b, u->meta.cgroup_bondings) + fprintf(f, "%s\tControlGroup: %s:%s\n", + prefix, b->controller, b->path); + if (UNIT_VTABLE(u)->dump) UNIT_VTABLE(u)->dump(u, f, prefix2); @@ -972,6 +978,19 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name) { return 0; } +int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name) { + Unit *other; + int r; + + if ((r = manager_load_unit(u->meta.manager, name, &other)) < 0) + return r; + + if ((r = unit_add_dependency(other, d, u)) < 0) + return r; + + return 0; +} + int set_unit_path(const char *p) { char *cwd, *c; int r; @@ -1060,6 +1079,138 @@ char *unit_dbus_path(Unit *u) { return p; } +int unit_add_cgroup(Unit *u, CGroupBonding *b) { + CGroupBonding *l; + int r; + + assert(u); + assert(b); + assert(b->path); + + /* 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 ((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); + b->unit = u; + + return 0; +} + +int unit_add_cgroup_from_text(Unit *u, const char *name) { + size_t n; + const char *p; + char *controller; + CGroupBonding *b; + int r; + + assert(u); + assert(name); + + /* Detect controller name */ + n = strcspn(name, ":/"); + + /* Only controller name, no path? No path? */ + if (name[n] == 0) + return -EINVAL; + + if (n > 0) { + if (name[n] != ':') + return -EINVAL; + + p = name+n+1; + } else + p = name; + + /* Insist in absolute paths */ + if (p[0] != '/') + return -EINVAL; + + if (!(controller = strndup(name, n))) + return -ENOMEM; + + if (cgroup_bonding_find_list(u->meta.cgroup_bondings, controller)) { + free(controller); + return -EEXIST; + } + + if (!(b = new0(CGroupBonding, 1))) { + free(controller); + return -ENOMEM; + } + + b->controller = controller; + + if (!(b->path = strdup(p))) { + r = -ENOMEM; + goto fail; + } + + b->only_us = false; + b->clean_up = false; + + if ((r = unit_add_cgroup(u, b)) < 0) + goto fail; + + return 0; + +fail: + free(b->path); + free(b->controller); + free(b); + + return r; +} + +int unit_add_default_cgroup(Unit *u) { + CGroupBonding *b; + int r = -ENOMEM; + + assert(u); + + /* Adds in the default cgroup data, if it wasn't specified yet */ + + if (unit_get_default_cgroup(u)) + return 0; + + if (!(b = new0(CGroupBonding, 1))) + return -ENOMEM; + + if (!(b->controller = strdup(u->meta.manager->cgroup_controller))) + goto fail; + + if (asprintf(&b->path, "%s/%s", u->meta.manager->cgroup_hierarchy, unit_id(u)) < 0) + goto fail; + + b->clean_up = true; + b->only_us = true; + + if ((r = unit_add_cgroup(u, b)) < 0) + goto fail; + + return 0; + +fail: + free(b->path); + free(b->controller); + free(b); + + return r; +} + +CGroupBonding* unit_get_default_cgroup(Unit *u) { + assert(u); + + return cgroup_bonding_find_list(u->meta.cgroup_bondings, u->meta.manager->cgroup_controller); +} + static const char* const unit_type_table[_UNIT_TYPE_MAX] = { [UNIT_SERVICE] = "service", [UNIT_TIMER] = "timer",