示例#1
0
int main(int argc, char *argv[]) {
        int r, exit_code = 0;
        DBusConnection *bus = NULL;
        DBusError error;
        _cleanup_close_ int fd = -1;

        dbus_error_init(&error);

        log_parse_environment();
        log_open();

        r = parse_argv(argc, argv);
        if (r <= 0)
                goto finish;

        bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
        if (!bus) {
                log_error("Failed to connect to bus: %s", bus_error_message(&error));
                r = -EIO;
                goto finish;
        }

        if (arg_action == ACTION_LIST) {

                r = print_inhibitors(bus, &error);
                if (r < 0) {
                        log_error("Failed to list inhibitors: %s", bus_error(&error, r));
                        goto finish;
                }

        } else {
                char *w = NULL;
                pid_t pid;

                if (!arg_who)
                        arg_who = w = strv_join(argv + optind, " ");

                fd = inhibit(bus, &error);
                free(w);

                if (fd < 0) {
                        log_error("Failed to inhibit: %s", bus_error(&error, r));
                        r = fd;
                        goto finish;
                }

                pid = fork();
                if (pid < 0) {
                        log_error("Failed to fork: %m");
                        r = -errno;
                        goto finish;
                }

                if (pid == 0) {
                        /* Child */

                        safe_close(fd);
                        close_all_fds(NULL, 0);

                        execvp(argv[optind], argv + optind);
                        log_error("Failed to execute %s: %m", argv[optind]);
                        _exit(EXIT_FAILURE);
                }

                r = wait_for_terminate_and_warn(argv[optind], pid);
                if (r >= 0)
                        exit_code = r;
        }

finish:
        if (bus) {
                dbus_connection_close(bus);
                dbus_connection_unref(bus);
        }

        dbus_error_free(&error);

        return r < 0 ? EXIT_FAILURE : exit_code;
}
示例#2
0
static int manager_connect_bus(Manager *m) {
        DBusError error;
        int r;
        struct epoll_event ev = {
                .events = EPOLLIN,
                .data.u32 = FD_BUS,
        };

        assert(m);
        assert(!m->bus);
        assert(m->bus_fd < 0);

        dbus_error_init(&error);

        m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
        if (!m->bus) {
                log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
                r = -ECONNREFUSED;
                goto fail;
        }

        if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/machine1", &bus_manager_vtable, m) ||
            !dbus_connection_register_fallback(m->bus, "/org/freedesktop/machine1/machine", &bus_machine_vtable, m) ||
            !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
                r = log_oom();
                goto fail;
        }

        dbus_bus_add_match(m->bus,
                           "type='signal',"
                           "sender='org.freedesktop.systemd1',"
                           "interface='org.freedesktop.systemd1.Manager',"
                           "member='JobRemoved',"
                           "path='/org/freedesktop/systemd1'",
                           &error);
        if (dbus_error_is_set(&error)) {
                log_error("Failed to add match for JobRemoved: %s", bus_error_message(&error));
                dbus_error_free(&error);
        }

        dbus_bus_add_match(m->bus,
                           "type='signal',"
                           "sender='org.freedesktop.systemd1',"
                           "interface='org.freedesktop.systemd1.Manager',"
                           "member='UnitRemoved',"
                           "path='/org/freedesktop/systemd1'",
                           &error);
        if (dbus_error_is_set(&error)) {
                log_error("Failed to add match for UnitRemoved: %s", bus_error_message(&error));
                dbus_error_free(&error);
        }

        dbus_bus_add_match(m->bus,
                           "type='signal',"
                           "sender='org.freedesktop.systemd1',"
                           "interface='org.freedesktop.DBus.Properties',"
                           "member='PropertiesChanged'",
                           &error);
        if (dbus_error_is_set(&error)) {
                log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error));
                dbus_error_free(&error);
        }

        dbus_bus_add_match(m->bus,
                           "type='signal',"
                           "sender='org.freedesktop.systemd1',"
                           "interface='org.freedesktop.systemd1.Manager',"
                           "member='Reloading',"
                           "path='/org/freedesktop/systemd1'",
                           &error);
        if (dbus_error_is_set(&error)) {
                log_error("Failed to add match for Reloading: %s", bus_error_message(&error));
                dbus_error_free(&error);
        }

        r = bus_method_call_with_reply(
                        m->bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        "org.freedesktop.systemd1.Manager",
                        "Subscribe",
                        NULL,
                        &error,
                        DBUS_TYPE_INVALID);
        if (r < 0) {
                log_error("Failed to enable subscription: %s", bus_error(&error, r));
                dbus_error_free(&error);
        }

        r = dbus_bus_request_name(m->bus, "org.freedesktop.machine1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
        if (dbus_error_is_set(&error)) {
                log_error("Failed to register name on bus: %s", bus_error_message(&error));
                r = -EIO;
                goto fail;
        }

        if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
                log_error("Failed to acquire name.");
                r = -EEXIST;
                goto fail;
        }

        m->bus_fd = bus_loop_open(m->bus);
        if (m->bus_fd < 0) {
                r = m->bus_fd;
                goto fail;
        }

        if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
                goto fail;

        return 0;

fail:
        dbus_error_free(&error);

        return r;
}

void manager_gc(Manager *m, bool drop_not_started) {
        Machine *machine;

        assert(m);

        while ((machine = m->machine_gc_queue)) {
                LIST_REMOVE(gc_queue, m->machine_gc_queue, machine);
                machine->in_gc_queue = false;

                if (machine_check_gc(machine, drop_not_started) == 0) {
                        machine_stop(machine);
                        machine_free(machine);
                }
        }
}