machined.c revision 4afd3348c7506dd1d36305b7bcb9feb8952b9d6b
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2013 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <string.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <unistd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "sd-daemon.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "alloc-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "bus-error.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "bus-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "cgroup-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "dirent-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "fd-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "formats-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "hostname-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "label.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "machine-image.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "machined.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "signal-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart PoetteringManager *manager_new(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Manager *m;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
6a4e0b13473baed129522310c39f3bb70f46ed42Lennart Poettering m = new0(Manager, 1);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!m)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->machines = hashmap_new(&string_hash_ops);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->machine_units = hashmap_new(&string_hash_ops);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->machine_leaders = hashmap_new(NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!m->machines || !m->machine_units || !m->machine_leaders) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering manager_free(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_event_default(&m->event);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering manager_free(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_event_set_watchdog(m->event, true);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return m;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringvoid manager_free(Manager *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Machine *machine;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Image *i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering while ((machine = hashmap_first(m->machines)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine_free(machine);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering hashmap_free(m->machines);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering hashmap_free(m->machine_units);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering hashmap_free(m->machine_leaders);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering while ((i = hashmap_steal_first(m->image_cache)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering image_unref(i);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering hashmap_free(m->image_cache);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_event_source_unref(m->image_cache_defer_event);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus_verify_polkit_async_registry_free(m->polkit_registry);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_bus_unref(m->bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_event_unref(m->event);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int manager_add_host_machine(Manager *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ char *rd = NULL, *unit = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_id128_t mid;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Machine *t;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->host_machine)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_id128_get_machine(&mid);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to get machine ID: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering rd = strdup("/");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!rd)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unit = strdup("-.slice");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!unit)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering t = machine_new(m, MACHINE_HOST, ".host");
8aec412ff697bc14995746953912ca6fdf2c9ba8Lennart Poettering if (!t)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering t->leader = 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering t->id = mid;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering t->root_directory = rd;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering t->unit = unit;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering rd = unit = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dual_timestamp_from_boottime_or_monotonic(&t->timestamp, 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->host_machine = t;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint manager_enumerate_machines(Manager *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_closedir_ DIR *d = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct dirent *de;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = manager_add_host_machine(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Read in machine data stored on disk */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering d = opendir("/run/systemd/machines");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!d) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (errno == ENOENT)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(errno, "Failed to open /run/systemd/machines: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering FOREACH_DIRENT(de, d, return -errno) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct Machine *machine;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int k;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!dirent_is_file(de))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering continue;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Ignore symlinks that map the unit name to the machine */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (startswith(de->d_name, "unit:"))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering continue;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!machine_name_is_valid(de->d_name))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering continue;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering k = manager_add_machine(m, de->d_name, &machine);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (k < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = log_error_errno(k, "Failed to add machine by file name %s: %m", de->d_name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering continue;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine_add_to_gc_queue(machine);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering k = machine_load(machine);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (k < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = k;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int manager_connect_bus(Manager *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
554604b3073467af75dc94fac9e2343148603289Lennart Poettering int r;
554604b3073467af75dc94fac9e2343148603289Lennart Poettering
554604b3073467af75dc94fac9e2343148603289Lennart Poettering assert(m);
554604b3073467af75dc94fac9e2343148603289Lennart Poettering assert(!m->bus);
554604b3073467af75dc94fac9e2343148603289Lennart Poettering
554604b3073467af75dc94fac9e2343148603289Lennart Poettering r = sd_bus_default_system(&m->bus);
554604b3073467af75dc94fac9e2343148603289Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to connect to system bus: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to add manager object vtable: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to add machine object vtable: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/machine", machine_node_enumerator, m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to add machine enumerator: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/image", "org.freedesktop.machine1.Image", image_vtable, image_object_find, m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to add image object vtable: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/image", image_node_enumerator, m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to add image enumerator: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_add_match(m->bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "type='signal',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "sender='org.freedesktop.systemd1',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "interface='org.freedesktop.systemd1.Manager',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "member='JobRemoved',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "path='/org/freedesktop/systemd1'",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering match_job_removed,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to add match for JobRemoved: %m");
554604b3073467af75dc94fac9e2343148603289Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_add_match(m->bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "type='signal',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "sender='org.freedesktop.systemd1',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "interface='org.freedesktop.systemd1.Manager',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "member='UnitRemoved',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "path='/org/freedesktop/systemd1'",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering match_unit_removed,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to add match for UnitRemoved: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_add_match(m->bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "type='signal',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "sender='org.freedesktop.systemd1',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "interface='org.freedesktop.DBus.Properties',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "member='PropertiesChanged',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "arg0='org.freedesktop.systemd1.Unit'",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering match_properties_changed,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to add match for PropertiesChanged: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_add_match(m->bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "type='signal',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "sender='org.freedesktop.systemd1',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "interface='org.freedesktop.systemd1.Manager',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "member='Reloading',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "path='/org/freedesktop/systemd1'",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering match_reloading,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to add match for Reloading: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_call_method(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.systemd1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/org/freedesktop/systemd1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.systemd1.Manager",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "Subscribe",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering &error,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_request_name(m->bus, "org.freedesktop.machine1", 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to register name: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_attach_event(m->bus, m->event, 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to attach bus to event loop: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringvoid manager_gc(Manager *m, bool drop_not_started) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Machine *machine;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering while ((machine = m->machine_gc_queue)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering LIST_REMOVE(gc_queue, m->machine_gc_queue, machine);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine->in_gc_queue = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* First, if we are not closing yet, initiate stopping */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!machine_check_gc(machine, drop_not_started) &&
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine_get_state(machine) != MACHINE_CLOSING)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine_stop(machine);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Now, the stop stop probably made this referenced
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * again, but if it didn't, then it's time to let it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * go entirely. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!machine_check_gc(machine, drop_not_started)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine_finalize(machine);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine_free(machine);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint manager_startup(Manager *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Machine *machine;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Iterator i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Connect to the bus */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = manager_connect_bus(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Deserialize state */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering manager_enumerate_machines(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Remove stale objects before we start them */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering manager_gc(m, false);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* And start everything */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering HASHMAP_FOREACH(machine, m->machines, i)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine_start(machine, NULL, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool check_idle(void *userdata) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Manager *m = userdata;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering manager_gc(m, true);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return hashmap_isempty(m->machines);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint manager_run(Manager *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_event_loop_with_idle(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->event,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DEFAULT_EXIT_USEC,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering check_idle, m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint main(int argc, char *argv[]) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Manager *m = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_set_target(LOG_TARGET_AUTO);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_set_facility(LOG_AUTH);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_parse_environment();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_open();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering umask(0022);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (argc != 1) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("This program takes no arguments.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Always create the directories people can create inotify
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * watches in. Note that some applications might check for the
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * existence of /run/systemd/machines/ to determine whether
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * machined is available, so please always make sure this
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * check stays in. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mkdir_label("/run/systemd/machines", 0755);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m = manager_new();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = manager_startup(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error_errno(r, "Failed to fully start up daemon: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_debug("systemd-machined running as pid "PID_FMT, getpid());
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_notify(false,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "READY=1\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "STATUS=Processing requests...");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = manager_run(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_debug("systemd-machined stopped as pid "PID_FMT, getpid());
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringfinish:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering manager_free(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering