X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Funit.c;h=66372f2a92a8e4b98f5302aa1ec5bb2a6f371882;hp=8f5ae8af3f8610ce10abdea7c8a85c853baaf141;hb=3b6fdb5b5afebc49a7e987e3e3bf7aa2615d1671;hpb=a40eb73224e237f758d38847ae216c019425ebac diff --git a/src/unit.c b/src/unit.c index 8f5ae8af3..66372f2a9 100644 --- a/src/unit.c +++ b/src/unit.c @@ -39,6 +39,7 @@ #include "specifier.h" #include "dbus-unit.h" #include "special.h" +#include "cgroup-util.h" const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = { [UNIT_SERVICE] = &service_vtable, @@ -282,7 +283,8 @@ void unit_add_to_dbus_queue(Unit *u) { if (u->meta.load_state == UNIT_STUB || u->meta.in_dbus_queue) return; - if (set_isempty(u->meta.manager->subscribed)) { + /* Shortcut things if nobody cares */ + if (!bus_has_subscriber(u->meta.manager)) { u->meta.sent_dbus_new_signal = true; return; } @@ -624,11 +626,13 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { "%s\tRecursive Stop: %s\n" "%s\tStopWhenUnneeded: %s\n" "%s\tOnlyByDependency: %s\n" - "%s\tDefaultDependencies: %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.only_by_dependency), - prefix, yes_no(u->meta.default_dependencies)); + prefix, yes_no(u->meta.default_dependencies), + prefix, yes_no(u->meta.ignore_dependency_failure)); LIST_FOREACH(by_unit, b, u->meta.cgroup_bondings) fprintf(f, "%s\tControlGroup: %s:%s\n", @@ -737,7 +741,7 @@ fail: u->meta.load_state = UNIT_FAILED; unit_add_to_dbus_queue(u); - log_debug("Failed to load configuration for %s: %s", u->meta.id, strerror(-r)); + log_notice("Failed to load configuration for %s: %s", u->meta.id, strerror(-r)); return r; } @@ -775,6 +779,9 @@ int unit_start(Unit *u) { * before it will start again. */ unit_add_to_dbus_queue(u); + + unit_status_printf(u, "Starting %s...\n", unit_description(u)); + return UNIT_VTABLE(u)->start(u); } @@ -802,6 +809,9 @@ int unit_stop(Unit *u) { return -EBADR; unit_add_to_dbus_queue(u); + + unit_status_printf(u, "Stopping %s...\n", unit_description(u)); + return UNIT_VTABLE(u)->stop(u); } @@ -871,10 +881,10 @@ static void unit_check_uneeded(Unit *u) { if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) return; - log_debug("Service %s is not needed anymore. Stopping.", u->meta.id); + log_info("Service %s is not needed anymore. Stopping.", u->meta.id); /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ - manager_add_job(u->meta.manager, JOB_STOP, u, JOB_FAIL, true, NULL); + manager_add_job(u->meta.manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL); } static void retroactively_start_dependencies(Unit *u) { @@ -886,23 +896,23 @@ static void retroactively_start_dependencies(Unit *u) { SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i) if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) - manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL); + 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))) - manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL); + 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))) - manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL); + 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))) - manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL); + 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))) - manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL); + manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); } static void retroactively_stop_dependencies(Unit *u) { @@ -916,7 +926,7 @@ static void retroactively_stop_dependencies(Unit *u) { /* 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); + 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 */ @@ -938,7 +948,6 @@ static void retroactively_stop_dependencies(Unit *u) { } void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { - bool unexpected = false; dual_timestamp ts; assert(u); @@ -964,10 +973,17 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns)) u->meta.active_exit_timestamp = ts; + if (ns != os && ns == UNIT_MAINTENANCE) + log_notice("Unit %s entered maintenance state.", u->meta.id); + + if (UNIT_IS_INACTIVE_OR_MAINTENANCE(ns)) + cgroup_bonding_trim_list(u->meta.cgroup_bondings, true); + timer_unit_notify(u, ns); path_unit_notify(u, ns); if (u->meta.job) { + bool unexpected = false; if (u->meta.job->state == JOB_WAITING) @@ -1013,10 +1029,8 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { case JOB_RESTART: case JOB_TRY_RESTART: - if (ns == UNIT_INACTIVE) + if (ns == UNIT_INACTIVE || ns == UNIT_MAINTENANCE) job_finish_and_invalidate(u->meta.job, true); - else if (ns == UNIT_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); @@ -1027,16 +1041,17 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { default: assert_not_reached("Job type unknown"); } - } - /* If this state change happened without being requested by a - * job, then let's retroactively start or stop dependencies */ + /* If this state change happened without being + * requested by a job, then let's retroactively start + * or stop dependencies */ - if (unexpected) { - if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns)) - retroactively_start_dependencies(u); - else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) - retroactively_stop_dependencies(u); + if (unexpected) { + if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns)) + retroactively_start_dependencies(u); + else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) + retroactively_stop_dependencies(u); + } } /* Some names are special */ @@ -1132,14 +1147,14 @@ int unit_watch_pid(Unit *u, pid_t pid) { /* Watch a specific PID. We only support one unit watching * each PID for now. */ - return hashmap_put(u->meta.manager->watch_pids, UINT32_TO_PTR(pid), u); + return hashmap_put(u->meta.manager->watch_pids, LONG_TO_PTR(pid), u); } void unit_unwatch_pid(Unit *u, pid_t pid) { assert(u); assert(pid >= 1); - hashmap_remove_value(u->meta.manager->watch_pids, UINT32_TO_PTR(pid), u); + hashmap_remove_value(u->meta.manager->watch_pids, LONG_TO_PTR(pid), u); } int unit_watch_timer(Unit *u, usec_t delay, Watch *w) { @@ -1385,7 +1400,7 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, con if (!(name = resolve_template(u, name, path, &s))) return -ENOMEM; - if ((r = manager_load_unit(u->meta.manager, name, path, &other)) < 0) + if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0) goto finish; r = unit_add_dependency(u, d, other, add_reference); @@ -1406,7 +1421,7 @@ int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency if (!(name = resolve_template(u, name, path, &s))) return -ENOMEM; - if ((r = manager_load_unit(u->meta.manager, name, path, &other)) < 0) + if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0) goto finish; r = unit_add_two_dependencies(u, d, e, other, add_reference); @@ -1427,7 +1442,7 @@ int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *n if (!(name = resolve_template(u, name, path, &s))) return -ENOMEM; - if ((r = manager_load_unit(u->meta.manager, name, path, &other)) < 0) + if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0) goto finish; r = unit_add_dependency(other, d, u, add_reference); @@ -1448,7 +1463,7 @@ int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDep if (!(name = resolve_template(u, name, path, &s))) return -ENOMEM; - if ((r = manager_load_unit(u->meta.manager, name, path, &other)) < 0) + if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0) goto finish; if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0) @@ -1586,7 +1601,7 @@ int unit_add_cgroup_from_text(Unit *u, const char *name) { if (n > 0) controller = strndup(name, n); else - controller = strdup(u->meta.manager->cgroup_controller); + controller = strdup(SYSTEMD_CGROUP_CONTROLLER); if (!controller) { r = -ENOMEM; @@ -1635,7 +1650,7 @@ int unit_add_default_cgroup(Unit *u) { if (!(b = new0(CGroupBonding, 1))) return -ENOMEM; - if (!(b->controller = strdup(u->meta.manager->cgroup_controller))) + if (!(b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER))) goto fail; if (!(b->path = default_cgroup_path(u))) @@ -1660,7 +1675,7 @@ fail: CGroupBonding* unit_get_default_cgroup(Unit *u) { assert(u); - return cgroup_bonding_find_list(u->meta.cgroup_bondings, u->meta.manager->cgroup_controller); + return cgroup_bonding_find_list(u->meta.cgroup_bondings, SYSTEMD_CGROUP_CONTROLLER); } int unit_load_related_unit(Unit *u, const char *type, Unit **_found) { @@ -1676,7 +1691,7 @@ int unit_load_related_unit(Unit *u, const char *type, Unit **_found) { assert(!unit_has_name(u, t)); - r = manager_load_unit(u->meta.manager, t, NULL, _found); + r = manager_load_unit(u->meta.manager, t, NULL, NULL, _found); free(t); assert(r < 0 || *_found != u); @@ -1961,7 +1976,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) { if (!(e = unit_name_build_escape(what+1, NULL, ".device"))) return -ENOMEM; - r = manager_load_unit(u->meta.manager, e, NULL, &device); + r = manager_load_unit(u->meta.manager, e, NULL, NULL, &device); free(e); if (r < 0) @@ -1987,7 +2002,7 @@ int unit_coldplug(Unit *u) { return r; if (u->meta.deserialized_job >= 0) { - if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_FAIL, false, NULL)) < 0) + if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_FAIL, false, NULL, NULL)) < 0) return r; u->meta.deserialized_job = _JOB_TYPE_INVALID; @@ -1996,6 +2011,29 @@ int unit_coldplug(Unit *u) { return 0; } +void unit_status_printf(Unit *u, const char *format, ...) { + va_list ap; + + assert(u); + assert(format); + + if (!UNIT_VTABLE(u)->show_status) + return; + + if (u->meta.manager->running_as != MANAGER_SYSTEM) + return; + + if (!u->meta.manager->show_status) + return; + + if (!manager_is_booting_or_shutting_down(u->meta.manager)) + return; + + va_start(ap, format); + status_vprintf(format, ap); + va_end(ap); +} + static const char* const unit_type_table[_UNIT_TYPE_MAX] = { [UNIT_SERVICE] = "service", [UNIT_TIMER] = "timer",