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