X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Funit.c;h=fb5583bfb2d589b3fbb451f3be777c08127d6bab;hp=d2f60801a9a2a1ad8c5916216c0a143fdc20e03e;hb=b81884e7466b8e8bc1261b1b1a722d11694b8c54;hpb=8a0867d6c5b47c8697d1ddd815116a548433c718 diff --git a/src/unit.c b/src/unit.c index d2f60801a..fb5583bfb 100644 --- a/src/unit.c +++ b/src/unit.c @@ -652,13 +652,11 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { if (u->meta.load_state == UNIT_LOADED) { fprintf(f, - "%s\tRecursive Stop: %s\n" "%s\tStopWhenUnneeded: %s\n" "%s\tRefuseManualStart: %s\n" "%s\tRefuseManualStop: %s\n" "%s\tDefaultDependencies: %s\n" "%s\tIgnoreDependencyFailure: %s\n", - prefix, yes_no(u->meta.recursive_stop), prefix, yes_no(u->meta.stop_when_unneeded), prefix, yes_no(u->meta.refuse_manual_start), prefix, yes_no(u->meta.refuse_manual_stop), @@ -768,6 +766,10 @@ static int unit_add_default_dependencies(Unit *u) { if ((r = unit_add_default_target_dependency(u, target)) < 0) return r; + SET_FOREACH(target, u->meta.dependencies[UNIT_BOUND_BY], i) + if ((r = unit_add_default_target_dependency(u, target)) < 0) + return r; + return 0; } @@ -966,6 +968,10 @@ static void unit_check_unneeded(Unit *u) { if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) return; + SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + return; + log_info("Service %s is not needed anymore. Stopping.", u->meta.id); /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ @@ -980,27 +986,36 @@ static void retroactively_start_dependencies(Unit *u) { assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))); SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i) - if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + if (!set_get(u->meta.dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL); + + SET_FOREACH(other, u->meta.dependencies[UNIT_BIND_TO], i) + if (!set_get(u->meta.dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL); SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i) - if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + if (!set_get(u->meta.dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL, NULL); SET_FOREACH(other, u->meta.dependencies[UNIT_REQUISITE], i) - if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + if (!set_get(u->meta.dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL); SET_FOREACH(other, u->meta.dependencies[UNIT_WANTS], i) - if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + if (!set_get(u->meta.dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL, NULL); SET_FOREACH(other, u->meta.dependencies[UNIT_CONFLICTS], i) - if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); SET_FOREACH(other, u->meta.dependencies[UNIT_CONFLICTED_BY], i) - if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); } @@ -1011,12 +1026,10 @@ static void retroactively_stop_dependencies(Unit *u) { assert(u); assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))); - if (u->meta.recursive_stop) { - /* Pull down units need us recursively if enabled */ - SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i) - if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) - manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); - } + /* Pull down units which are bound to us recursively if enabled */ + SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); /* Garbage collect services that might not be needed anymore, if enabled */ SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i) @@ -1034,6 +1047,9 @@ static void retroactively_stop_dependencies(Unit *u) { SET_FOREACH(other, u->meta.dependencies[UNIT_REQUISITE_OVERRIDABLE], i) if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) unit_check_unneeded(other); + SET_FOREACH(other, u->meta.dependencies[UNIT_BIND_TO], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); } void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { @@ -1398,9 +1414,11 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen [UNIT_WANTS] = UNIT_WANTED_BY, [UNIT_REQUISITE] = UNIT_REQUIRED_BY, [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE, + [UNIT_BIND_TO] = UNIT_BOUND_BY, [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID, [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID, [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID, + [UNIT_BOUND_BY] = UNIT_BIND_TO, [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY, [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS, [UNIT_BEFORE] = UNIT_AFTER, @@ -1427,7 +1445,8 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen (d == UNIT_REQUIRES || d == UNIT_REQUIRES_OVERRIDABLE || d == UNIT_REQUISITE || - d == UNIT_REQUISITE_OVERRIDABLE)) { + d == UNIT_REQUISITE_OVERRIDABLE || + d == UNIT_BIND_TO)) { return -EINVAL; } @@ -2006,6 +2025,11 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds) { if (u->meta.job) unit_serialize_item(u, f, "job", job_type_to_string(u->meta.job->type)); + dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->meta.inactive_exit_timestamp); + dual_timestamp_serialize(f, "active-enter-timestamp", &u->meta.active_enter_timestamp); + dual_timestamp_serialize(f, "active-exit-timestamp", &u->meta.active_exit_timestamp); + dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->meta.inactive_enter_timestamp); + /* End marker */ fputc('\n', f); return 0; @@ -2082,6 +2106,18 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { u->meta.deserialized_job = type; continue; + } else if (streq(l, "inactive-exit-timestamp")) { + dual_timestamp_deserialize(v, &u->meta.inactive_exit_timestamp); + continue; + } else if (streq(l, "active-enter-timestamp")) { + dual_timestamp_deserialize(v, &u->meta.active_enter_timestamp); + continue; + } else if (streq(l, "active-exit-timestamp")) { + dual_timestamp_deserialize(v, &u->meta.active_exit_timestamp); + continue; + } else if (streq(l, "inactive-enter-timestamp")) { + dual_timestamp_deserialize(v, &u->meta.inactive_enter_timestamp); + continue; } if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0) @@ -2113,7 +2149,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) { if (r < 0) return r; - if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, device, true)) < 0) + if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BIND_TO, device, true)) < 0) return r; if (wants) @@ -2297,9 +2333,11 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable", [UNIT_REQUIRED_BY] = "RequiredBy", [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable", + [UNIT_BIND_TO] = "BindTo", [UNIT_WANTED_BY] = "WantedBy", [UNIT_CONFLICTS] = "Conflicts", [UNIT_CONFLICTED_BY] = "ConflictedBy", + [UNIT_BOUND_BY] = "BoundBy", [UNIT_BEFORE] = "Before", [UNIT_AFTER] = "After", [UNIT_REFERENCES] = "References",