Example #1
0
static int get_cgroup_root(char **ret) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
        _cleanup_free_ char *unit = NULL, *path = NULL;
        const char *m;
        int r;

        if (arg_root) {
                char *aux;

                aux = strdup(arg_root);
                if (!aux)
                        return log_oom();

                *ret = aux;
                return 0;
        }

        if (!arg_machine) {
                r = cg_get_root_path(ret);
                if (r < 0)
                        return log_error_errno(r, "Failed to get root control group path: %m");

                return 0;
        }

        m = strjoina("/run/systemd/machines/", arg_machine);
        r = parse_env_file(m, NEWLINE, "SCOPE", &unit, NULL);
        if (r < 0)
                return log_error_errno(r, "Failed to load machine data: %m");

        path = unit_dbus_path_from_name(unit);
        if (!path)
                return log_oom();

        r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
        if (r < 0)
                return log_error_errno(r, "Failed to create bus connection: %m");

        r = sd_bus_get_property_string(
                        bus,
                        "org.freedesktop.systemd1",
                        path,
                        unit_dbus_interface_from_name(unit),
                        "ControlGroup",
                        &error,
                        ret);
        if (r < 0)
                return log_error_errno(r, "Failed to query unit control group path: %s", bus_error_message(&error, r));

        return 0;
}
static int get_current_runlevel(Context *c) {
        static const struct {
                const int runlevel;
                const char *special;
        } table[] = {
                /* The first target of this list that is active or has
                 * a job scheduled wins. We prefer runlevels 5 and 3
                 * here over the others, since these are the main
                 * runlevels used on Fedora. It might make sense to
                 * change the order on some distributions. */
                { '5', SPECIAL_RUNLEVEL5_TARGET },
                { '3', SPECIAL_RUNLEVEL3_TARGET },
                { '4', SPECIAL_RUNLEVEL4_TARGET },
                { '2', SPECIAL_RUNLEVEL2_TARGET },
                { '1', SPECIAL_RESCUE_TARGET },
        };

        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;
        unsigned i;

        assert(c);

        for (i = 0; i < ELEMENTSOF(table); i++) {
                _cleanup_free_ char *state = NULL, *path = NULL;

                path = unit_dbus_path_from_name(table[i].special);
                if (!path)
                        return log_oom();

                r = sd_bus_get_property_string(
                                c->bus,
                                "org.freedesktop.systemd1",
                                path,
                                "org.freedesktop.systemd1.Unit",
                                "ActiveState",
                                &error,
                                &state);
                if (r < 0) {
                        log_warning("Failed to get state: %s", bus_error_message(&error, -r));
                        return r;
                }

                if (streq(state, "active") || streq(state, "reloading"))
                        return table[i].runlevel;
        }

        return 0;
}