X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Funit.c;h=1fbfb1dea5fb7df643f04ed5d46b1abe1c171c77;hp=ad4063b07b6bd86d8281902ce71e26928db5d4d0;hb=755a02c6800246e7e293897d0594fe7e7531ba59;hpb=5831e9b726ab6e76b28a94861a014d3bc2aa3015 diff --git a/src/unit.c b/src/unit.c index ad4063b07..1fbfb1dea 100644 --- a/src/unit.c +++ b/src/unit.c @@ -377,12 +377,15 @@ void unit_free(Unit *u) { free(u->meta.description); free(u->meta.fragment_path); + free(u->meta.instance); set_free_free(u->meta.names); condition_free_list(u->meta.conditions); - free(u->meta.instance); + while (u->meta.refs) + unit_ref_unset(u->meta.refs); + free(u); } @@ -498,6 +501,10 @@ int unit_merge(Unit *u, Unit *other) { /* Merge names */ merge_names(u, other); + /* Redirect all references */ + while (other->meta.refs) + unit_ref_set(other->meta.refs, u); + /* Merge dependencies */ for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) merge_dependencies(u, other, d); @@ -561,11 +568,15 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { if (c->std_output != EXEC_OUTPUT_KMSG && c->std_output != EXEC_OUTPUT_SYSLOG && + c->std_output != EXEC_OUTPUT_JOURNAL && c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE && c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE && + c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE && c->std_error != EXEC_OUTPUT_KMSG && - c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE && - c->std_error != EXEC_OUTPUT_KMSG && + c->std_error != EXEC_OUTPUT_SYSLOG && + c->std_error != EXEC_OUTPUT_JOURNAL && + c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE && + c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE && c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE) return 0; @@ -573,7 +584,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { * logging daemon is run first. */ if (u->meta.manager->running_as == MANAGER_SYSTEM) - if ((r = unit_add_two_dependencies_by_name(u, UNIT_REQUIRES, UNIT_AFTER, SPECIAL_STDOUT_SYSLOG_BRIDGE_SOCKET, NULL, true)) < 0) + if ((r = unit_add_two_dependencies_by_name(u, UNIT_REQUIRES, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true)) < 0) return r; return 0; @@ -858,6 +869,7 @@ fail: u->meta.load_state = UNIT_ERROR; u->meta.load_error = r; unit_add_to_dbus_queue(u); + unit_add_to_gc_queue(u); log_debug("Failed to load configuration for %s: %s", u->meta.id, strerror(-r)); @@ -1031,19 +1043,19 @@ static void unit_check_unneeded(Unit *u) { return; SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i) - if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + if (unit_pending_active(other)) return; SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i) - if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + if (unit_pending_active(other)) return; SET_FOREACH(other, u->meta.dependencies[UNIT_WANTED_BY], i) - if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + if (unit_pending_active(other)) return; SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i) - if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + if (unit_pending_active(other)) return; log_info("Service %s is not needed anymore. Stopping.", u->meta.id); @@ -1104,6 +1116,14 @@ static void retroactively_stop_dependencies(Unit *u) { 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); +} + +static void check_unneeded_dependencies(Unit *u) { + Iterator i; + Unit *other; + + assert(u); + assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))); /* Garbage collect services that might not be needed anymore, if enabled */ SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i) @@ -1262,6 +1282,10 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su retroactively_stop_dependencies(u); } + /* stop unneeded units regardless if going down was expected or not */ + if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) + check_unneeded_dependencies(u); + if (ns != os && ns == UNIT_FAILED) { log_notice("Unit %s entered failed state.", u->meta.id); unit_trigger_on_failure(u); @@ -1314,7 +1338,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su } } - manager_recheck_syslog(u->meta.manager); + manager_recheck_journal(u->meta.manager); /* Maybe we finished startup and are now ready for being * stopped because unneeded? */ @@ -1513,7 +1537,11 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen [UNIT_AFTER] = UNIT_BEFORE, [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID, [UNIT_REFERENCES] = UNIT_REFERENCED_BY, - [UNIT_REFERENCED_BY] = UNIT_REFERENCES + [UNIT_REFERENCED_BY] = UNIT_REFERENCES, + [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY, + [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS, + [UNIT_PROPAGATE_RELOAD_TO] = UNIT_PROPAGATE_RELOAD_FROM, + [UNIT_PROPAGATE_RELOAD_FROM] = UNIT_PROPAGATE_RELOAD_TO }; int r, q = 0, v = 0, w = 0; @@ -2428,9 +2456,6 @@ int unit_coldplug(Unit *u) { void unit_status_printf(Unit *u, const char *status, const char *format, ...) { va_list ap; - char *s, *e; - int err; - const unsigned emax = status ? 80 - (sizeof("[ OK ]")-1) : 80; assert(u); assert(format); @@ -2445,21 +2470,8 @@ void unit_status_printf(Unit *u, const char *status, const char *format, ...) { return; va_start(ap, format); - err = vasprintf(&s, format, ap); + status_vprintf(status, true, format, ap); va_end(ap); - if (err < 0) - return; - - e = ellipsize(s, emax, 100); - free(s); - if (!e) - return; - - if (status) - status_printf("%s%*s[%s]\n", e, emax - strlen(e), "", status); - else - status_printf("%s\n", e); - free(e); } bool unit_need_daemon_reload(Unit *u) { @@ -2517,7 +2529,7 @@ bool unit_pending_inactive(Unit *u) { bool unit_pending_active(Unit *u) { assert(u); - /* Returns true if the unit is inactive or going down */ + /* Returns true if the unit is active or going up */ if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) return true; @@ -2591,6 +2603,28 @@ UnitFileState unit_get_unit_file_state(Unit *u) { return u->meta.unit_file_state; } +Unit* unit_ref_set(UnitRef *ref, Unit *u) { + assert(ref); + assert(u); + + if (ref->unit) + unit_ref_unset(ref); + + ref->unit = u; + LIST_PREPEND(UnitRef, refs, u->meta.refs, ref); + return u; +} + +void unit_ref_unset(UnitRef *ref) { + assert(ref); + + if (!ref->unit) + return; + + LIST_REMOVE(UnitRef, refs, ref->unit->meta.refs, ref); + ref->unit = NULL; +} + static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = { [UNIT_STUB] = "stub", [UNIT_LOADED] = "loaded", @@ -2629,7 +2663,11 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { [UNIT_AFTER] = "After", [UNIT_REFERENCES] = "References", [UNIT_REFERENCED_BY] = "ReferencedBy", - [UNIT_ON_FAILURE] = "OnFailure" + [UNIT_ON_FAILURE] = "OnFailure", + [UNIT_TRIGGERS] = "Triggers", + [UNIT_TRIGGERED_BY] = "TriggeredBy", + [UNIT_PROPAGATE_RELOAD_TO] = "PropagateReloadTo", + [UNIT_PROPAGATE_RELOAD_FROM] = "PropagateReloadFrom" }; DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);