busname.c revision dcc2fc01fa850e9ee36c549dc2691e7e5c71bebf
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/***
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt This file is part of systemd.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt Copyright 2013 Lennart Poettering
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt systemd is free software; you can redistribute it and/or modify it
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt under the terms of the GNU Lesser General Public License as published by
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt the Free Software Foundation; either version 2.1 of the License, or
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt (at your option) any later version.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt systemd is distributed in the hope that it will be useful, but
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt WITHOUT ANY WARRANTY; without even the implied warranty of
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt Lesser General Public License for more details.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt You should have received a copy of the GNU Lesser General Public License
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt along with systemd; If not, see <http://www.gnu.org/licenses/>.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt***/
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <sys/mman.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt#include "special.h"
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams#include "bus-kernel.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "bus-internal.h"
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#include "bus-util.h"
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#include "service.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "dbus-busname.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "busname.h"
3df3e884ae1237ef0d4d23b0e80f4ffda95ac135Ronny Chevalier#include "kdbus.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flyktstatic const UnitActiveState state_translation_table[_BUSNAME_STATE_MAX] = {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [BUSNAME_DEAD] = UNIT_INACTIVE,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [BUSNAME_MAKING] = UNIT_ACTIVATING,
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt [BUSNAME_REGISTERED] = UNIT_ACTIVE,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt [BUSNAME_LISTENING] = UNIT_ACTIVE,
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen [BUSNAME_RUNNING] = UNIT_ACTIVE,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt [BUSNAME_SIGTERM] = UNIT_DEACTIVATING,
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams [BUSNAME_SIGKILL] = UNIT_DEACTIVATING,
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams [BUSNAME_FAILED] = UNIT_FAILED
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt};
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic void busname_init(Unit *u) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt BusName *n = BUSNAME(u);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams assert(u);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams assert(u->load_state == UNIT_STUB);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt n->starter_fd = -1;
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt n->accept_fd = true;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt n->activating = true;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt n->timeout_usec = u->manager->default_timeout_start_usec;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt}
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flyktstatic void busname_unwatch_control_pid(BusName *n) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(n);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (n->control_pid <= 0)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt unit_unwatch_pid(UNIT(n), n->control_pid);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt n->control_pid = 0;
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen}
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic void busname_free_policy(BusName *n) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt BusNamePolicy *p;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt assert(n);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt while ((p = n->policy)) {
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt LIST_REMOVE(policy, n->policy, p);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt free(p->name);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(p);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt}
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic void busname_close_fd(BusName *n) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(n);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt n->starter_event_source = sd_event_source_unref(n->starter_event_source);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt n->starter_fd = safe_close(n->starter_fd);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt}
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic void busname_done(Unit *u) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt BusName *n = BUSNAME(u);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(n);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(n->name);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt n->name = NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_free_policy(n);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_unwatch_control_pid(n);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_close_fd(n);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unit_ref_unset(&n->service);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt n->timer_event_source = sd_event_source_unref(n->timer_event_source);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic int busname_arm_timer(BusName *n) {
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt int r;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt assert(n);
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt if (n->timeout_usec <= 0) {
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt n->timer_event_source = sd_event_source_unref(n->timer_event_source);
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt return 0;
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (n->timer_event_source) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt r = sd_event_source_set_time(n->timer_event_source, now(CLOCK_MONOTONIC) + n->timeout_usec);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (r < 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return r;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return sd_event_source_set_enabled(n->timer_event_source, SD_EVENT_ONESHOT);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return sd_event_add_time(
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt UNIT(n)->manager->event,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt &n->timer_event_source,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt CLOCK_MONOTONIC,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt now(CLOCK_MONOTONIC) + n->timeout_usec, 0,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt busname_dispatch_timer, n);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt}
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic int busname_add_default_default_dependencies(BusName *n) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt int r;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(n);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams r = unit_add_dependency_by_name(UNIT(n), UNIT_BEFORE, SPECIAL_BUSNAMES_TARGET, NULL, true);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (r < 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return r;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (UNIT(n)->manager->running_as == SYSTEMD_SYSTEM) {
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams r = unit_add_two_dependencies_by_name(UNIT(n), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (r < 0)
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams return r;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams }
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams return unit_add_two_dependencies_by_name(UNIT(n), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt}
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williamsstatic int busname_add_extras(BusName *n) {
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams Unit *u = UNIT(n);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams int r;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams assert(n);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (!n->name) {
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams n->name = unit_name_to_prefix(u->id);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (!n->name)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return -ENOMEM;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller if (!u->description) {
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller r = unit_set_description(u, n->name);
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller if (r < 0)
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller return r;
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller }
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller if (n->activating) {
ebe207d4acf38165adbc45298662982eecdb9e9fTom Gundersen if (!UNIT_DEREF(n->service)) {
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams Unit *x;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams r = unit_load_related_unit(u, ".service", &x);
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams if (r < 0)
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams return r;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen unit_ref_set(&n->service, x);
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen }
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(n->service), true);
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen if (r < 0)
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen return r;
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen }
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen if (u->default_dependencies) {
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen r = busname_add_default_default_dependencies(n);
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen if (r < 0)
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen return r;
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen }
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen return 0;
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen}
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersenstatic int busname_verify(BusName *n) {
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen char *e;
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen assert(n);
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen if (UNIT(n)->load_state != UNIT_LOADED)
ebe207d4acf38165adbc45298662982eecdb9e9fTom Gundersen return 0;
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams if (!service_name_is_valid(n->name)) {
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams log_error_unit(UNIT(n)->id, "%s's Name= setting is not a valid service name Refusing.", UNIT(n)->id);
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams return -EINVAL;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt e = strappenda(n->name, ".busname");
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (!unit_has_name(UNIT(n), e)) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_error_unit(UNIT(n)->id, "%s's Name= setting doesn't match unit name. Refusing.", UNIT(n)->id);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return -EINVAL;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return 0;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt}
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktstatic int busname_load(Unit *u) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt BusName *n = BUSNAME(u);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt int r;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt assert(u);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt assert(u->load_state == UNIT_STUB);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt r = unit_load_fragment_and_dropin(u);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (r < 0)
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt return r;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (u->load_state == UNIT_LOADED) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt /* This is a new unit? Then let's add in some extras */
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt r = busname_add_extras(n);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (r < 0)
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt return r;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt }
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt return busname_verify(n);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt}
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flyktstatic void busname_dump(Unit *u, FILE *f, const char *prefix) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt BusName *n = BUSNAME(u);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt assert(n);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt assert(f);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt fprintf(f,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "%sBus Name State: %s\n"
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "%sResult: %s\n"
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "%sName: %s\n"
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "%sActivating: %s\n"
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "%sAccept FD: %s\n",
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt prefix, busname_state_to_string(n->state),
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt prefix, busname_result_to_string(n->result),
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt prefix, n->name,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt prefix, yes_no(n->activating),
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt prefix, yes_no(n->accept_fd));
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (n->control_pid > 0)
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt fprintf(f,
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt "%sControl PID: "PID_FMT"\n",
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt prefix, n->control_pid);
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt}
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flyktstatic void busname_unwatch_fd(BusName *n) {
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt int r;
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt assert(n);
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt if (!n->starter_event_source)
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt return;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_OFF);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (r < 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_debug_unit(UNIT(n)->id, "Failed to disable event source.");
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt}
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic int busname_watch_fd(BusName *n) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt int r;
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt assert(n);
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt if (n->starter_fd < 0)
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt return 0;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (n->starter_event_source)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_ON);
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek else
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = sd_event_add_io(UNIT(n)->manager->event, &n->starter_event_source, n->starter_fd, EPOLLIN, busname_dispatch_io, n);
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt if (r < 0) {
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt log_warning_unit(UNIT(n)->id, "Failed to watch starter fd: %s", strerror(-r));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt busname_unwatch_fd(n);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return r;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt }
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return 0;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic int busname_open_fd(BusName *n) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt _cleanup_free_ char *path = NULL;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt const char *mode;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(n);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (n->starter_fd >= 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt mode = UNIT(n)->manager->running_as == SYSTEMD_SYSTEM ? "system" : "user";
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt n->starter_fd = bus_kernel_open_bus_fd(mode, &path);
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt if (n->starter_fd < 0) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_warning_unit(UNIT(n)->id, "Failed to open %s: %s", path ?: "kdbus", strerror(-n->starter_fd));
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt return n->starter_fd;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt return 0;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt}
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic void busname_set_state(BusName *n, BusNameState state) {
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt BusNameState old_state;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(n);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt old_state = n->state;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt n->state = state;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (!IN_SET(state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt n->timer_event_source = sd_event_source_unref(n->timer_event_source);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt busname_unwatch_control_pid(n);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (state != BUSNAME_LISTENING)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt busname_unwatch_fd(n);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (!IN_SET(state, BUSNAME_LISTENING, BUSNAME_MAKING, BUSNAME_REGISTERED, BUSNAME_RUNNING))
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt busname_close_fd(n);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (state != old_state)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_debug_unit(UNIT(n)->id, "%s changed %s -> %s",
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt UNIT(n)->id, busname_state_to_string(old_state), busname_state_to_string(state));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt unit_notify(UNIT(n), state_translation_table[old_state], state_translation_table[state], true);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt}
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktstatic int busname_coldplug(Unit *u) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt BusName *n = BUSNAME(u);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt int r;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(n);
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt assert(n->state == BUSNAME_DEAD);
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
926695f1b5f9395eeb416cc2f478a9cf75fdbeb4Thomas Hindoe Paaboel Andersen if (n->deserialized_state == n->state)
926695f1b5f9395eeb416cc2f478a9cf75fdbeb4Thomas Hindoe Paaboel Andersen return 0;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (n->control_pid <= 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return -EBADMSG;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt r = unit_watch_pid(UNIT(n), n->control_pid);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (r < 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return r;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = busname_arm_timer(n);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r < 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return r;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING)) {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt r = busname_open_fd(n);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (r < 0)
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt return r;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (n->deserialized_state == BUSNAME_LISTENING) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = busname_watch_fd(n);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (r < 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return r;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt busname_set_state(n, n->deserialized_state);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return 0;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt}
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flyktstatic int busname_make_starter(BusName *n, pid_t *_pid) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt pid_t pid;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt int r;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = busname_arm_timer(n);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (r < 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt goto fail;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt /* We have to resolve the user/group names out-of-process,
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt * hence let's fork here. It's messy, but well, what can we
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt * do? */
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt pid = fork();
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (pid < 0)
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt return -errno;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller if (pid == 0) {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt int ret;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt ignore_signals(SIGPIPE, -1);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt log_forget_fds();
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, n->policy, n->policy_world);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (r < 0) {
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt ret = EXIT_MAKE_STARTER;
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt goto fail_child;
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt }
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt _exit(0);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt fail_child:
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt log_open();
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_error("Failed to create starter connection at step %s: %s", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD), strerror(-r));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt _exit(ret);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = unit_watch_pid(UNIT(n), pid);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (r < 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt goto fail;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt *_pid = pid;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktfail:
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt n->timer_event_source = sd_event_source_unref(n->timer_event_source);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic void busname_enter_dead(BusName *n, BusNameResult f) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(n);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (f != BUSNAME_SUCCESS)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt n->result = f;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt busname_set_state(n, n->result != BUSNAME_SUCCESS ? BUSNAME_FAILED : BUSNAME_DEAD);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt}
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic void busname_enter_signal(BusName *n, BusNameState state, BusNameResult f) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt KillContext kill_context = {};
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt int r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(n);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (f != BUSNAME_SUCCESS)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt n->result = f;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt kill_context_init(&kill_context);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = unit_kill_context(UNIT(n),
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt &kill_context,
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt state != BUSNAME_SIGTERM ? KILL_KILL : KILL_TERMINATE,
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt -1,
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt n->control_pid,
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt false);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r < 0) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_warning_unit(UNIT(n)->id, "%s failed to kill control process: %s", UNIT(n)->id, strerror(-r));
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt goto fail;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r > 0) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = busname_arm_timer(n);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r < 0) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_warning_unit(UNIT(n)->id, "%s failed to arm timer: %s", UNIT(n)->id, strerror(-r));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt goto fail;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt busname_set_state(n, state);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt } else if (state == BUSNAME_SIGTERM)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_SUCCESS);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt else
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt busname_enter_dead(n, BUSNAME_SUCCESS);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flyktfail:
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic void busname_enter_listening(BusName *n) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt int r;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(n);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (n->activating) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = busname_watch_fd(n);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r < 0) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_warning_unit(UNIT(n)->id, "%s failed to watch names: %s", UNIT(n)->id, strerror(-r));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt goto fail;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
4b4923e65423e60d755841b5b264730e8f3deab3Tom Gundersen
5e91345094a9e983e7abb2313334e7808bcd2cc2Tom Gundersen busname_set_state(n, BUSNAME_LISTENING);
513a6fa8679510ea1b55967bdb482dd5f8a39f21Ronny Chevalier } else
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt busname_set_state(n, BUSNAME_REGISTERED);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktfail:
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_FAILURE_RESOURCES);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic void busname_enter_making(BusName *n) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt int r;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt assert(n);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt r = busname_open_fd(n);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (r < 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt goto fail;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (n->policy) {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt /* If there is a policy, we need to resolve user/group
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt * names, which we can't do from PID1, hence let's
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt * fork. */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt busname_unwatch_control_pid(n);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = busname_make_starter(n, &n->control_pid);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r < 0) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_warning_unit(UNIT(n)->id, "%s failed to fork 'making' task: %s", UNIT(n)->id, strerror(-r));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt goto fail;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt busname_set_state(n, BUSNAME_MAKING);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt } else {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt /* If there is no policy, we can do everything
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt * directly from PID 1, hence do so. */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, NULL, n->policy_world);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r < 0) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_warning_unit(UNIT(n)->id, "%s failed to make starter: %s", UNIT(n)->id, strerror(-r));
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt goto fail;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt }
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt busname_enter_listening(n);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt }
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flyktfail:
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt}
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flyktstatic void busname_enter_running(BusName *n) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt bool pending = false;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt Unit *other;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt Iterator i;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt int r;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt assert(n);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (!n->activating)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* We don't take conenctions anymore if we are supposed to
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * shut down anyway */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (unit_stop_pending(UNIT(n))) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_debug_unit(UNIT(n)->id, "Suppressing activation request on %s since unit stop is scheduled.", UNIT(n)->id);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* Flush all queued activation reqeuest by closing and reopening the connection */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt bus_kernel_drop_one(n->starter_fd);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt busname_enter_listening(n);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return;
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* If there's already a start pending don't bother to do
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * anything */
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt SET_FOREACH(other, UNIT(n)->dependencies[UNIT_TRIGGERS], i)
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (unit_active_or_pending(other)) {
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt pending = true;
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt break;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!pending) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = manager_add_job(UNIT(n)->manager, JOB_START, UNIT_DEREF(n->service), JOB_REPLACE, true, &error, NULL);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (r < 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt goto fail;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt busname_set_state(n, BUSNAME_RUNNING);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktfail:
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_warning_unit(UNIT(n)->id, "%s failed to queue service startup job: %s", UNIT(n)->id, bus_error_message(&error, r));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic int busname_start(Unit *u) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt BusName *n = BUSNAME(u);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(n);
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* We cannot fulfill this request right now, try again later
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * please! */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL))
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return -EAGAIN;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* Already on it! */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (n->state == BUSNAME_MAKING)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return 0;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (n->activating && UNIT_ISSET(n->service)) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt Service *service;
356779df90a2ecab5da2cb310ad0f8ebc9ca9f46Lennart Poettering
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen service = SERVICE(UNIT_DEREF(n->service));
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen if (UNIT(service)->load_state != UNIT_LOADED) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_error_unit(u->id, "Bus service %s not loaded, refusing.", UNIT(service)->id);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return -ENOENT;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(IN_SET(n->state, BUSNAME_DEAD, BUSNAME_FAILED));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen n->result = BUSNAME_SUCCESS;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt busname_enter_making(n);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return 0;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic int busname_stop(Unit *u) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt BusName *n = BUSNAME(u);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(n);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen /* Already on it */
356779df90a2ecab5da2cb310ad0f8ebc9ca9f46Lennart Poettering if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL))
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen return 0;
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* If there's already something running, we go directly into
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * kill mode. */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (n->state == BUSNAME_MAKING) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_SUCCESS);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return -EAGAIN;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(IN_SET(n->state, BUSNAME_REGISTERED, BUSNAME_LISTENING, BUSNAME_RUNNING));
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen busname_enter_dead(n, BUSNAME_SUCCESS);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return 0;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt}
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flyktstatic int busname_serialize(Unit *u, FILE *f, FDSet *fds) {
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt BusName *n = BUSNAME(u);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen assert(n);
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen assert(f);
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen assert(fds);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt unit_serialize_item(u, f, "state", busname_state_to_string(n->state));
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt unit_serialize_item(u, f, "result", busname_result_to_string(n->result));
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (n->control_pid > 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unit_serialize_item_format(u, f, "control-pid", PID_FMT, n->control_pid);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (n->starter_fd >= 0) {
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek int copy;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt copy = fdset_put_dup(fds, n->starter_fd);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (copy < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return copy;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek unit_serialize_item_format(u, f, "starter-fd", "%i", copy);
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek }
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic int busname_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt BusName *n = BUSNAME(u);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(n);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(key);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(value);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams if (streq(key, "state")) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt BusNameState state;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt state = busname_state_from_string(value);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (state < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_debug_unit(u->id, "Failed to parse state value %s", value);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt n->deserialized_state = state;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt } else if (streq(key, "result")) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt BusNameResult f;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt f = busname_result_from_string(value);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (f < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_debug_unit(u->id, "Failed to parse result value %s", value);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else if (f != BUSNAME_SUCCESS)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt n->result = f;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt } else if (streq(key, "control-pid")) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt pid_t pid;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (parse_pid(value, &pid) < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt n->control_pid = pid;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt } else if (streq(key, "starter-fd")) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt int fd;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_debug_unit(u->id, "Failed to parse starter fd value %s", value);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt safe_close(n->starter_fd);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt n->starter_fd = fdset_remove(fds, fd);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt } else
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_debug_unit(u->id, "Unknown serialization key '%s'", key);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt_pure_ static UnitActiveState busname_active_state(Unit *u) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(u);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return state_translation_table[BUSNAME(u)->state];
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt_pure_ static const char *busname_sub_state_to_string(Unit *u) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(u);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return busname_state_to_string(BUSNAME(u)->state);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt}
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktstatic int busname_peek_message(BusName *n) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt struct kdbus_cmd_recv cmd_recv = {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt .flags = KDBUS_RECV_PEEK,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt };
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct kdbus_cmd_free cmd_free = {};
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt const char *comm = NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct kdbus_item *d;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct kdbus_msg *k;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt size_t start, ps, sz, delta;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt void *p = NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt pid_t pid = 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt int r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Generate a friendly debug log message about which process
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * caused triggering of this bus name. This simply peeks the
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * metadata of the first queued message and logs it. */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(n);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Let's shortcut things a bit, if debug logging is turned off
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt * anyway. */
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt if (log_get_max_level() < LOG_DEBUG)
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt return 0;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt r = ioctl(n->starter_fd, KDBUS_CMD_MSG_RECV, &cmd_recv);
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt if (r < 0) {
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt if (errno == EINTR || errno == EAGAIN)
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt return 0;
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt log_error_unit(UNIT(n)->id, "%s: Failed to query activation message: %m", UNIT(n)->id);
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt return -errno;
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt }
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt /* We map as late as possible, and unmap imemdiately after
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt * use. On 32bit address space is scarce and we want to be
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt * able to handle a lot of activator connections at the same
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt * time, and hence shouldn't keep the mmap()s around for
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt * longer than necessary. */
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt ps = page_size();
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt start = (cmd_recv.offset / ps) * ps;
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt delta = cmd_recv.offset - start;
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt sz = PAGE_ALIGN(delta + cmd_recv.msg_size);
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt p = mmap(NULL, sz, PROT_READ, MAP_SHARED, n->starter_fd, start);
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt if (p == MAP_FAILED) {
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt log_error_unit(UNIT(n)->id, "%s: Failed to map activation message: %m", UNIT(n)->id);
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt r = -errno;
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt goto finish;
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt }
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt k = (struct kdbus_msg *) ((uint8_t *) p + delta);
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt KDBUS_ITEM_FOREACH(d, k, items) {
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt switch (d->type) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt case KDBUS_ITEM_PIDS:
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt pid = d->pids.pid;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt break;
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt case KDBUS_ITEM_PID_COMM:
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt comm = d->str;
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt break;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (pid > 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_debug_unit(UNIT(n)->id, "%s: Activation triggered by process " PID_FMT " (%s)", UNIT(n)->id, pid, strna(comm));
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt r = 0;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktfinish:
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (p)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt (void) munmap(p, sz);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt cmd_free.offset = cmd_recv.offset;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (ioctl(n->starter_fd, KDBUS_CMD_FREE, &cmd_free) < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_warning_unit(UNIT(n)->id, "Failed to free peeked message, ignoring: %m");
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt BusName *n = userdata;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(n);
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt assert(fd >= 0);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (n->state != BUSNAME_LISTENING)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_debug_unit(UNIT(n)->id, "Activation request on %s", UNIT(n)->id);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (revents != EPOLLIN) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_error_unit(UNIT(n)->id, "%s: Got unexpected poll event (0x%x) on starter fd.",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt UNIT(n)->id, revents);
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt goto fail;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt }
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt busname_peek_message(n);
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt busname_enter_running(n);
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt return 0;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flyktfail:
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return 0;
5364f729ba9616cd9fdab8d5413fbc25a1af3a57Lennart Poettering}
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktstatic void busname_sigchld_event(Unit *u, pid_t pid, int code, int status) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt BusName *n = BUSNAME(u);
9d89d1ae71cb298218e35a69d6b70e2c94de5271Patrik Flykt BusNameResult f;
9d89d1ae71cb298218e35a69d6b70e2c94de5271Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(n);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(pid >= 0);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (pid != n->control_pid)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt n->control_pid = 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (is_clean_exit(code, status, NULL))
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt f = BUSNAME_SUCCESS;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else if (code == CLD_EXITED)
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt f = BUSNAME_FAILURE_EXIT_CODE;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else if (code == CLD_KILLED)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt f = BUSNAME_FAILURE_SIGNAL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else if (code == CLD_DUMPED)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt f = BUSNAME_FAILURE_CORE_DUMP;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert_not_reached("Unknown sigchld code");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_full_unit(f == BUSNAME_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt u->id, "%s control process exited, code=%s status=%i",
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt u->id, sigchld_code_to_string(code), status);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (f != BUSNAME_SUCCESS)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt n->result = f;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt switch (n->state) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt case BUSNAME_MAKING:
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (f == BUSNAME_SUCCESS)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_enter_listening(n);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_enter_signal(n, BUSNAME_SIGTERM, f);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt break;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt case BUSNAME_SIGTERM:
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt case BUSNAME_SIGKILL:
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_enter_dead(n, f);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt break;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt default:
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert_not_reached("Uh, control process died at wrong time.");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Notify clients about changed exit status */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unit_add_to_dbus_queue(u);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt BusName *n = BUSNAME(userdata);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(n);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(n->timer_event_source == source);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt switch (n->state) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt case BUSNAME_MAKING:
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_warning_unit(UNIT(n)->id, "%s making timed out. Terminating.", UNIT(n)->id);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_FAILURE_TIMEOUT);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt break;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
6ec60d20724d2a32e20d25ef75d2af178c242bc2Ronny Chevalier case BUSNAME_SIGTERM:
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_warning_unit(UNIT(n)->id, "%s stopping timed out. Killing.", UNIT(n)->id);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_FAILURE_TIMEOUT);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt break;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt case BUSNAME_SIGKILL:
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_warning_unit(UNIT(n)->id, "%s still around after SIGKILL. Ignoring.", UNIT(n)->id);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_enter_dead(n, BUSNAME_FAILURE_TIMEOUT);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt break;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt default:
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert_not_reached("Timeout at wrong time.");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic void busname_reset_failed(Unit *u) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt BusName *n = BUSNAME(u);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(n);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (n->state == BUSNAME_FAILED)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_set_state(n, BUSNAME_DEAD);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt n->result = BUSNAME_SUCCESS;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic void busname_trigger_notify(Unit *u, Unit *other) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt BusName *n = BUSNAME(u);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt Service *s;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(n);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt assert(other);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (!IN_SET(n->state, BUSNAME_RUNNING, BUSNAME_LISTENING))
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt s = SERVICE(other);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (s->state == SERVICE_FAILED && s->result == SERVICE_FAILURE_START_LIMIT)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt busname_enter_dead(n, BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else if (IN_SET(s->state,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt SERVICE_DEAD, SERVICE_FAILED,
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt SERVICE_AUTO_RESTART))
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt busname_enter_listening(n);
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flyktstatic int busname_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt return unit_kill_common(u, who, signo, -1, BUSNAME(u)->control_pid, error);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt}
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flyktstatic int busname_get_timeout(Unit *u, uint64_t *timeout) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt BusName *n = BUSNAME(u);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt int r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (!n->timer_event_source)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = sd_event_source_get_time(n->timer_event_source, timeout);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r < 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return 1;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic const char* const busname_state_table[_BUSNAME_STATE_MAX] = {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [BUSNAME_DEAD] = "dead",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [BUSNAME_MAKING] = "making",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [BUSNAME_REGISTERED] = "registered",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [BUSNAME_LISTENING] = "listening",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [BUSNAME_RUNNING] = "running",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [BUSNAME_SIGTERM] = "sigterm",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [BUSNAME_SIGKILL] = "sigkill",
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt [BUSNAME_FAILED] = "failed",
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt};
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik FlyktDEFINE_STRING_TABLE_LOOKUP(busname_state, BusNameState);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic const char* const busname_result_table[_BUSNAME_RESULT_MAX] = {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt [BUSNAME_SUCCESS] = "success",
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt [BUSNAME_FAILURE_RESOURCES] = "resources",
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt [BUSNAME_FAILURE_TIMEOUT] = "timeout",
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt [BUSNAME_FAILURE_EXIT_CODE] = "exit-code",
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt [BUSNAME_FAILURE_SIGNAL] = "signal",
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt [BUSNAME_FAILURE_CORE_DUMP] = "core-dump",
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt [BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent",
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt};
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik FlyktDEFINE_STRING_TABLE_LOOKUP(busname_result, BusNameResult);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flyktconst UnitVTable busname_vtable = {
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt .object_size = sizeof(BusName),
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt .sections =
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt "Unit\0"
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt "BusName\0"
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt "Install\0",
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt .private_section = "BusName",
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt .init = busname_init,
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt .done = busname_done,
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt .load = busname_load,
38a03f06a7393d2721c23f23f0589d2f6d0904afLennart Poettering
38a03f06a7393d2721c23f23f0589d2f6d0904afLennart Poettering .coldplug = busname_coldplug,
38a03f06a7393d2721c23f23f0589d2f6d0904afLennart Poettering
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt .dump = busname_dump,
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt .start = busname_start,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt .stop = busname_stop,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt .kill = busname_kill,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt .get_timeout = busname_get_timeout,
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt .serialize = busname_serialize,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt .deserialize_item = busname_deserialize_item,
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt .active_state = busname_active_state,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt .sub_state_to_string = busname_sub_state_to_string,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt .sigchld_event = busname_sigchld_event,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt .trigger_notify = busname_trigger_notify,
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt .reset_failed = busname_reset_failed,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt .bus_interface = "org.freedesktop.systemd1.BusName",
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt .bus_vtable = bus_busname_vtable,
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt .status_message_formats = {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt .finished_start_job = {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [JOB_DONE] = "Listening on %s.",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [JOB_FAILED] = "Failed to listen on %s.",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [JOB_DEPENDENCY] = "Dependency failed for %s.",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [JOB_TIMEOUT] = "Timed out starting %s.",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt },
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt .finished_stop_job = {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [JOB_DONE] = "Closed %s.",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [JOB_FAILED] = "Failed stopping %s.",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [JOB_TIMEOUT] = "Timed out stopping %s.",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt },
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt },
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt};
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt