busname.c revision a9c8343e83ec09f80a76930573b2592f97ae4283
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2013 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poetteringstatic const UnitActiveState state_translation_table[_BUSNAME_STATE_MAX] = {
3c0cf502796be355431d4a64d738e75f543aa51dLennart Poetteringstatic int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poetteringstatic int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering n->timeout_usec = u->manager->default_timeout_start_usec;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void busname_unwatch_control_pid(BusName *n) {
if (n->control_pid <= 0)
n->control_pid = 0;
BusNamePolicy *p;
assert(n);
while ((p = n->policy)) {
free(p);
assert(n);
assert(n);
busname_close_fd(n);
assert(n);
if (n->timeout_usec <= 0) {
if (n->timer_event_source) {
return sd_event_add_time(
&n->timer_event_source,
assert(n);
r = unit_add_two_dependencies_by_name(UNIT(n), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
return unit_add_two_dependencies_by_name(UNIT(n), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
assert(n);
if (!n->name) {
if (!n->name)
return -ENOMEM;
if (!u->description) {
if (n->activating) {
Unit *x;
if (u->default_dependencies) {
assert(n);
log_unit_error(UNIT(n)->id, "%s's Name= setting is not a valid service name Refusing.", UNIT(n)->id);
return -EINVAL;
return -EINVAL;
assert(u);
r = unit_load_fragment_and_dropin(u);
r = busname_add_extras(n);
return busname_verify(n);
assert(n);
assert(f);
fprintf(f,
if (n->control_pid > 0)
fprintf(f,
assert(n);
if (!n->starter_event_source)
assert(n);
if (n->starter_fd < 0)
if (n->starter_event_source)
r = sd_event_add_io(UNIT(n)->manager->event, &n->starter_event_source, n->starter_fd, EPOLLIN, busname_dispatch_io, n);
const char *mode;
assert(n);
if (n->starter_fd >= 0)
if (n->starter_fd < 0)
return log_unit_warning_errno(UNIT(n)->id, n->starter_fd, "Failed to open %s: %m", path ?: "kdbus");
assert(n);
busname_close_fd(n);
assert(n);
if (n->control_pid <= 0)
return -EBADMSG;
r = busname_arm_timer(n);
if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING)) {
r = busname_open_fd(n);
r = busname_watch_fd(n);
r = busname_arm_timer(n);
goto fail;
if (pid < 0)
return -errno;
if (pid == 0) {
int ret;
r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, n->policy, n->policy_world);
goto fail_child;
_exit(0);
log_open();
log_error_errno(r, "Failed to create starter connection at step %s: %m", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD));
goto fail;
fail:
assert(n);
if (f != BUSNAME_SUCCESS)
n->result = f;
assert(n);
if (f != BUSNAME_SUCCESS)
n->result = f;
n->control_pid,
goto fail;
r = busname_arm_timer(n);
goto fail;
fail:
assert(n);
if (n->activating) {
r = busname_watch_fd(n);
goto fail;
fail:
assert(n);
r = busname_open_fd(n);
goto fail;
if (n->policy) {
goto fail;
r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, NULL, n->policy_world);
goto fail;
fail:
bool pending = false;
Iterator i;
assert(n);
if (!n->activating)
log_unit_debug(UNIT(n)->id, "Suppressing activation request on %s since unit stop is scheduled.", UNIT(n)->id);
pending = true;
if (!pending) {
r = manager_add_job(UNIT(n)->manager, JOB_START, UNIT_DEREF(n->service), JOB_REPLACE, true, &error, NULL);
goto fail;
fail:
log_unit_warning(UNIT(n)->id, "%s failed to queue service startup job: %s", UNIT(n)->id, bus_error_message(&error, r));
assert(n);
return -EAGAIN;
return -ENOENT;
assert(n);
return -EAGAIN;
assert(n);
assert(f);
if (n->control_pid > 0)
if (n->starter_fd >= 0) {
int copy;
if (copy < 0)
return copy;
assert(n);
if (state < 0)
else if (f != BUSNAME_SUCCESS)
n->result = f;
int fd;
assert(u);
assert(u);
struct kdbus_item *d;
struct kdbus_msg *k;
void *p = NULL;
assert(n);
return -errno;
if (p == MAP_FAILED) {
r = -errno;
goto finish;
switch (d->type) {
case KDBUS_ITEM_PIDS:
case KDBUS_ITEM_PID_COMM:
if (pid > 0)
log_unit_debug(UNIT(n)->id, "%s: Activation triggered by process " PID_FMT " (%s)", UNIT(n)->id, pid, strna(comm));
assert(n);
goto fail;
fail:
assert(n);
n->control_pid = 0;
f = BUSNAME_SUCCESS;
if (f != BUSNAME_SUCCESS)
n->result = f;
switch (n->state) {
case BUSNAME_MAKING:
if (f == BUSNAME_SUCCESS)
case BUSNAME_SIGTERM:
case BUSNAME_SIGKILL:
busname_enter_dead(n, f);
assert(n);
switch (n->state) {
case BUSNAME_MAKING:
case BUSNAME_SIGTERM:
case BUSNAME_SIGKILL:
assert(n);
Service *s;
assert(n);
if (!n->timer_event_source)
assert(m);
if (supported < 0)
return supported;
.sections =
.finished_start_job = {
.finished_stop_job = {