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 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; }
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; }
static int bus_scope_set_transient_property( Scope *s, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error) { int r; assert(s); assert(name); assert(message); if (streq(name, "PIDs")) { unsigned n = 0; uint32_t pid; r = sd_bus_message_enter_container(message, 'a', "u"); if (r < 0) return r; while ((r = sd_bus_message_read(message, "u", &pid)) > 0) { if (pid <= 1) return -EINVAL; if (mode != UNIT_CHECK) { r = unit_watch_pid(UNIT(s), pid); if (r < 0 && r != -EEXIST) return r; } n++; } if (r < 0) return r; r = sd_bus_message_exit_container(message); if (r < 0) return r; if (n <= 0) return -EINVAL; return 1; } else if (streq(name, "Controller")) { const char *controller; char *c; r = sd_bus_message_read(message, "s", &controller); if (r < 0) return r; if (!isempty(controller) && !service_name_is_valid(controller)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller); if (mode != UNIT_CHECK) { if (isempty(controller)) c = NULL; else { c = strdup(controller); if (!c) return -ENOMEM; } free(s->controller); s->controller = c; } return 1; } else if (streq(name, "TimeoutStopUSec")) { if (mode != UNIT_CHECK) { r = sd_bus_message_read(message, "t", &s->timeout_stop_usec); if (r < 0) return r; unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nTimeoutStopSec=%lluus\n", (unsigned long long) s->timeout_stop_usec); } else { r = sd_bus_message_skip(message, "t"); if (r < 0) return r; } return 1; } return 0; }
static int bus_scope_set_transient_property( Scope *s, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) { int r; assert(s); assert(name); assert(message); flags |= UNIT_PRIVATE; if (streq(name, "TimeoutStopUSec")) return bus_set_transient_usec(UNIT(s), name, &s->timeout_stop_usec, message, flags, error); if (streq(name, "PIDs")) { _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; unsigned n = 0; r = sd_bus_message_enter_container(message, 'a', "u"); if (r < 0) return r; for (;;) { uint32_t upid; pid_t pid; r = sd_bus_message_read(message, "u", &upid); if (r < 0) return r; if (r == 0) break; if (upid == 0) { if (!creds) { r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds); if (r < 0) return r; } r = sd_bus_creds_get_pid(creds, &pid); if (r < 0) return r; } else pid = (uid_t) upid; r = unit_pid_attachable(UNIT(s), pid, error); if (r < 0) return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = unit_watch_pid(UNIT(s), pid); if (r < 0 && r != -EEXIST) return r; } n++; } r = sd_bus_message_exit_container(message); if (r < 0) return r; if (n <= 0) return -EINVAL; return 1; } else if (streq(name, "Controller")) { const char *controller; /* We can't support direct connections with this, as direct connections know no service or unique name * concept, but the Controller field stores exactly that. */ if (sd_bus_message_get_bus(message) != UNIT(s)->manager->api_bus) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Sorry, Controller= logic only supported via the bus."); r = sd_bus_message_read(message, "s", &controller); if (r < 0) return r; if (!isempty(controller) && !service_name_is_valid(controller)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller); if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = free_and_strdup(&s->controller, empty_to_null(controller)); if (r < 0) return r; } return 1; } return 0; }