X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fcore%2Fbusname.c;h=63c7dde0bd9f23b4924a285b98c537585610296a;hb=4b58153dd22172d817055d2a09a0cdf3f4bd9db3;hp=3592f72fe5f46b3041ea6710856dd45638bd99b7;hpb=64529a2921a8972878b3f953935f286ce77914e0;p=thirdparty%2Fsystemd.git diff --git a/src/core/busname.c b/src/core/busname.c index 3592f72fe5f..63c7dde0bd9 100644 --- a/src/core/busname.c +++ b/src/core/busname.c @@ -1,5 +1,3 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** This file is part of systemd. @@ -112,29 +110,27 @@ static void busname_done(Unit *u) { n->timer_event_source = sd_event_source_unref(n->timer_event_source); } -static int busname_arm_timer(BusName *n) { +static int busname_arm_timer(BusName *n, usec_t usec) { int r; assert(n); - if (n->timeout_usec <= 0) { - n->timer_event_source = sd_event_source_unref(n->timer_event_source); - return 0; - } - if (n->timer_event_source) { - r = sd_event_source_set_time(n->timer_event_source, now(CLOCK_MONOTONIC) + n->timeout_usec); + r = sd_event_source_set_time(n->timer_event_source, usec); if (r < 0) return r; return sd_event_source_set_enabled(n->timer_event_source, SD_EVENT_ONESHOT); } + if (usec == USEC_INFINITY) + return 0; + r = sd_event_add_time( UNIT(n)->manager->event, &n->timer_event_source, CLOCK_MONOTONIC, - now(CLOCK_MONOTONIC) + n->timeout_usec, 0, + usec, 0, busname_dispatch_timer, n); if (r < 0) return r; @@ -153,7 +149,7 @@ static int busname_add_default_default_dependencies(BusName *n) { if (r < 0) return r; - if (UNIT(n)->manager->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(UNIT(n)->manager)) { r = unit_add_two_dependencies_by_name(UNIT(n), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true); if (r < 0) return r; @@ -322,7 +318,7 @@ static int busname_open_fd(BusName *n) { if (n->starter_fd >= 0) return 0; - mode = UNIT(n)->manager->running_as == MANAGER_SYSTEM ? "system" : "user"; + mode = MANAGER_IS_SYSTEM(UNIT(n)->manager) ? "system" : "user"; n->starter_fd = bus_kernel_open_bus_fd(mode, &path); if (n->starter_fd < 0) return log_unit_warning_errno(UNIT(n), n->starter_fd, "Failed to open %s: %m", path ?: "kdbus"); @@ -364,16 +360,15 @@ static int busname_coldplug(Unit *u) { if (n->deserialized_state == n->state) return 0; - if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) { - - if (n->control_pid <= 0) - return -EBADMSG; + if (n->control_pid > 0 && + pid_is_unwaited(n->control_pid) && + IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) { r = unit_watch_pid(UNIT(n), n->control_pid); if (r < 0) return r; - r = busname_arm_timer(n); + r = busname_arm_timer(n, usec_add(u->state_change_timestamp.monotonic, n->timeout_usec)); if (r < 0) return r; } @@ -398,7 +393,7 @@ static int busname_make_starter(BusName *n, pid_t *_pid) { pid_t pid; int r; - r = busname_arm_timer(n); + r = busname_arm_timer(n, usec_add(now(CLOCK_MONOTONIC), n->timeout_usec)); if (r < 0) goto fail; @@ -447,7 +442,7 @@ fail: static void busname_enter_dead(BusName *n, BusNameResult f) { assert(n); - if (f != BUSNAME_SUCCESS) + if (n->result == BUSNAME_SUCCESS) n->result = f; busname_set_state(n, n->result != BUSNAME_SUCCESS ? BUSNAME_FAILED : BUSNAME_DEAD); @@ -459,7 +454,7 @@ static void busname_enter_signal(BusName *n, BusNameState state, BusNameResult f assert(n); - if (f != BUSNAME_SUCCESS) + if (n->result == BUSNAME_SUCCESS) n->result = f; kill_context_init(&kill_context); @@ -476,7 +471,7 @@ static void busname_enter_signal(BusName *n, BusNameState state, BusNameResult f } if (r > 0) { - r = busname_arm_timer(n); + r = busname_arm_timer(n, usec_add(now(CLOCK_MONOTONIC), n->timeout_usec)); if (r < 0) { log_unit_warning_errno(UNIT(n), r, "Failed to arm timer: %m"); goto fail; @@ -558,7 +553,7 @@ fail: } static void busname_enter_running(BusName *n) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; bool pending = false; Unit *other; Iterator i; @@ -597,7 +592,7 @@ static void busname_enter_running(BusName *n) { goto fail; } - r = manager_add_job(UNIT(n)->manager, JOB_START, UNIT_DEREF(n->service), JOB_REPLACE, true, &error, NULL); + r = manager_add_job(UNIT(n)->manager, JOB_START, UNIT_DEREF(n->service), JOB_REPLACE, &error, NULL); if (r < 0) goto fail; } @@ -612,6 +607,7 @@ fail: static int busname_start(Unit *u) { BusName *n = BUSNAME(u); + int r; assert(n); @@ -637,6 +633,16 @@ static int busname_start(Unit *u) { assert(IN_SET(n->state, BUSNAME_DEAD, BUSNAME_FAILED)); + r = unit_start_limit_test(u); + if (r < 0) { + busname_enter_dead(n, BUSNAME_FAILURE_START_LIMIT_HIT); + return r; + } + + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + n->result = BUSNAME_SUCCESS; busname_enter_making(n); @@ -880,7 +886,7 @@ static void busname_sigchld_event(Unit *u, pid_t pid, int code, int status) { log_unit_full(u, f == BUSNAME_SUCCESS ? LOG_DEBUG : LOG_NOTICE, 0, "Control process exited, code=%s status=%i", sigchld_code_to_string(code), status); - if (f != BUSNAME_SUCCESS) + if (n->result == BUSNAME_SUCCESS) n->result = f; switch (n->state) { @@ -948,7 +954,6 @@ static void busname_reset_failed(Unit *u) { static void busname_trigger_notify(Unit *u, Unit *other) { BusName *n = BUSNAME(u); - Service *s; assert(n); assert(other); @@ -956,46 +961,56 @@ static void busname_trigger_notify(Unit *u, Unit *other) { if (!IN_SET(n->state, BUSNAME_RUNNING, BUSNAME_LISTENING)) return; - if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE) + if (other->start_limit_hit) { + busname_enter_dead(n, BUSNAME_FAILURE_SERVICE_START_LIMIT_HIT); return; + } - s = SERVICE(other); + if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE) + return; - if (s->state == SERVICE_FAILED && s->result == SERVICE_FAILURE_START_LIMIT) - busname_enter_dead(n, BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT); - else if (IN_SET(s->state, - SERVICE_DEAD, SERVICE_FAILED, - SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, - SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL, - SERVICE_AUTO_RESTART)) + if (IN_SET(SERVICE(other)->state, + SERVICE_DEAD, SERVICE_FAILED, + SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL, + SERVICE_AUTO_RESTART)) busname_enter_listening(n); + + if (SERVICE(other)->state == SERVICE_RUNNING) + busname_set_state(n, BUSNAME_RUNNING); } static int busname_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { return unit_kill_common(u, who, signo, -1, BUSNAME(u)->control_pid, error); } -static int busname_get_timeout(Unit *u, uint64_t *timeout) { +static int busname_get_timeout(Unit *u, usec_t *timeout) { BusName *n = BUSNAME(u); + usec_t t; int r; if (!n->timer_event_source) return 0; - r = sd_event_source_get_time(n->timer_event_source, timeout); + r = sd_event_source_get_time(n->timer_event_source, &t); if (r < 0) return r; + if (t == USEC_INFINITY) + return 0; + *timeout = t; return 1; } static bool busname_supported(void) { - static int supported = -1; + return false; +} - if (supported < 0) - supported = is_kdbus_available(); +static int busname_control_pid(Unit *u) { + BusName *n = BUSNAME(u); - return supported; + assert(n); + + return n->control_pid; } static const char* const busname_result_table[_BUSNAME_RESULT_MAX] = { @@ -1005,7 +1020,8 @@ static const char* const busname_result_table[_BUSNAME_RESULT_MAX] = { [BUSNAME_FAILURE_EXIT_CODE] = "exit-code", [BUSNAME_FAILURE_SIGNAL] = "signal", [BUSNAME_FAILURE_CORE_DUMP] = "core-dump", - [BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent", + [BUSNAME_FAILURE_START_LIMIT_HIT] = "start-limit-hit", + [BUSNAME_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit", }; DEFINE_STRING_TABLE_LOOKUP(busname_result, BusNameResult); @@ -1019,9 +1035,6 @@ const UnitVTable busname_vtable = { "Install\0", .private_section = "BusName", - .no_alias = true, - .no_instances = true, - .init = busname_init, .done = busname_done, .load = busname_load, @@ -1051,6 +1064,8 @@ const UnitVTable busname_vtable = { .supported = busname_supported, + .control_pid = busname_control_pid, + .bus_vtable = bus_busname_vtable, .status_message_formats = {