e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering This file is part of systemd.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Copyright 2013 Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (at your option) any later version.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is distributed in the hope that it will be useful, but
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Lesser General Public License for more details.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic const UnitActiveState state_translation_table[_BUSNAME_STATE_MAX] = {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n->timeout_usec = u->manager->default_timeout_start_usec;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void busname_unwatch_control_pid(BusName *n) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering unit_unwatch_pid(UNIT(n), n->control_pid);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void busname_free_policy(BusName *n) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering while ((p = n->policy)) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void busname_close_fd(BusName *n) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n->starter_event_source = sd_event_source_unref(n->starter_event_source);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n->starter_fd = safe_close(n->starter_fd);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n->timer_event_source = sd_event_source_unref(n->timer_event_source);
36c16a7cdd6c33d7980efc2cd6a2211941f302b4Lennart Poetteringstatic int busname_arm_timer(BusName *n, usec_t usec) {
36c16a7cdd6c33d7980efc2cd6a2211941f302b4Lennart Poettering r = sd_event_source_set_time(n->timer_event_source, usec);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_event_source_set_enabled(n->timer_event_source, SD_EVENT_ONESHOT);
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen (void) sd_event_source_set_description(n->timer_event_source, "busname-timer");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int busname_add_default_default_dependencies(BusName *n) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = unit_add_dependency_by_name(UNIT(n), UNIT_BEFORE, SPECIAL_BUSNAMES_TARGET, NULL, true);
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering if (UNIT(n)->manager->running_as == MANAGER_SYSTEM) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = unit_add_two_dependencies_by_name(UNIT(n), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return unit_add_two_dependencies_by_name(UNIT(n), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int busname_add_extras(BusName *n) {
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering r = unit_name_to_prefix(u->id, &n->name);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(n->service), true);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = busname_add_default_default_dependencies(n);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_error(UNIT(n), "Name= setting is not a valid service name Refusing.");
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_error(UNIT(n), "Name= setting doesn't match unit name. Refusing.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* This is a new unit? Then let's add in some extras */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void busname_dump(Unit *u, FILE *f, const char *prefix) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "%sBus Name State: %s\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "%sResult: %s\n"
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering "%sName: %s\n"
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack "%sActivating: %s\n"
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering "%sAccept FD: %s\n",
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering prefix, busname_state_to_string(n->state),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering prefix, busname_result_to_string(n->result),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void busname_unwatch_fd(BusName *n) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_OFF);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_debug_errno(UNIT(n), r, "Failed to disable event source: %m");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_ON);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_event_add_io(UNIT(n)->manager->event, &n->starter_event_source, n->starter_fd, EPOLLIN, busname_dispatch_io, n);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering (void) sd_event_source_set_description(n->starter_event_source, "busname-starter");
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering log_unit_warning_errno(UNIT(n), r, "Failed to watch starter fd: %m");
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek _cleanup_free_ char *path = NULL;
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering mode = UNIT(n)->manager->running_as == MANAGER_SYSTEM ? "system" : "user";
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek n->starter_fd = bus_kernel_open_bus_fd(mode, &path);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering return log_unit_warning_errno(UNIT(n), n->starter_fd, "Failed to open %s: %m", path ?: "kdbus");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void busname_set_state(BusName *n, BusNameState state) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!IN_SET(state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n->timer_event_source = sd_event_source_unref(n->timer_event_source);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!IN_SET(state, BUSNAME_LISTENING, BUSNAME_MAKING, BUSNAME_REGISTERED, BUSNAME_RUNNING))
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_debug(UNIT(n), "Changed %s -> %s", busname_state_to_string(old_state), busname_state_to_string(state));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unit_notify(UNIT(n), state_translation_table[old_state], state_translation_table[state], true);
c386f5886466de6022b3b4b1c8ac8df72871fbc7Lennart Poettering IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = unit_watch_pid(UNIT(n), n->control_pid);
36c16a7cdd6c33d7980efc2cd6a2211941f302b4Lennart Poettering r = busname_arm_timer(n, usec_add(u->state_change_timestamp.monotonic, n->timeout_usec));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING)) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (n->deserialized_state == BUSNAME_LISTENING) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering busname_set_state(n, n->deserialized_state);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int busname_make_starter(BusName *n, pid_t *_pid) {
36c16a7cdd6c33d7980efc2cd6a2211941f302b4Lennart Poettering r = busname_arm_timer(n, usec_add(now(CLOCK_MONOTONIC), n->timeout_usec));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* We have to resolve the user/group names out-of-process,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * hence let's fork here. It's messy, but well, what can we
ce30c8dcb41dfe9264f79f30c7f51c0e74576638Lennart Poettering (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, n->policy, n->policy_world);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to create starter connection at step %s: %m", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n->timer_event_source = sd_event_source_unref(n->timer_event_source);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void busname_enter_dead(BusName *n, BusNameResult f) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering busname_set_state(n, n->result != BUSNAME_SUCCESS ? BUSNAME_FAILED : BUSNAME_DEAD);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void busname_enter_signal(BusName *n, BusNameState state, BusNameResult f) {
db2cb23b5b179707000d28a11efb3d888d06ee80Umut Tezduyar Lindskog state != BUSNAME_SIGTERM ? KILL_KILL : KILL_TERMINATE,
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_warning_errno(UNIT(n), r, "Failed to kill control process: %m");
36c16a7cdd6c33d7980efc2cd6a2211941f302b4Lennart Poettering r = busname_arm_timer(n, usec_add(now(CLOCK_MONOTONIC), n->timeout_usec));
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_warning_errno(UNIT(n), r, "Failed to arm timer: %m");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_SUCCESS);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void busname_enter_listening(BusName *n) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (r < 0) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_warning_errno(UNIT(n), r, "Failed to watch names: %m");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_FAILURE_RESOURCES);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void busname_enter_making(BusName *n) {
8d0e0ddda6501479eb69164687c83c1a7667b33aJan Engelhardt /* If there is a policy, we need to resolve user/group
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * names, which we can't do from PID1, hence let's
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = busname_make_starter(n, &n->control_pid);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_warning_errno(UNIT(n), r, "Failed to fork 'making' task: %m");
8d0e0ddda6501479eb69164687c83c1a7667b33aJan Engelhardt /* If there is no policy, we can do everything
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * directly from PID 1, hence do so. */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, NULL, n->policy_world);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_warning_errno(UNIT(n), r, "Failed to make starter: %m");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void busname_enter_running(BusName *n) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
05a08cb60f02970e8476306074c70ee4e6a57fb3Thomas Hindoe Paaboel Andersen /* We don't take connections anymore if we are supposed to
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * shut down anyway */
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_debug(UNIT(n), "Suppressing activation request since unit stop is scheduled.");
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering /* Flush all queued activation reqeuest by closing and reopening the connection */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* If there's already a start pending don't bother to do
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering SET_FOREACH(other, UNIT(n)->dependencies[UNIT_TRIGGERS], i)
995c5e96cdf9e6054a4df04960253d897f4d7cc2Lennart Poettering log_unit_error(UNIT(n), "Service to activate vanished, refusing activation.");
4bd29fe5cec9d744a4e39240c76b85d999bd2cf7Lennart Poettering r = manager_add_job(UNIT(n)->manager, JOB_START, UNIT_DEREF(n->service), JOB_REPLACE, &error, NULL);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_warning(UNIT(n), "Failed to queue service startup job: %s", bus_error_message(&error, r));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* We cannot fulfill this request right now, try again later
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Already on it! */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering service = SERVICE(UNIT_DEREF(n->service));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (UNIT(service)->load_state != UNIT_LOADED) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_error(u, "Bus service %s not loaded, refusing.", UNIT(service)->id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(IN_SET(n->state, BUSNAME_DEAD, BUSNAME_FAILED));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Already on it */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* If there's already something running, we go directly into
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * kill mode. */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_SUCCESS);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack assert(IN_SET(n->state, BUSNAME_REGISTERED, BUSNAME_LISTENING, BUSNAME_RUNNING));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int busname_serialize(Unit *u, FILE *f, FDSet *fds) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unit_serialize_item(u, f, "state", busname_state_to_string(n->state));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unit_serialize_item(u, f, "result", busname_result_to_string(n->result));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering unit_serialize_item_format(u, f, "control-pid", PID_FMT, n->control_pid);
a34ceba66fc0e856d8f76f340389a4768b57a365Lennart Poettering r = unit_serialize_item_fd(u, f, fds, "starter-fd", n->starter_fd);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int busname_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering state = busname_state_from_string(value);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_debug(u, "Failed to parse state value: %s", value);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_debug(u, "Failed to parse result value: %s", value);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_debug(u, "Failed to parse control-pid value: %s", value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_debug(u, "Failed to parse starter fd value: %s", value);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_debug(u, "Unknown serialization key: %s", key);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering_pure_ static UnitActiveState busname_active_state(Unit *u) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return state_translation_table[BUSNAME(u)->state];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering_pure_ static const char *busname_sub_state_to_string(Unit *u) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return busname_state_to_string(BUSNAME(u)->state);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poetteringstatic int busname_peek_message(BusName *n) {
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering /* Generate a friendly debug log message about which process
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering * caused triggering of this bus name. This simply peeks the
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering * metadata of the first queued message and logs it. */
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering /* Let's shortcut things a bit, if debug logging is turned off
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann r = ioctl(n->starter_fd, KDBUS_CMD_RECV, &cmd_recv);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering return log_unit_error_errno(UNIT(n), errno, "Failed to query activation message: %m");
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering /* We map as late as possible, and unmap imemdiately after
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering * use. On 32bit address space is scarce and we want to be
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering * able to handle a lot of activator connections at the same
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering * time, and hence shouldn't keep the mmap()s around for
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering * longer than necessary. */
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering p = mmap(NULL, sz, PROT_READ, MAP_SHARED, n->starter_fd, start);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = log_unit_error_errno(UNIT(n), errno, "Failed to map activation message: %m");
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering k = (struct kdbus_msg *) ((uint8_t *) p + delta);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_debug(UNIT(n), "Activation triggered by process " PID_FMT " (%s)", pid, strna(comm));
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering if (ioctl(n->starter_fd, KDBUS_CMD_FREE, &cmd_free) < 0)
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_warning(UNIT(n), "Failed to free peeked message, ignoring: %m");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_debug(UNIT(n), "Activation request");
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_error(UNIT(n), "Got unexpected poll event (0x%x) on starter fd.", revents);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void busname_sigchld_event(Unit *u, pid_t pid, int code, int status) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert_not_reached("Unknown sigchld code");
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_full(u, f == BUSNAME_SUCCESS ? LOG_DEBUG : LOG_NOTICE, 0,
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering "Control process exited, code=%s status=%i", sigchld_code_to_string(code), status);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering busname_enter_signal(n, BUSNAME_SIGTERM, f);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert_not_reached("Uh, control process died at wrong time.");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Notify clients about changed exit status */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_warning(UNIT(n), "Making timed out. Terminating.");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_FAILURE_TIMEOUT);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_warning(UNIT(n), "Stopping timed out. Killing.");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_FAILURE_TIMEOUT);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering log_unit_warning(UNIT(n), "Processes still around after SIGKILL. Ignoring.");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering busname_enter_dead(n, BUSNAME_FAILURE_TIMEOUT);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert_not_reached("Timeout at wrong time.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void busname_reset_failed(Unit *u) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void busname_trigger_notify(Unit *u, Unit *other) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!IN_SET(n->state, BUSNAME_RUNNING, BUSNAME_LISTENING))
6bf0f408e4833152197fb38fb10a9989c89f3a59Lennart Poettering busname_enter_dead(n, BUSNAME_FAILURE_SERVICE_START_LIMIT_HIT);
6bf0f408e4833152197fb38fb10a9989c89f3a59Lennart Poettering if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
6bf0f408e4833152197fb38fb10a9989c89f3a59Lennart Poettering SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
6bf0f408e4833152197fb38fb10a9989c89f3a59Lennart Poettering if (SERVICE(other)->state == SERVICE_RUNNING)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int busname_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return unit_kill_common(u, who, signo, -1, BUSNAME(u)->control_pid, error);
7a7821c878a6ddfb2e79268bb1cd8f7662a9b8f8Lennart Poetteringstatic int busname_get_timeout(Unit *u, usec_t *timeout) {
7a7821c878a6ddfb2e79268bb1cd8f7662a9b8f8Lennart Poettering r = sd_event_source_get_time(n->timer_event_source, &t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic const char* const busname_result_table[_BUSNAME_RESULT_MAX] = {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering [BUSNAME_FAILURE_RESOURCES] = "resources",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering [BUSNAME_FAILURE_EXIT_CODE] = "exit-code",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering [BUSNAME_FAILURE_CORE_DUMP] = "core-dump",
6bf0f408e4833152197fb38fb10a9989c89f3a59Lennart Poettering [BUSNAME_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit",
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart PoetteringDEFINE_STRING_TABLE_LOOKUP(busname_result, BusNameResult);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering .deserialize_item = busname_deserialize_item,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering .sub_state_to_string = busname_sub_state_to_string,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering .trigger_notify = busname_trigger_notify,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering [JOB_FAILED] = "Failed to listen on %s.",