busname.c revision c95f97a20f3b854109dc564da64950067b388aeb
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer This file is part of systemd.
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer Copyright 2013 Lennart Poettering
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer systemd is free software; you can redistribute it and/or modify it
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer under the terms of the GNU Lesser General Public License as published by
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt the Free Software Foundation; either version 2.1 of the License, or
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt (at your option) any later version.
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt systemd is distributed in the hope that it will be useful, but
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt WITHOUT ANY WARRANTY; without even the implied warranty of
4be4833ece2856e0cacc09f8f8b2c02b320751faMartin Pitt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c50a4525aa8151b180d5a325e88c5f3812e66c36Martin Pitt Lesser General Public License for more details.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier You should have received a copy of the GNU Lesser General Public License
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier along with systemd; If not, see <http://www.gnu.org/licenses/>.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic const UnitActiveState state_translation_table[_BUSNAME_STATE_MAX] = {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyerstatic int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier n->timeout_usec = u->manager->default_timeout_start_usec;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic void busname_unwatch_control_pid(BusName *n) {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic void busname_free_policy(BusName *n) {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier while ((p = n->policy)) {
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmekstatic void busname_close_fd(BusName *n) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier n->starter_event_source = sd_event_source_unref(n->starter_event_source);
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek n->starter_fd = safe_close(n->starter_fd);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier n->timer_event_source = sd_event_source_unref(n->timer_event_source);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier n->timer_event_source = sd_event_source_unref(n->timer_event_source);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_event_source_set_time(n->timer_event_source, now(CLOCK_MONOTONIC) + n->timeout_usec);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return sd_event_source_set_enabled(n->timer_event_source, SD_EVENT_ONESHOT);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int busname_add_default_default_dependencies(BusName *n) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = unit_add_dependency_by_name(UNIT(n), UNIT_BEFORE, SPECIAL_BUSNAMES_TARGET, NULL, true);
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek if (UNIT(n)->manager->running_as == SYSTEMD_SYSTEM) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = unit_add_two_dependencies_by_name(UNIT(n), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
edbced8a151c1b7ded685e2ec644950d2adec5f5Harald Hoyer return unit_add_two_dependencies_by_name(UNIT(n), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = unit_load_related_unit(u, ".service", &x);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(n->service), true);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = busname_add_default_default_dependencies(n);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_unit_error(UNIT(n)->id, "%s's Name= setting is not a valid service name Refusing.", UNIT(n)->id);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_unit_error(UNIT(n)->id, "%s's Name= setting doesn't match unit name. Refusing.", UNIT(n)->id);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* This is a new unit? Then let's add in some extras */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic void busname_dump(Unit *u, FILE *f, const char *prefix) {
7d023341c765c205068e33d23d63a4000ec211dfMartin Pitt "%sBus Name State: %s\n"
7d023341c765c205068e33d23d63a4000ec211dfMartin Pitt "%sResult: %s\n"
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "%sName: %s\n"
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "%sActivating: %s\n"
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "%sAccept FD: %s\n",
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier prefix, busname_result_to_string(n->result),
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_OFF);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_unit_debug(UNIT(n)->id, "Failed to disable event source.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_ON);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_event_add_io(UNIT(n)->manager->event, &n->starter_event_source, n->starter_fd, EPOLLIN, busname_dispatch_io, n);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_unit_warning_errno(UNIT(n)->id, r, "Failed to watch starter fd: %m");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier mode = UNIT(n)->manager->running_as == SYSTEMD_SYSTEM ? "system" : "user";
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier n->starter_fd = bus_kernel_open_bus_fd(mode, &path);
53d90f9582f96208b3674da823ad1a3d2c3b1aa4Martin Pitt log_unit_warning_errno(UNIT(n)->id, n->starter_fd, "Failed to open %s: %m", path ?: "kdbus");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic void busname_set_state(BusName *n, BusNameState state) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!IN_SET(state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier n->timer_event_source = sd_event_source_unref(n->timer_event_source);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!IN_SET(state, BUSNAME_LISTENING, BUSNAME_MAKING, BUSNAME_REGISTERED, BUSNAME_RUNNING))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_debug(UNIT(n)->id, "%s changed %s -> %s",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer UNIT(n)->id, busname_state_to_string(old_state), busname_state_to_string(state));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unit_notify(UNIT(n), state_translation_table[old_state], state_translation_table[state], true);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING)) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (n->deserialized_state == BUSNAME_LISTENING) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int busname_make_starter(BusName *n, pid_t *_pid) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* We have to resolve the user/group names out-of-process,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * hence let's fork here. It's messy, but well, what can we
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, n->policy, n->policy_world);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error_errno(r, "Failed to create starter connection at step %s: %m", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer n->timer_event_source = sd_event_source_unref(n->timer_event_source);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void busname_enter_dead(BusName *n, BusNameResult f) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer busname_set_state(n, n->result != BUSNAME_SUCCESS ? BUSNAME_FAILED : BUSNAME_DEAD);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void busname_enter_signal(BusName *n, BusNameState state, BusNameResult f) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer state != BUSNAME_SIGTERM ? KILL_KILL : KILL_TERMINATE,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_warning_errno(UNIT(n)->id, r, "%s failed to kill control process: %m", UNIT(n)->id);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r > 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_warning_errno(UNIT(n)->id, r, "%s failed to arm timer: %m", UNIT(n)->id);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_SUCCESS);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic void busname_enter_listening(BusName *n) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_warning_errno(UNIT(n)->id, r, "%s failed to watch names: %m", UNIT(n)->id);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_FAILURE_RESOURCES);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* If there is a policy, we need to resolve user/group
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * names, which we can't do from PID1, hence let's
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_warning_errno(UNIT(n)->id, r, "%s failed to fork 'making' task: %m", UNIT(n)->id);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* If there is no policy, we can do everything
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * directly from PID 1, hence do so. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, NULL, n->policy_world);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_warning_errno(UNIT(n)->id, r, "%s failed to make starter: %m", UNIT(n)->id);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bool pending = false;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* We don't take conenctions anymore if we are supposed to
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * shut down anyway */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_debug(UNIT(n)->id, "Suppressing activation request on %s since unit stop is scheduled.", UNIT(n)->id);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Flush all queued activation reqeuest by closing and reopening the connection */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* If there's already a start pending don't bother to do
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * anything */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer SET_FOREACH(other, UNIT(n)->dependencies[UNIT_TRIGGERS], i)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = manager_add_job(UNIT(n)->manager, JOB_START, UNIT_DEREF(n->service), JOB_REPLACE, true, &error, NULL);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_warning(UNIT(n)->id, "%s failed to queue service startup job: %s", UNIT(n)->id, bus_error_message(&error, r));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* We cannot fulfill this request right now, try again later
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * please! */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Already on it! */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (UNIT(service)->load_state != UNIT_LOADED) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_error(u->id, "Bus service %s not loaded, refusing.", UNIT(service)->id);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(IN_SET(n->state, BUSNAME_DEAD, BUSNAME_FAILED));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Already on it */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* If there's already something running, we go directly into
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * kill mode. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_SUCCESS);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(IN_SET(n->state, BUSNAME_REGISTERED, BUSNAME_LISTENING, BUSNAME_RUNNING));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int busname_serialize(Unit *u, FILE *f, FDSet *fds) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unit_serialize_item(u, f, "state", busname_state_to_string(n->state));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unit_serialize_item(u, f, "result", busname_result_to_string(n->result));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unit_serialize_item_format(u, f, "control-pid", PID_FMT, n->control_pid);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (n->starter_fd >= 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unit_serialize_item_format(u, f, "starter-fd", "%i", copy);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int busname_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_debug(u->id, "Failed to parse state value %s", value);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_debug(u->id, "Failed to parse result value %s", value);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_debug(u->id, "Failed to parse control-pid value %s", value);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_debug(u->id, "Failed to parse starter fd value %s", value);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_debug(u->id, "Unknown serialization key '%s'", key);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer_pure_ static UnitActiveState busname_active_state(Unit *u) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return state_translation_table[BUSNAME(u)->state];
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer_pure_ static const char *busname_sub_state_to_string(Unit *u) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return busname_state_to_string(BUSNAME(u)->state);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Generate a friendly debug log message about which process
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * caused triggering of this bus name. This simply peeks the
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * metadata of the first queued message and logs it. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Let's shortcut things a bit, if debug logging is turned off
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * anyway. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = ioctl(n->starter_fd, KDBUS_CMD_MSG_RECV, &cmd_recv);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_error(UNIT(n)->id, "%s: Failed to query activation message: %m", UNIT(n)->id);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* We map as late as possible, and unmap imemdiately after
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * use. On 32bit address space is scarce and we want to be
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * able to handle a lot of activator connections at the same
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * time, and hence shouldn't keep the mmap()s around for
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * longer than necessary. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer p = mmap(NULL, sz, PROT_READ, MAP_SHARED, n->starter_fd, start);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_error(UNIT(n)->id, "%s: Failed to map activation message: %m", UNIT(n)->id);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer k = (struct kdbus_msg *) ((uint8_t *) p + delta);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer switch (d->type) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_debug(UNIT(n)->id, "%s: Activation triggered by process " PID_FMT " (%s)", UNIT(n)->id, pid, strna(comm));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (ioctl(n->starter_fd, KDBUS_CMD_FREE, &cmd_free) < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_warning(UNIT(n)->id, "Failed to free peeked message, ignoring: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_debug(UNIT(n)->id, "Activation request on %s", UNIT(n)->id);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_unit_error(UNIT(n)->id, "%s: Got unexpected poll event (0x%x) on starter fd.",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void busname_sigchld_event(Unit *u, pid_t pid, int code, int status) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "%s control process exited, code=%s status=%i",
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer switch (n->state) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert_not_reached("Uh, control process died at wrong time.");
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* Notify clients about changed exit status */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer switch (n->state) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_unit_warning(UNIT(n)->id, "%s making timed out. Terminating.", UNIT(n)->id);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_FAILURE_TIMEOUT);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_unit_warning(UNIT(n)->id, "%s stopping timed out. Killing.", UNIT(n)->id);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_FAILURE_TIMEOUT);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_unit_warning(UNIT(n)->id, "%s still around after SIGKILL. Ignoring.", UNIT(n)->id);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer busname_enter_dead(n, BUSNAME_FAILURE_TIMEOUT);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic void busname_trigger_notify(Unit *u, Unit *other) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (!IN_SET(n->state, BUSNAME_RUNNING, BUSNAME_LISTENING))
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (s->state == SERVICE_FAILED && s->result == SERVICE_FAILURE_START_LIMIT)
c53158818d8cdaf46b3f1b5299b9bda118a1043fThomas Hindoe Paaboel Andersen busname_enter_dead(n, BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int busname_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return unit_kill_common(u, who, signo, -1, BUSNAME(u)->control_pid, error);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int busname_get_timeout(Unit *u, uint64_t *timeout) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = sd_event_source_get_time(n->timer_event_source, timeout);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic const char* const busname_state_table[_BUSNAME_STATE_MAX] = {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald HoyerDEFINE_STRING_TABLE_LOOKUP(busname_state, BusNameState);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic const char* const busname_result_table[_BUSNAME_RESULT_MAX] = {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer [BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent",
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald HoyerDEFINE_STRING_TABLE_LOOKUP(busname_result, BusNameResult);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer "Install\0",
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer .sub_state_to_string = busname_sub_state_to_string,
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer .bus_interface = "org.freedesktop.systemd1.BusName",
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer [JOB_DEPENDENCY] = "Dependency failed for %s.",