static int slice_add_parent_slice(Slice *s) { char *a, *dash; Unit *parent; int r; assert(s); if (UNIT_ISSET(UNIT(s)->slice)) return 0; if (unit_has_name(UNIT(s), SPECIAL_ROOT_SLICE)) return 0; a = strdupa(UNIT(s)->id); dash = strrchr(a, '-'); if (dash) strcpy(dash, ".slice"); else a = (char*) SPECIAL_ROOT_SLICE; r = manager_load_unit(UNIT(s)->manager, a, NULL, NULL, &parent); if (r < 0) return r; unit_ref_set(&UNIT(s)->slice, parent); return 0; }
static int slice_verify(Slice *s) { _cleanup_free_ char *parent = NULL; int r; assert(s); if (UNIT(s)->load_state != UNIT_LOADED) return 0; if (!slice_name_is_valid(UNIT(s)->id)) { log_unit_error(UNIT(s), "Slice name %s is not valid. Refusing.", UNIT(s)->id); return -EINVAL; } r = slice_build_parent_slice(UNIT(s)->id, &parent); if (r < 0) return log_unit_error_errno(UNIT(s), r, "Failed to determine parent slice: %m"); if (parent ? !unit_has_name(UNIT_DEREF(UNIT(s)->slice), parent) : UNIT_ISSET(UNIT(s)->slice)) { log_unit_error(UNIT(s), "Located outside of parent slice. Refusing."); return -EINVAL; } return 0; }
static int busname_start(Unit *u) { BusName *n = BUSNAME(u); assert(n); /* We cannot fulfill this request right now, try again later * please! */ if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) return -EAGAIN; /* Already on it! */ if (n->state == BUSNAME_MAKING) return 0; if (n->activating && UNIT_ISSET(n->service)) { Service *service; service = SERVICE(UNIT_DEREF(n->service)); if (UNIT(service)->load_state != UNIT_LOADED) { log_unit_error(u->id, "Bus service %s not loaded, refusing.", UNIT(service)->id); return -ENOENT; } } assert(IN_SET(n->state, BUSNAME_DEAD, BUSNAME_FAILED)); n->result = BUSNAME_SUCCESS; busname_enter_making(n); return 1; }
static void busname_enter_running(BusName *n) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; bool pending = false; Unit *other; Iterator i; int r; assert(n); if (!n->activating) return; /* We don't take connections anymore if we are supposed to * shut down anyway */ if (unit_stop_pending(UNIT(n))) { log_unit_debug(UNIT(n), "Suppressing activation request since unit stop is scheduled."); /* Flush all queued activation reqeuest by closing and reopening the connection */ bus_kernel_drop_one(n->starter_fd); busname_enter_listening(n); return; } /* If there's already a start pending don't bother to do * anything */ SET_FOREACH(other, UNIT(n)->dependencies[UNIT_TRIGGERS], i) if (unit_active_or_pending(other)) { pending = true; break; } if (!pending) { if (!UNIT_ISSET(n->service)) { log_unit_error(UNIT(n), "Service to activate vanished, refusing activation."); r = -ENOENT; goto fail; } r = manager_add_job(UNIT(n)->manager, JOB_START, UNIT_DEREF(n->service), JOB_REPLACE, &error, NULL); if (r < 0) goto fail; } busname_set_state(n, BUSNAME_RUNNING); return; fail: log_unit_warning(UNIT(n), "Failed to queue service startup job: %s", bus_error_message(&error, r)); busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES); }