X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Funit.c;h=79b9e2bb8a0f8dc9563a6f6e42439e8bdb03a5fb;hp=c12c2a7deb3fa02b7f297e8d91137ce655401287;hb=6124958c7bda3fed9b079e8217781480797703f5;hpb=5e8d1c9a9f15b7453474dc4879bdb4021c3f50a1 diff --git a/src/unit.c b/src/unit.c index c12c2a7de..79b9e2bb8 100644 --- a/src/unit.c +++ b/src/unit.c @@ -365,8 +365,12 @@ void unit_free(Unit *u) { UnitActiveState unit_active_state(Unit *u) { assert(u); - if (u->meta.load_state != UNIT_LOADED) - return UNIT_INACTIVE; + if (u->meta.load_state == UNIT_MERGED) + return unit_active_state(unit_follow_merge(u)); + + /* After a reload it might happen that a unit is not correctly + * loaded but still has a process around. That's why we won't + * shortcut failed loading to UNIT_INACTIVE_MAINTENANCE. */ return UNIT_VTABLE(u)->active_state(u); } @@ -463,7 +467,7 @@ int unit_merge(Unit *u, Unit *other) { if (other->meta.job) return -EEXIST; - if (unit_active_state(other) != UNIT_INACTIVE) + if (!UNIT_IS_INACTIVE_OR_MAINTENANCE(unit_active_state(other))) return -EEXIST; /* Merge names */ @@ -542,7 +546,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { if ((r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_LOGGER_SOCKET, NULL, true)) < 0) return r; - if (u->meta.manager->running_as != MANAGER_SESSION) + if (u->meta.manager->running_as == MANAGER_SYSTEM) if ((r = unit_add_dependency_by_name(u, UNIT_REQUIRES, SPECIAL_LOGGER_SOCKET, NULL, true)) < 0) return r; @@ -746,6 +750,9 @@ int unit_start(Unit *u) { assert(u); + if (u->meta.load_state != UNIT_LOADED) + return -EINVAL; + /* If this is already (being) started, then this will * succeed. Note that this will even succeed if this unit is * not startable by the user. This is relied on to detect when @@ -785,7 +792,7 @@ int unit_stop(Unit *u) { assert(u); state = unit_active_state(u); - if (state == UNIT_INACTIVE) + if (UNIT_IS_INACTIVE_OR_MAINTENANCE(state)) return -EALREADY; if (!UNIT_VTABLE(u)->stop) @@ -805,6 +812,9 @@ int unit_reload(Unit *u) { assert(u); + if (u->meta.load_state != UNIT_LOADED) + return -EINVAL; + if (!unit_can_reload(u)) return -EBADR; @@ -926,7 +936,7 @@ static void retroactively_stop_dependencies(Unit *u) { void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { bool unexpected = false; - timestamp ts; + dual_timestamp ts; assert(u); assert(os < _UNIT_ACTIVE_STATE_MAX); @@ -939,11 +949,11 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { * this function will be called too and the utmp code below * relies on that! */ - timestamp_get(&ts); + dual_timestamp_get(&ts); - if (os == UNIT_INACTIVE && ns != UNIT_INACTIVE) + if (UNIT_IS_INACTIVE_OR_MAINTENANCE(os) && !UNIT_IS_INACTIVE_OR_MAINTENANCE(ns)) u->meta.inactive_exit_timestamp = ts; - else if (os != UNIT_INACTIVE && ns == UNIT_INACTIVE) + else if (!UNIT_IS_INACTIVE_OR_MAINTENANCE(os) && UNIT_IS_INACTIVE_OR_MAINTENANCE(ns)) u->meta.inactive_enter_timestamp = ts; if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns)) @@ -1002,6 +1012,8 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { if (ns == UNIT_INACTIVE) job_finish_and_invalidate(u->meta.job, true); + else if (ns == UNIT_INACTIVE_MAINTENANCE) + job_finish_and_invalidate(u->meta.job, false); else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) { unexpected = true; job_finish_and_invalidate(u->meta.job, false); @@ -1952,7 +1964,9 @@ DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState); static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = { [UNIT_ACTIVE] = "active", + [UNIT_ACTIVE_RELOADING] = "active-reloading", [UNIT_INACTIVE] = "inactive", + [UNIT_INACTIVE_MAINTENANCE] = "inactive-maintenance", [UNIT_ACTIVATING] = "activating", [UNIT_DEACTIVATING] = "deactivating" };