static int busname_make_starter(BusName *n, pid_t *_pid) {
        pid_t pid;
        int r;

        r = busname_arm_timer(n);
        if (r < 0)
                goto fail;

        /* We have to resolve the user/group names out-of-process,
         * hence let's fork here. It's messy, but well, what can we
         * do? */

        pid = fork();
        if (pid < 0)
                return -errno;

        if (pid == 0) {
                int ret;

                default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1);
                ignore_signals(SIGPIPE, -1);
                log_forget_fds();

                r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, n->policy, n->policy_world);
                if (r < 0) {
                        ret = EXIT_MAKE_STARTER;
                        goto fail_child;
                }

                _exit(0);

        fail_child:
                log_open();
                log_error_errno(r, "Failed to create starter connection at step %s: %m", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD));

                _exit(ret);
        }

        r = unit_watch_pid(UNIT(n), pid);
        if (r < 0)
                goto fail;

        *_pid = pid;
        return 0;

fail:
        n->timer_event_source = sd_event_source_unref(n->timer_event_source);
        return r;
}
static void busname_enter_signal(BusName *n, BusNameState state, BusNameResult f) {
        KillContext kill_context = {};
        int r;

        assert(n);

        if (f != BUSNAME_SUCCESS)
                n->result = f;

        kill_context_init(&kill_context);

        r = unit_kill_context(UNIT(n),
                              &kill_context,
                              state != BUSNAME_SIGTERM ? KILL_KILL : KILL_TERMINATE,
                              -1,
                              n->control_pid,
                              false);
        if (r < 0) {
                log_unit_warning_errno(UNIT(n)->id, r, "%s failed to kill control process: %m", UNIT(n)->id);
                goto fail;
        }

        if (r > 0) {
                r = busname_arm_timer(n);
                if (r < 0) {
                        log_unit_warning_errno(UNIT(n)->id, r, "%s failed to arm timer: %m", UNIT(n)->id);
                        goto fail;
                }

                busname_set_state(n, state);
        } else if (state == BUSNAME_SIGTERM)
                busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_SUCCESS);
        else
                busname_enter_dead(n, BUSNAME_SUCCESS);

        return;

fail:
        busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
}
static int busname_coldplug(Unit *u, Hashmap *deferred_work) {
        BusName *n = BUSNAME(u);
        int r;

        assert(n);
        assert(n->state == BUSNAME_DEAD);

        if (n->deserialized_state == n->state)
                return 0;

        if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {

                if (n->control_pid <= 0)
                        return -EBADMSG;

                r = unit_watch_pid(UNIT(n), n->control_pid);
                if (r < 0)
                        return r;

                r = busname_arm_timer(n);
                if (r < 0)
                        return r;
        }

        if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING)) {
                r = busname_open_fd(n);
                if (r < 0)
                        return r;
        }

        if (n->deserialized_state == BUSNAME_LISTENING) {
                r = busname_watch_fd(n);
                if (r < 0)
                        return r;
        }

        busname_set_state(n, n->deserialized_state);
        return 0;
}
Exemple #4
0
static int busname_coldplug(Unit *u) {
        BusName *n = BUSNAME(u);
        int r;

        assert(n);
        assert(n->state == BUSNAME_DEAD);

        if (n->deserialized_state == n->state)
                return 0;

        if (n->control_pid > 0 &&
            pid_is_unwaited(n->control_pid) &&
            IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {

                r = unit_watch_pid(UNIT(n), n->control_pid);
                if (r < 0)
                        return r;

                r = busname_arm_timer(n, usec_add(u->state_change_timestamp.monotonic, n->timeout_usec));
                if (r < 0)
                        return r;
        }

        if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING)) {
                r = busname_open_fd(n);
                if (r < 0)
                        return r;
        }

        if (n->deserialized_state == BUSNAME_LISTENING) {
                r = busname_watch_fd(n);
                if (r < 0)
                        return r;
        }

        busname_set_state(n, n->deserialized_state);
        return 0;
}