#include <sys/epoll.h>
#include "sd-daemon.h"
-
#include "strv.h"
#include "conf-parser.h"
#include "cgroup-util.h"
#include "mkdir.h"
#include "bus-util.h"
#include "bus-error.h"
+#include "label.h"
+#include "machine-image.h"
#include "machined.h"
Manager *manager_new(void) {
if (!m)
return NULL;
- m->machines = hashmap_new(string_hash_func, string_compare_func);
- m->machine_units = hashmap_new(string_hash_func, string_compare_func);
- m->machine_leaders = hashmap_new(trivial_hash_func, trivial_compare_func);
+ m->machines = hashmap_new(&string_hash_ops);
+ m->machine_units = hashmap_new(&string_hash_ops);
+ m->machine_leaders = hashmap_new(NULL);
if (!m->machines || !m->machine_units || !m->machine_leaders) {
manager_free(m);
return NULL;
}
+ sd_event_set_watchdog(m->event, true);
+
return m;
}
void manager_free(Manager *m) {
Machine *machine;
+ Image *i;
assert(m);
hashmap_free(m->machine_units);
hashmap_free(m->machine_leaders);
+ while ((i = hashmap_steal_first(m->image_cache)))
+ image_unref(i);
+
+ hashmap_free(m->image_cache);
+
+ sd_event_source_unref(m->image_cache_defer_event);
+
+ bus_verify_polkit_async_registry_free(m->polkit_registry);
+
sd_bus_unref(m->bus);
sd_event_unref(m->event);
if (errno == ENOENT)
return 0;
- log_error("Failed to open /run/systemd/machines: %m");
+ log_error_errno(errno, "Failed to open /run/systemd/machines: %m");
return -errno;
}
if (!dirent_is_file(de))
continue;
+ /* Ignore symlinks that map the unit name to the machine */
+ if (startswith(de->d_name, "unit:"))
+ continue;
+
k = manager_add_machine(m, de->d_name, &machine);
if (k < 0) {
- log_error("Failed to add machine by file name %s: %s", de->d_name, strerror(-k));
+ log_error_errno(k, "Failed to add machine by file name %s: %m", de->d_name);
r = k;
continue;
assert(!m->bus);
r = sd_bus_default_system(&m->bus);
- if (r < 0) {
- log_error("Failed to connect to system bus: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to system bus: %m");
- r = sd_bus_add_object_vtable(m->bus, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m);
- if (r < 0) {
- log_error("Failed to add manager object vtable: %s", strerror(-r));
- return r;
- }
+ r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add manager object vtable: %m");
- r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m);
- if (r < 0) {
- log_error("Failed to add machine object vtable: %s", strerror(-r));
- return r;
- }
+ r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add machine object vtable: %m");
- r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/machine1/machine", machine_node_enumerator, m);
- if (r < 0) {
- log_error("Failed to add machine enumerator: %s", strerror(-r));
- return r;
- }
+ r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/machine", machine_node_enumerator, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add machine enumerator: %m");
+
+ r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/image", "org.freedesktop.machine1.Image", image_vtable, image_object_find, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add image object vtable: %m");
+
+ r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/image", image_node_enumerator, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add image enumerator: %m");
r = sd_bus_add_match(m->bus,
+ NULL,
"type='signal',"
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'",
match_job_removed,
m);
- if (r < 0) {
- log_error("Failed to add match for JobRemoved: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to add match for JobRemoved: %m");
r = sd_bus_add_match(m->bus,
+ NULL,
"type='signal',"
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'",
match_unit_removed,
m);
- if (r < 0) {
- log_error("Failed to add match for UnitRemoved: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to add match for UnitRemoved: %m");
r = sd_bus_add_match(m->bus,
+ NULL,
"type='signal',"
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.DBus.Properties',"
"member='PropertiesChanged'",
match_properties_changed,
m);
- if (r < 0) {
- log_error("Failed to add match for PropertiesChanged: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to add match for PropertiesChanged: %m");
r = sd_bus_add_match(m->bus,
+ NULL,
"type='signal',"
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'",
match_reloading,
m);
- if (r < 0) {
- log_error("Failed to add match for Reloading: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to add match for Reloading: %m");
r = sd_bus_call_method(
m->bus,
return r;
}
- r = sd_bus_request_name(m->bus, "org.freedesktop.machine1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_DO_NOT_QUEUE);
- if (r < 0) {
- log_error("Failed to register name: %s", strerror(-r));
- return r;
- }
+ r = sd_bus_request_name(m->bus, "org.freedesktop.machine1", 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to register name: %m");
r = sd_bus_attach_event(m->bus, m->event, 0);
- if (r < 0) {
- log_error("Failed to attach bus to event loop: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach bus to event loop: %m");
return 0;
}
return 0;
}
-int manager_run(Manager *m) {
- int r;
-
- assert(m);
+static bool check_idle(void *userdata) {
+ Manager *m = userdata;
- for (;;) {
- r = sd_event_get_state(m->event);
- if (r < 0)
- return r;
- if (r == SD_EVENT_FINISHED)
- return 0;
+ manager_gc(m, true);
- manager_gc(m, true);
+ return hashmap_isempty(m->machines);
+}
- r = sd_event_run(m->event, (uint64_t) -1);
- if (r < 0)
- return r;
- }
+int manager_run(Manager *m) {
+ assert(m);
- return 0;
+ return bus_event_loop_with_idle(
+ m->event,
+ m->bus,
+ "org.freedesktop.machine1",
+ DEFAULT_EXIT_USEC,
+ check_idle, m);
}
int main(int argc, char *argv[]) {
r = manager_startup(m);
if (r < 0) {
- log_error("Failed to fully start up daemon: %s", strerror(-r));
+ log_error_errno(r, "Failed to fully start up daemon: %m");
goto finish;
}
- log_debug("systemd-machined running as pid %lu", (unsigned long) getpid());
+ log_debug("systemd-machined running as pid "PID_FMT, getpid());
sd_notify(false,
"READY=1\n"
r = manager_run(m);
- log_debug("systemd-machined stopped as pid %lu", (unsigned long) getpid());
+ log_debug("systemd-machined stopped as pid "PID_FMT, getpid());
finish:
- sd_notify(false,
- "STATUS=Shutting down...");
-
if (m)
manager_free(m);