X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Funit.c;h=90ff43da668e2a909237238080cfc33172f641b6;hp=7029b6443e649179424f5080fcb5218f8be6aefc;hb=702a2d8f6a90b999cef0fbf75a226a770f863b00;hpb=b1e2b33c5258f1cefcee55116ac5d049478c804d diff --git a/src/core/unit.c b/src/core/unit.c index 7029b6443..90ff43da6 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -60,7 +60,8 @@ const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = { [UNIT_AUTOMOUNT] = &automount_vtable, [UNIT_SNAPSHOT] = &snapshot_vtable, [UNIT_SWAP] = &swap_vtable, - [UNIT_PATH] = &path_vtable + [UNIT_PATH] = &path_vtable, + [UNIT_SLICE] = &slice_vtable }; Unit *unit_new(Manager *m, size_t size) { @@ -415,6 +416,8 @@ void unit_free(Unit *u) { condition_free_list(u->conditions); + unit_ref_unset(&u->slice); + while (u->refs) unit_ref_unset(u->refs); @@ -853,6 +856,7 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) { } static int unit_add_default_dependencies(Unit *u) { + static const UnitDependency deps[] = { UNIT_REQUIRED_BY, UNIT_REQUIRED_BY_OVERRIDABLE, @@ -868,9 +872,17 @@ static int unit_add_default_dependencies(Unit *u) { assert(u); for (k = 0; k < ELEMENTSOF(deps); k++) - SET_FOREACH(target, u->dependencies[deps[k]], i) - if ((r = unit_add_default_target_dependency(u, target)) < 0) + SET_FOREACH(target, u->dependencies[deps[k]], i) { + r = unit_add_default_target_dependency(u, target); + if (r < 0) return r; + } + + if (u->default_dependencies && UNIT_DEREF(u->slice)) { + r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true); + if (r < 0) + return r; + } return 0; } @@ -949,7 +961,7 @@ bool unit_condition_test(Unit *u) { return u->condition_result; } -static const char* unit_get_status_message_format(Unit *u, JobType t) { +_pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) { const UnitStatusMessageFormats *format_table; assert(u); @@ -966,7 +978,7 @@ static const char* unit_get_status_message_format(Unit *u, JobType t) { return format_table->starting_stopping[t == JOB_STOP]; } -static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) { +_pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) { const char *format; assert(u); @@ -1468,7 +1480,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su if (ns != os && ns == UNIT_FAILED) { log_notice_unit(u->id, - "MESSAGE=Unit %s entered failed state.", u->id); + "Unit %s entered failed state.", u->id); unit_start_on_failure(u); } } @@ -1977,10 +1989,23 @@ static int unit_add_cgroup(Unit *u, CGroupBonding *b) { } char *unit_default_cgroup_path(Unit *u) { + _cleanup_free_ char *escaped_instance = NULL, *slice = NULL; + int r; + assert(u); + if (UNIT_DEREF(u->slice)) { + r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice); + if (r < 0) + return NULL; + } + + escaped_instance = cg_escape(u->id); + if (!escaped_instance) + return NULL; + if (u->instance) { - _cleanup_free_ char *t = NULL, *escaped_template = NULL, *escaped_instance = NULL; + _cleanup_free_ char *t = NULL, *escaped_template = NULL; t = unit_name_template(u->id); if (!t) @@ -1990,20 +2015,13 @@ char *unit_default_cgroup_path(Unit *u) { if (!escaped_template) return NULL; - escaped_instance = cg_escape(u->id); - if (!escaped_instance) - return NULL; - - return strjoin(u->manager->cgroup_hierarchy, "/", escaped_template, "/", escaped_instance, NULL); - } else { - _cleanup_free_ char *escaped = NULL; - - escaped = cg_escape(u->id); - if (!escaped) - return NULL; - - return strjoin(u->manager->cgroup_hierarchy, "/", escaped, NULL); - } + return strjoin(u->manager->cgroup_hierarchy, "/", + slice ? slice : "", slice ? "/" : "", + escaped_template, "/", escaped_instance, NULL); + } else + return strjoin(u->manager->cgroup_hierarchy, "/", + slice ? slice : "", slice ? "/" : "", + escaped_instance, NULL); } int unit_add_cgroup_from_text(Unit *u, const char *name, bool overwrite, CGroupBonding **ret) { @@ -2025,7 +2043,7 @@ int unit_add_cgroup_from_text(Unit *u, const char *name, bool overwrite, CGroupB } if (!controller) { - controller = strdup(SYSTEMD_CGROUP_CONTROLLER); + controller = strdup("systemd"); ours = true; } @@ -2035,6 +2053,16 @@ int unit_add_cgroup_from_text(Unit *u, const char *name, bool overwrite, CGroupB return log_oom(); } + if (streq(controller, "systemd")) { + /* Within the systemd unit hierarchy we do not allow changes. */ + if (path_startswith(path, "/system")) { + log_warning_unit(u->id, "Manipulating the systemd:/system cgroup hierarchy is not permitted."); + free(path); + free(controller); + return -EPERM; + } + } + b = cgroup_bonding_find_list(u->cgroup_bondings, controller); if (b) { if (streq(path, b->path)) { @@ -2138,6 +2166,26 @@ fail: return r; } +int unit_add_default_slice(Unit *u) { + Unit *slice; + int r; + + assert(u); + + if (UNIT_DEREF(u->slice)) + return 0; + + if (u->manager->running_as != SYSTEMD_SYSTEM) + return 0; + + r = manager_load_unit(u->manager, SPECIAL_SYSTEM_SLICE, NULL, NULL, &slice); + if (r < 0) + return r; + + unit_ref_set(&u->slice, slice); + return 0; +} + int unit_add_default_cgroups(Unit *u) { CGroupAttribute *a; char **c; @@ -2671,6 +2719,9 @@ bool unit_inactive_or_pending(Unit *u) { /* Returns true if the unit is inactive or going down */ + if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))) + return true; + if (unit_stop_pending(u)) return true;