machine.c revision 2c4c73b3ffa123cc5c69f5749c58706aafb3f257
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 2011 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 <string.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <unistd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include <systemd/sd-messages.h>
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "util.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "mkdir.h"
c34255bdb217c2a1d3ac6348252437ab8be9ca46Lennart Poettering#include "hashmap.h"
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include "strv.h"
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include "fileio.h"
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering#include "special.h"
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering#include "unit-name.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "dbus-common.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "machine.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart PoetteringMachine* machine_new(Manager *manager, const char *name) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Machine *m;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(manager);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt m = new0(Machine, 1);
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt if (!m)
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt return NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d3e84ddb885e9d5f0ae9930eb905910e3a81f157Lennart Poettering m->name = strdup(name);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (!m->name)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering goto fail;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering m->state_file = strappend("/run/systemd/machines/", m->name);
afc6adb5ec7e73bc13156c43f52fb015cd80cc68Lennart Poettering if (!m->state_file)
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering goto fail;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (hashmap_put(manager->machines, m->name, m) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto fail;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
cde93897cdefdd7c7f66c400a61e42ceee5f6a46Lennart Poettering m->class = _MACHINE_CLASS_INVALID;
cde93897cdefdd7c7f66c400a61e42ceee5f6a46Lennart Poettering m->manager = manager;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return m;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringfail:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(m->state_file);
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering free(m->name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringvoid machine_free(Machine *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d3e84ddb885e9d5f0ae9930eb905910e3a81f157Lennart Poettering if (m->in_gc_queue)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering LIST_REMOVE(Machine, gc_queue, m->manager->machine_gc_queue, m);
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering if (m->scope) {
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering hashmap_remove(m->manager->machine_units, m->scope);
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering free(m->scope);
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering }
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering free(m->scope_job);
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering hashmap_remove(m->manager->machines, m->name);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (m->create_message)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering dbus_message_unref(m->create_message);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering free(m->name);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering free(m->state_file);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(m->service);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(m->root_directory);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint machine_save(Machine *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ char *temp_path = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m->state_file);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt if (!m->started)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = fopen_temporary(m->state_file, &f, &temp_path);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering fchmod(fileno(f), 0644);
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering fprintf(f,
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering "# This is private data. Do not parse.\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "NAME=%s\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->name);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->scope)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f, "SCOPE=%s\n", m->scope);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->scope_job)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f, "SCOPE_JOB=%s\n", m->scope_job);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->service)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f, "SERVICE=%s\n", m->service);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->root_directory)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f, "ROOT=%s\n", m->root_directory);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!sd_id128_equal(m->id, SD_ID128_NULL))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f, "ID=" SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->id));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->leader != 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering fprintf(f, "LEADER=%lu\n", (unsigned long) m->leader);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->class != _MACHINE_CLASS_INVALID)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f, "CLASS=%s\n", machine_class_to_string(m->class));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (dual_timestamp_is_set(&m->timestamp))
76b543756ef69ce69784d571aefe8de65eaeb331Lennart Poettering fprintf(f,
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt "REALTIME=%llu\n"
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt "MONOTONIC=%llu\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (unsigned long long) m->timestamp.realtime,
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering (unsigned long long) m->timestamp.monotonic);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt fflush(f);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering if (ferror(f) || rename(temp_path, m->state_file) < 0) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt r = -errno;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt unlink(m->state_file);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering unlink(temp_path);
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering }
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidtfinish:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering log_error("Failed to save machine data for %s: %s", m->name, strerror(-r));
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering return r;
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering}
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poetteringint machine_load(Machine *m) {
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL;
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering int r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering assert(m);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = parse_env_file(m->state_file, NEWLINE,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "SCOPE", &m->scope,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "SCOPE_JOB", &m->scope_job,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "SERVICE", &m->service,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "ROOT", &m->root_directory,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "ID", &id,
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt "LEADER", &leader,
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt "CLASS", &class,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "REALTIME", &realtime,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "MONOTONIC", &monotonic,
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering NULL);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r == -ENOENT)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return 0;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering log_error("Failed to read %s: %s", m->state_file, strerror(-r));
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (id)
943aca8efb39453e3994ccdd1e08534b788c5aeeLennart Poettering sd_id128_from_string(id, &m->id);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering if (leader)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering parse_pid(leader, &m->leader);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (class) {
11b90e69e5620c2483b019340eff121d504db115Lennart Poettering MachineClass c;
11b90e69e5620c2483b019340eff121d504db115Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering c = machine_class_from_string(class);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (c >= 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt m->class = c;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (realtime) {
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering unsigned long long l;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (sscanf(realtime, "%llu", &l) > 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering m->timestamp.realtime = l;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (monotonic) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering unsigned long long l;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (sscanf(monotonic, "%llu", &l) > 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt m->timestamp.monotonic = l;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt }
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int machine_start_scope(Machine *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ char *description = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBusError error;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char *job;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering int r = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(m);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_error_init(&error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
5bb658a1784a0fd4f0f32adb4b1fb636ff503f7dKay Sievers if (!m->scope) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt _cleanup_free_ char *escaped = NULL;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt char *scope;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering escaped = unit_name_escape(m->name);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (!escaped)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering scope = strjoin("machine-", escaped, ".scope", NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!scope)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering description = strappend(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = manager_start_scope(m->manager, scope, m->leader, SPECIAL_MACHINE_SLICE, description, &error, &job);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to start machine scope: %s", bus_error(&error, r));
71fda00f320379f5cbee8e118848de98caaa229dLennart Poettering dbus_error_free(&error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(scope);
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering } else {
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering m->scope = scope;
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(m->scope_job);
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering m->scope_job = job;
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering }
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering }
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering if (m->scope)
49f3fffd94591bdf2bd6c2233a9300daeab79566Lennart Poettering hashmap_put(m->manager->machine_units, m->scope, m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint machine_start(Machine *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->started)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Create cgroup */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = machine_start_scope(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_struct(LOG_INFO,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MESSAGE_ID(SD_MESSAGE_MACHINE_START),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "NAME=%s", m->name,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "LEADER=%lu", (unsigned long) m->leader,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "MESSAGE=New machine %s.", m->name,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!dual_timestamp_is_set(&m->timestamp))
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering dual_timestamp_get(&m->timestamp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->started = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Save new machine data */
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering machine_save(m);
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine_send_signal(m, true);
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering}
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int machine_stop_scope(Machine *m) {
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering DBusError error;
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering char *job;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering assert(m);
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering dbus_error_init(&error);
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering if (!m->scope)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = manager_stop_unit(m->manager, m->scope, &error, &job);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to stop machine scope: %s", bus_error(&error, r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_error_free(&error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(m->scope_job);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->scope_job = job;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint machine_stop(Machine *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r = 0, k;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->started)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_struct(LOG_INFO,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering MESSAGE_ID(SD_MESSAGE_MACHINE_STOP),
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "NAME=%s", m->name,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "LEADER=%lu", (unsigned long) m->leader,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "MESSAGE=Machine %s terminated.", m->name,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL);
72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9Lennart Poettering
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering /* Kill cgroup */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering k = machine_stop_scope(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (k < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = k;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unlink(m->state_file);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine_add_to_gc_queue(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->started)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt machine_send_signal(m, false);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->started = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint machine_check_gc(Machine *m, bool drop_not_started) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (drop_not_started && !m->started)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->scope_job)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1;
3e044c492e3ebe64f4e3175c94f9db8a62557b82Markus Elfring
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->scope)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return manager_unit_is_active(m->manager, m->scope) != 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
return 0;
}
void machine_add_to_gc_queue(Machine *m) {
assert(m);
if (m->in_gc_queue)
return;
LIST_PREPEND(Machine, gc_queue, m->manager->machine_gc_queue, m);
m->in_gc_queue = true;
}
MachineState machine_get_state(Machine *s) {
assert(s);
if (s->scope_job)
return s->started ? MACHINE_OPENING : MACHINE_CLOSING;
return MACHINE_RUNNING;
}
int machine_kill(Machine *m, KillWho who, int signo) {
assert(m);
if (!m->scope)
return -ESRCH;
return manager_kill_unit(m->manager, m->scope, who, signo, NULL);
}
static const char* const machine_class_table[_MACHINE_CLASS_MAX] = {
[MACHINE_CONTAINER] = "container",
[MACHINE_VM] = "vm"
};
DEFINE_STRING_TABLE_LOOKUP(machine_class, MachineClass);
static const char* const machine_state_table[_MACHINE_STATE_MAX] = {
[MACHINE_OPENING] = "opening",
[MACHINE_RUNNING] = "running",
[MACHINE_CLOSING] = "closing"
};
DEFINE_STRING_TABLE_LOOKUP(machine_state, MachineState);
static const char* const kill_who_table[_KILL_WHO_MAX] = {
[KILL_LEADER] = "leader",
[KILL_ALL] = "all"
};
DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho);