Esempio n. 1
0
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;
}
Esempio n. 2
0
int scope_abandon(Scope *s) {
        assert(s);

        if (unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE))
                return -EPERM;

        if (!IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED))
                return -ESTALE;

        s->controller = mfree(s->controller);

        /* The client is no longer watching the remaining processes,
         * so let's step in here, under the assumption that the
         * remaining processes will be sooner or later reassigned to
         * us as parent. */

        unit_tidy_watch_pids(UNIT(s), 0, 0);
        unit_watch_all_pids(UNIT(s));

        /* If the PID set is empty now, then let's finish this off */
        if (set_isempty(UNIT(s)->pids))
                scope_notify_cgroup_empty_event(UNIT(s));
        else
                scope_set_state(s, SCOPE_ABANDONED);

        return 0;
}
Esempio n. 3
0
static int slice_verify(Slice *s) {
        assert(s);

        if (UNIT(s)->load_state != UNIT_LOADED)
                return 0;

        if (UNIT_DEREF(UNIT(s)->slice)) {
                char *a, *dash;

                a = strdupa(UNIT(s)->id);
                dash = strrchr(a, '-');
                if (dash)
                        strcpy(dash, ".slice");
                else
                        a = (char*) SPECIAL_ROOT_SLICE;

                if (!unit_has_name(UNIT_DEREF(UNIT(s)->slice), a)) {
                        log_unit_error(UNIT(s)->id,
                                       "%s located outside its parent slice. Refusing.", UNIT(s)->id);
                        return -EINVAL;
                }
        }

        return 0;
}
Esempio n. 4
0
static int automount_verify(Automount *a) {
        bool b;
        char *e;
        assert(a);

        if (UNIT(a)->load_state != UNIT_LOADED)
                return 0;

        if (path_equal(a->where, "/")) {
                log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
                return -EINVAL;
        }

        e = unit_name_from_path(a->where, ".automount");
        if (!e)
                return -ENOMEM;

        b = unit_has_name(UNIT(a), e);
        free(e);

        if (!b) {
                log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
                return -EINVAL;
        }

        return 0;
}
Esempio n. 5
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;
}
Esempio n. 6
0
static int automount_verify(Automount *a) {
        _cleanup_free_ char *e = NULL;
        int r;

        assert(a);

        if (UNIT(a)->load_state != UNIT_LOADED)
                return 0;

        if (path_equal(a->where, "/")) {
                log_unit_error(UNIT(a), "Cannot have an automount unit for the root directory. Refusing.");
                return -EINVAL;
        }

        r = unit_name_from_path(a->where, ".automount", &e);
        if (r < 0)
                return log_unit_error(UNIT(a), "Failed to generate unit name from path: %m");

        if (!unit_has_name(UNIT(a), e)) {
                log_unit_error(UNIT(a), "Where= setting doesn't match unit name. Refusing.");
                return -EINVAL;
        }

        return 0;
}
Esempio n. 7
0
static int scope_verify(Scope *s) {
        assert(s);

        if (UNIT(s)->load_state != UNIT_LOADED)
                return 0;

        if (set_isempty(UNIT(s)->pids) &&
            !MANAGER_IS_RELOADING(UNIT(s)->manager) &&
            !unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE)) {
                log_unit_error(UNIT(s), "Scope has no PIDs. Refusing.");
                return -ENOENT;
        }

        return 0;
}
Esempio n. 8
0
static int scope_verify(Scope *s) {
        assert(s);

        if (UNIT(s)->load_state != UNIT_LOADED)
                return 0;

        if (set_isempty(UNIT(s)->pids) &&
            !manager_is_reloading_or_reexecuting(UNIT(s)->manager) &&
            !unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE)) {
                log_unit_error(UNIT(s), "Scope has no PIDs. Refusing.");
                return -EINVAL;
        }

        return 0;
}
Esempio n. 9
0
static int scope_start(Unit *u) {
        Scope *s = SCOPE(u);
        int r;

        assert(s);

        if (unit_has_name(u, SPECIAL_INIT_SCOPE))
                return -EPERM;

        if (s->state == SCOPE_FAILED)
                return -EPERM;

        /* We can't fulfill this right now, please try again later */
        if (IN_SET(s->state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
                return -EAGAIN;

        assert(s->state == SCOPE_DEAD);

        if (!u->transient && !MANAGER_IS_RELOADING(u->manager))
                return -ENOENT;

        (void) bus_scope_track_controller(s);

        r = unit_acquire_invocation_id(u);
        if (r < 0)
                return r;

        (void) unit_realize_cgroup(u);
        (void) unit_reset_cpu_accounting(u);
        (void) unit_reset_ip_accounting(u);

        unit_export_state_files(UNIT(s));

        r = unit_attach_pids_to_cgroup(u, UNIT(s)->pids, NULL);
        if (r < 0) {
                log_unit_warning_errno(UNIT(s), r, "Failed to add PIDs to scope's control group: %m");
                scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
                return r;
        }

        s->result = SCOPE_SUCCESS;

        scope_set_state(s, SCOPE_RUNNING);

        /* Start watching the PIDs currently in the scope */
        (void) unit_enqueue_rewatch_pids(UNIT(s));
        return 1;
}
static int busname_verify(BusName *n) {
        char *e;

        assert(n);

        if (UNIT(n)->load_state != UNIT_LOADED)
                return 0;

        if (!service_name_is_valid(n->name)) {
                log_unit_error(UNIT(n)->id, "%s's Name= setting is not a valid service name Refusing.", UNIT(n)->id);
                return -EINVAL;
        }

        e = strjoina(n->name, ".busname");
        if (!unit_has_name(UNIT(n), e)) {
                log_unit_error(UNIT(n)->id, "%s's Name= setting doesn't match unit name. Refusing.", UNIT(n)->id);
                return -EINVAL;
        }

        return 0;
}
Esempio n. 11
0
int scope_abandon(Scope *s) {
        assert(s);

        if (unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE))
                return -EPERM;

        if (!IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED))
                return -ESTALE;

        s->was_abandoned = true;

        s->controller = mfree(s->controller);
        s->controller_track = sd_bus_track_unref(s->controller_track);

        scope_set_state(s, SCOPE_ABANDONED);

        /* The client is no longer watching the remaining processes, so let's step in here, under the assumption that
         * the remaining processes will be sooner or later reassigned to us as parent. */
        (void) unit_enqueue_rewatch_pids(UNIT(s));

        return 0;
}
Esempio n. 12
0
static int scope_load_init_scope(Unit *u) {
        assert(u);

        if (!unit_has_name(u, SPECIAL_INIT_SCOPE))
                return 0;

        u->transient = true;
        u->perpetual = true;

        /* init.scope is a bit special, as it has to stick around forever. Because of its special semantics we
         * synthesize it here, instead of relying on the unit file on disk. */

        u->default_dependencies = false;

        /* Prettify things, if we can. */
        if (!u->description)
                u->description = strdup("System and Service Manager");
        if (!u->documentation)
                (void) strv_extend(&u->documentation, "man:systemd(1)");

        return 1;
}
Esempio n. 13
0
static int scope_start(Unit *u) {
        Scope *s = SCOPE(u);
        int r;

        assert(s);

        if (unit_has_name(u, SPECIAL_INIT_SCOPE))
                return -EPERM;

        if (s->state == SCOPE_FAILED)
                return -EPERM;

        /* We can't fulfill this right now, please try again later */
        if (s->state == SCOPE_STOP_SIGTERM ||
            s->state == SCOPE_STOP_SIGKILL)
                return -EAGAIN;

        assert(s->state == SCOPE_DEAD);

        if (!u->transient && !manager_is_reloading_or_reexecuting(u->manager))
                return -ENOENT;

        (void) unit_realize_cgroup(u);
        (void) unit_reset_cpu_usage(u);

        r = unit_attach_pids_to_cgroup(u);
        if (r < 0) {
                log_unit_warning_errno(UNIT(s), r, "Failed to add PIDs to scope's control group: %m");
                scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
                return r;
        }

        s->result = SCOPE_SUCCESS;

        scope_set_state(s, SCOPE_RUNNING);
        return 1;
}