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; /* First, if we are not closing yet, initiate stopping */ if (!machine_check_gc(machine, drop_not_started) && machine_get_state(machine) != MACHINE_CLOSING) machine_stop(machine); /* Now, the stop stop probably made this referenced * again, but if it didn't, then it's time to let it * go entirely. */ if (!machine_check_gc(machine, drop_not_started)) { machine_finalize(machine); machine_free(machine); } } }
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)) { machine_stop(machine); machine_free(machine); } } }
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); } } }