summaryrefslogtreecommitdiff
path: root/src/grp-machine/systemd-machined
diff options
context:
space:
mode:
Diffstat (limited to 'src/grp-machine/systemd-machined')
-rw-r--r--src/grp-machine/systemd-machined/Makefile30
-rw-r--r--src/grp-machine/systemd-machined/image-dbus.c423
-rw-r--r--src/grp-machine/systemd-machined/image-dbus.h35
-rw-r--r--src/grp-machine/systemd-machined/machine-dbus.c1473
-rw-r--r--src/grp-machine/systemd-machined/machine-dbus.h44
-rw-r--r--src/grp-machine/systemd-machined/machine.c631
-rw-r--r--src/grp-machine/systemd-machined/machine.h111
-rw-r--r--src/grp-machine/systemd-machined/machined-dbus.c1805
-rw-r--r--src/grp-machine/systemd-machined/machined.c23
-rw-r--r--src/grp-machine/systemd-machined/machined.h82
-rw-r--r--src/grp-machine/systemd-machined/operation.c153
-rw-r--r--src/grp-machine/systemd-machined/operation.h49
-rw-r--r--src/grp-machine/systemd-machined/test-machine-tables.c30
13 files changed, 13 insertions, 4876 deletions
diff --git a/src/grp-machine/systemd-machined/Makefile b/src/grp-machine/systemd-machined/Makefile
index 97fa68c5f9..011e740e02 100644
--- a/src/grp-machine/systemd-machined/Makefile
+++ b/src/grp-machine/systemd-machined/Makefile
@@ -29,39 +29,13 @@ systemd_machined_SOURCES = \
systemd_machined_LDADD = \
libsystemd-internal.la \
- libshared.la \
- libbasic.la \
+ libsystemd-shared.la \
+ libsystemd-basic.la \
libmachine-core.la
rootlibexec_PROGRAMS += \
systemd-machined
-libmachine_core_la_SOURCES = \
- src/machine/machine.c \
- src/machine/machine.h \
- src/machine/machined-dbus.c \
- src/machine/machine-dbus.c \
- src/machine/machine-dbus.h \
- src/machine/image-dbus.c \
- src/machine/image-dbus.h \
- src/machine/operation.c \
- src/machine/operation.h
-
-libmachine_core_la_LIBADD = \
- libsystemd-shared.la
-
-noinst_LTLIBRARIES += \
- libmachine-core.la
-
-test_machine_tables_SOURCES = \
- src/machine/test-machine-tables.c
-
-test_machine_tables_LDADD = \
- libmachine-core.la
-
-tests += \
- test-machine-tables
-
nodist_systemunit_DATA += \
units/systemd-machined.service
diff --git a/src/grp-machine/systemd-machined/image-dbus.c b/src/grp-machine/systemd-machined/image-dbus.c
deleted file mode 100644
index 6ab627a710..0000000000
--- a/src/grp-machine/systemd-machined/image-dbus.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "basic/alloc-util.h"
-#include "basic/bus-label.h"
-#include "basic/fd-util.h"
-#include "basic/io-util.h"
-#include "basic/process-util.h"
-#include "basic/strv.h"
-#include "basic/user-util.h"
-#include "shared/bus-util.h"
-#include "shared/machine-image.h"
-
-#include "image-dbus.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, image_type, ImageType);
-
-int bus_image_method_remove(
- sd_bus_message *message,
- void *userdata,
- sd_bus_error *error) {
-
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
- Image *image = userdata;
- Manager *m = image->userdata;
- pid_t child;
- int r;
-
- assert(message);
- assert(image);
-
- if (m->n_operations >= OPERATIONS_MAX)
- return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- "org.freedesktop.machine1.manage-images",
- NULL,
- false,
- UID_INVALID,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
-
- child = fork();
- if (child < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
- if (child == 0) {
- errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
-
- r = image_remove(image);
- if (r < 0) {
- (void) write(errno_pipe_fd[1], &r, sizeof(r));
- _exit(EXIT_FAILURE);
- }
-
- _exit(EXIT_SUCCESS);
- }
-
- errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
-
- r = operation_new(m, NULL, child, message, errno_pipe_fd[0], NULL);
- if (r < 0) {
- (void) sigkill_wait(child);
- return r;
- }
-
- errno_pipe_fd[0] = -1;
-
- return 1;
-}
-
-int bus_image_method_rename(
- sd_bus_message *message,
- void *userdata,
- sd_bus_error *error) {
-
- Image *image = userdata;
- Manager *m = image->userdata;
- const char *new_name;
- int r;
-
- assert(message);
- assert(image);
-
- r = sd_bus_message_read(message, "s", &new_name);
- if (r < 0)
- return r;
-
- if (!image_name_is_valid(new_name))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- "org.freedesktop.machine1.manage-images",
- NULL,
- false,
- UID_INVALID,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- r = image_rename(image, new_name);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-int bus_image_method_clone(
- sd_bus_message *message,
- void *userdata,
- sd_bus_error *error) {
-
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
- Image *image = userdata;
- Manager *m = image->userdata;
- const char *new_name;
- int r, read_only;
- pid_t child;
-
- assert(message);
- assert(image);
- assert(m);
-
- if (m->n_operations >= OPERATIONS_MAX)
- return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
-
- r = sd_bus_message_read(message, "sb", &new_name, &read_only);
- if (r < 0)
- return r;
-
- if (!image_name_is_valid(new_name))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- "org.freedesktop.machine1.manage-images",
- NULL,
- false,
- UID_INVALID,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
-
- child = fork();
- if (child < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
- if (child == 0) {
- errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
-
- r = image_clone(image, new_name, read_only);
- if (r < 0) {
- (void) write(errno_pipe_fd[1], &r, sizeof(r));
- _exit(EXIT_FAILURE);
- }
-
- _exit(EXIT_SUCCESS);
- }
-
- errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
-
- r = operation_new(m, NULL, child, message, errno_pipe_fd[0], NULL);
- if (r < 0) {
- (void) sigkill_wait(child);
- return r;
- }
-
- errno_pipe_fd[0] = -1;
-
- return 1;
-}
-
-int bus_image_method_mark_read_only(
- sd_bus_message *message,
- void *userdata,
- sd_bus_error *error) {
-
- Image *image = userdata;
- Manager *m = image->userdata;
- int r, read_only;
-
- assert(message);
-
- r = sd_bus_message_read(message, "b", &read_only);
- if (r < 0)
- return r;
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- "org.freedesktop.machine1.manage-images",
- NULL,
- false,
- UID_INVALID,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- r = image_read_only(image, read_only);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-int bus_image_method_set_limit(
- sd_bus_message *message,
- void *userdata,
- sd_bus_error *error) {
-
- Image *image = userdata;
- Manager *m = image->userdata;
- uint64_t limit;
- int r;
-
- assert(message);
-
- r = sd_bus_message_read(message, "t", &limit);
- if (r < 0)
- return r;
- if (!FILE_SIZE_VALID_OR_INFINITY(limit))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- "org.freedesktop.machine1.manage-images",
- NULL,
- false,
- UID_INVALID,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- r = image_set_limit(image, limit);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-const sd_bus_vtable image_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
- SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0),
- SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0),
- SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0),
- SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0),
- SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0),
- SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0),
- SD_BUS_PROPERTY("Limit", "t", NULL, offsetof(Image, limit), 0),
- SD_BUS_PROPERTY("UsageExclusive", "t", NULL, offsetof(Image, usage_exclusive), 0),
- SD_BUS_PROPERTY("LimitExclusive", "t", NULL, offsetof(Image, limit_exclusive), 0),
- SD_BUS_METHOD("Remove", NULL, NULL, bus_image_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Rename", "s", NULL, bus_image_method_rename, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_VTABLE_END
-};
-
-static int image_flush_cache(sd_event_source *s, void *userdata) {
- Manager *m = userdata;
- Image *i;
-
- assert(s);
- assert(m);
-
- while ((i = hashmap_steal_first(m->image_cache)))
- image_unref(i);
-
- return 0;
-}
-
-int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
- _cleanup_free_ char *e = NULL;
- Manager *m = userdata;
- Image *image = NULL;
- const char *p;
- int r;
-
- assert(bus);
- assert(path);
- assert(interface);
- assert(found);
-
- p = startswith(path, "/org/freedesktop/machine1/image/");
- if (!p)
- return 0;
-
- e = bus_label_unescape(p);
- if (!e)
- return -ENOMEM;
-
- image = hashmap_get(m->image_cache, e);
- if (image) {
- *found = image;
- return 1;
- }
-
- r = hashmap_ensure_allocated(&m->image_cache, &string_hash_ops);
- if (r < 0)
- return r;
-
- if (!m->image_cache_defer_event) {
- r = sd_event_add_defer(m->event, &m->image_cache_defer_event, image_flush_cache, m);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(m->image_cache_defer_event, SD_EVENT_PRIORITY_IDLE);
- if (r < 0)
- return r;
- }
-
- r = sd_event_source_set_enabled(m->image_cache_defer_event, SD_EVENT_ONESHOT);
- if (r < 0)
- return r;
-
- r = image_find(e, &image);
- if (r <= 0)
- return r;
-
- image->userdata = m;
-
- r = hashmap_put(m->image_cache, image->name, image);
- if (r < 0) {
- image_unref(image);
- return r;
- }
-
- *found = image;
- return 1;
-}
-
-char *image_bus_path(const char *name) {
- _cleanup_free_ char *e = NULL;
-
- assert(name);
-
- e = bus_label_escape(name);
- if (!e)
- return NULL;
-
- return strappend("/org/freedesktop/machine1/image/", e);
-}
-
-int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
- _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
- _cleanup_strv_free_ char **l = NULL;
- Image *image;
- Iterator i;
- int r;
-
- assert(bus);
- assert(path);
- assert(nodes);
-
- images = hashmap_new(&string_hash_ops);
- if (!images)
- return -ENOMEM;
-
- r = image_discover(images);
- if (r < 0)
- return r;
-
- HASHMAP_FOREACH(image, images, i) {
- char *p;
-
- p = image_bus_path(image->name);
- if (!p)
- return -ENOMEM;
-
- r = strv_consume(&l, p);
- if (r < 0)
- return r;
- }
-
- *nodes = l;
- l = NULL;
-
- return 1;
-}
diff --git a/src/grp-machine/systemd-machined/image-dbus.h b/src/grp-machine/systemd-machined/image-dbus.h
deleted file mode 100644
index b62da996c6..0000000000
--- a/src/grp-machine/systemd-machined/image-dbus.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "machined.h"
-
-extern const sd_bus_vtable image_vtable[];
-
-char *image_bus_path(const char *name);
-
-int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
-int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
-
-int bus_image_method_remove(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_image_method_rename(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_image_method_clone(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_image_method_mark_read_only(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_image_method_set_limit(sd_bus_message *message, void *userdata, sd_bus_error *error);
diff --git a/src/grp-machine/systemd-machined/machine-dbus.c b/src/grp-machine/systemd-machined/machine-dbus.c
deleted file mode 100644
index 91b5dfa993..0000000000
--- a/src/grp-machine/systemd-machined/machine-dbus.c
+++ /dev/null
@@ -1,1473 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <sys/wait.h>
-
-/* When we include libgen.h because we need dirname() we immediately
- * undefine basename() since libgen.h defines it as a macro to the POSIX
- * version which is really broken. We prefer GNU basename(). */
-#include <libgen.h>
-#undef basename
-
-#include "basic/alloc-util.h"
-#include "basic/bus-label.h"
-#include "basic/copy.h"
-#include "basic/env-util.h"
-#include "basic/fd-util.h"
-#include "basic/fileio.h"
-#include "basic/formats-util.h"
-#include "basic/fs-util.h"
-#include "basic/in-addr-util.h"
-#include "basic/mkdir.h"
-#include "basic/path-util.h"
-#include "basic/process-util.h"
-#include "basic/signal-util.h"
-#include "basic/strv.h"
-#include "basic/terminal-util.h"
-#include "basic/user-util.h"
-#include "sd-bus/bus-common-errors.h"
-#include "sd-bus/bus-internal.h"
-#include "sd-netlink/local-addresses.h"
-#include "shared/bus-util.h"
-
-#include "machine-dbus.h"
-#include "machine.h"
-
-static int property_get_id(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Machine *m = userdata;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- return sd_bus_message_append_array(reply, 'y', &m->id, 16);
-}
-
-static int property_get_state(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Machine *m = userdata;
- const char *state;
- int r;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- state = machine_state_to_string(machine_get_state(m));
-
- r = sd_bus_message_append_basic(reply, 's', state);
- if (r < 0)
- return r;
-
- return 1;
-}
-
-static int property_get_netif(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Machine *m = userdata;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- assert_cc(sizeof(int) == sizeof(int32_t));
-
- return sd_bus_message_append_array(reply, 'i', m->netif, m->n_netif * sizeof(int));
-}
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
-
-int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Machine *m = userdata;
- int r;
-
- assert(message);
- assert(m);
-
- r = bus_verify_polkit_async(
- message,
- CAP_KILL,
- "org.freedesktop.machine1.manage-machines",
- NULL,
- false,
- UID_INVALID,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- r = machine_stop(m);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-int bus_machine_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Machine *m = userdata;
- const char *swho;
- int32_t signo;
- KillWho who;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "si", &swho, &signo);
- if (r < 0)
- return r;
-
- if (isempty(swho))
- who = KILL_ALL;
- else {
- who = kill_who_from_string(swho);
- if (who < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
- }
-
- if (!SIGNAL_VALID(signo))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
-
- r = bus_verify_polkit_async(
- message,
- CAP_KILL,
- "org.freedesktop.machine1.manage-machines",
- NULL,
- false,
- UID_INVALID,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- r = machine_kill(m, who, signo);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- Machine *m = userdata;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(reply, 'a', "(iay)");
- if (r < 0)
- return r;
-
- switch (m->class) {
-
- case MACHINE_HOST: {
- _cleanup_free_ struct local_address *addresses = NULL;
- struct local_address *a;
- int n, i;
-
- n = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
- if (n < 0)
- return n;
-
- for (a = addresses, i = 0; i < n; a++, i++) {
-
- r = sd_bus_message_open_container(reply, 'r', "iay");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(reply, "i", addresses[i].family);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append_array(reply, 'y', &addresses[i].address, FAMILY_ADDRESS_SIZE(addresses[i].family));
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
- }
-
- break;
- }
-
- case MACHINE_CONTAINER: {
- _cleanup_close_pair_ int pair[2] = { -1, -1 };
- _cleanup_free_ char *us = NULL, *them = NULL;
- _cleanup_close_ int netns_fd = -1;
- const char *p;
- siginfo_t si;
- pid_t child;
-
- r = readlink_malloc("/proc/self/ns/net", &us);
- if (r < 0)
- return r;
-
- p = procfs_file_alloca(m->leader, "ns/net");
- r = readlink_malloc(p, &them);
- if (r < 0)
- return r;
-
- if (streq(us, them))
- return sd_bus_error_setf(error, BUS_ERROR_NO_PRIVATE_NETWORKING, "Machine %s does not use private networking", m->name);
-
- r = namespace_open(m->leader, NULL, NULL, &netns_fd, NULL, NULL);
- if (r < 0)
- return r;
-
- if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
- return -errno;
-
- child = fork();
- if (child < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
-
- if (child == 0) {
- _cleanup_free_ struct local_address *addresses = NULL;
- struct local_address *a;
- int i, n;
-
- pair[0] = safe_close(pair[0]);
-
- r = namespace_enter(-1, -1, netns_fd, -1, -1);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
- n = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
- if (n < 0)
- _exit(EXIT_FAILURE);
-
- for (a = addresses, i = 0; i < n; a++, i++) {
- struct iovec iov[2] = {
- { .iov_base = &a->family, .iov_len = sizeof(a->family) },
- { .iov_base = &a->address, .iov_len = FAMILY_ADDRESS_SIZE(a->family) },
- };
-
- r = writev(pair[1], iov, 2);
- if (r < 0)
- _exit(EXIT_FAILURE);
- }
-
- pair[1] = safe_close(pair[1]);
-
- _exit(EXIT_SUCCESS);
- }
-
- pair[1] = safe_close(pair[1]);
-
- for (;;) {
- int family;
- ssize_t n;
- union in_addr_union in_addr;
- struct iovec iov[2];
- struct msghdr mh = {
- .msg_iov = iov,
- .msg_iovlen = 2,
- };
-
- iov[0] = (struct iovec) { .iov_base = &family, .iov_len = sizeof(family) };
- iov[1] = (struct iovec) { .iov_base = &in_addr, .iov_len = sizeof(in_addr) };
-
- n = recvmsg(pair[0], &mh, 0);
- if (n < 0)
- return -errno;
- if ((size_t) n < sizeof(family))
- break;
-
- r = sd_bus_message_open_container(reply, 'r', "iay");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(reply, "i", family);
- if (r < 0)
- return r;
-
- switch (family) {
-
- case AF_INET:
- if (n != sizeof(struct in_addr) + sizeof(family))
- return -EIO;
-
- r = sd_bus_message_append_array(reply, 'y', &in_addr.in, sizeof(in_addr.in));
- break;
-
- case AF_INET6:
- if (n != sizeof(struct in6_addr) + sizeof(family))
- return -EIO;
-
- r = sd_bus_message_append_array(reply, 'y', &in_addr.in6, sizeof(in_addr.in6));
- break;
- }
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
- }
-
- r = wait_for_terminate(child, &si);
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
- if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
- return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
- break;
- }
-
- default:
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Requesting IP address data is only supported on container machines.");
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
-
- return sd_bus_send(NULL, reply, NULL);
-}
-
-int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_strv_free_ char **l = NULL;
- Machine *m = userdata;
- char **k, **v;
- int r;
-
- assert(message);
- assert(m);
-
- switch (m->class) {
-
- case MACHINE_HOST:
- r = load_env_file_pairs(NULL, "/etc/os-release", NULL, &l);
- if (r < 0)
- return r;
-
- break;
-
- case MACHINE_CONTAINER: {
- _cleanup_close_ int mntns_fd = -1, root_fd = -1;
- _cleanup_close_pair_ int pair[2] = { -1, -1 };
- _cleanup_fclose_ FILE *f = NULL;
- siginfo_t si;
- pid_t child;
-
- r = namespace_open(m->leader, NULL, &mntns_fd, NULL, NULL, &root_fd);
- if (r < 0)
- return r;
-
- if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
- return -errno;
-
- child = fork();
- if (child < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
-
- if (child == 0) {
- _cleanup_close_ int fd = -1;
-
- pair[0] = safe_close(pair[0]);
-
- r = namespace_enter(-1, mntns_fd, -1, -1, root_fd);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
- fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC);
- if (fd < 0) {
- fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC);
- if (fd < 0)
- _exit(EXIT_FAILURE);
- }
-
- r = copy_bytes(fd, pair[1], (uint64_t) -1, false);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
- _exit(EXIT_SUCCESS);
- }
-
- pair[1] = safe_close(pair[1]);
-
- f = fdopen(pair[0], "re");
- if (!f)
- return -errno;
-
- pair[0] = -1;
-
- r = load_env_file_pairs(f, "/etc/os-release", NULL, &l);
- if (r < 0)
- return r;
-
- r = wait_for_terminate(child, &si);
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
- if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
- return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
-
- break;
- }
-
- default:
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Requesting OS release data is only supported on container machines.");
- }
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(reply, 'a', "{ss}");
- if (r < 0)
- return r;
-
- STRV_FOREACH_PAIR(k, v, l) {
- r = sd_bus_message_append(reply, "{ss}", *k, *v);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
-
- return sd_bus_send(NULL, reply, NULL);
-}
-
-int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_free_ char *pty_name = NULL;
- _cleanup_close_ int master = -1;
- Machine *m = userdata;
- int r;
-
- assert(message);
- assert(m);
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-open-pty" : "org.freedesktop.machine1.open-pty",
- NULL,
- false,
- UID_INVALID,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (master < 0)
- return master;
-
- r = ptsname_namespace(master, &pty_name);
- if (r < 0)
- return r;
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(reply, "hs", master, pty_name);
- if (r < 0)
- return r;
-
- return sd_bus_send(NULL, reply, NULL);
-}
-
-static int container_bus_new(Machine *m, sd_bus_error *error, sd_bus **ret) {
- int r;
-
- assert(m);
- assert(ret);
-
- switch (m->class) {
-
- case MACHINE_HOST:
- *ret = NULL;
- break;
-
- case MACHINE_CONTAINER: {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
- char *address;
-
- r = sd_bus_new(&bus);
- if (r < 0)
- return r;
-
- if (asprintf(&address, "x-machine-kernel:pid=%1$" PID_PRI ";x-machine-unix:pid=%1$" PID_PRI, m->leader) < 0)
- return -ENOMEM;
-
- bus->address = address;
- bus->bus_client = true;
- bus->trusted = false;
- bus->is_system = true;
-
- r = sd_bus_start(bus);
- if (r == -ENOENT)
- return sd_bus_error_set_errnof(error, r, "There is no system bus in container %s.", m->name);
- if (r < 0)
- return r;
-
- *ret = bus;
- bus = NULL;
- break;
- }
-
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_free_ char *pty_name = NULL;
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL;
- _cleanup_close_ int master = -1;
- sd_bus *container_bus = NULL;
- Machine *m = userdata;
- const char *p, *getty;
- int r;
-
- assert(message);
- assert(m);
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-login" : "org.freedesktop.machine1.login",
- NULL,
- false,
- UID_INVALID,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (master < 0)
- return master;
-
- r = ptsname_namespace(master, &pty_name);
- if (r < 0)
- return r;
-
- p = path_startswith(pty_name, "/dev/pts/");
- if (!p)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PTS name %s is invalid", pty_name);
-
- r = container_bus_new(m, error, &allocated_bus);
- if (r < 0)
- return r;
-
- container_bus = allocated_bus ?: m->manager->bus;
-
- getty = strjoina("container-getty@", p, ".service");
-
- r = sd_bus_call_method(
- container_bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "StartUnit",
- error, NULL,
- "ss", getty, "replace");
- if (r < 0)
- return r;
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(reply, "hs", master, pty_name);
- if (r < 0)
- return r;
-
- return sd_bus_send(NULL, reply, NULL);
-}
-
-int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *tm = NULL;
- _cleanup_free_ char *pty_name = NULL;
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL;
- sd_bus *container_bus = NULL;
- _cleanup_close_ int master = -1, slave = -1;
- _cleanup_strv_free_ char **env = NULL, **args = NULL;
- Machine *m = userdata;
- const char *p, *unit, *user, *path, *description, *utmp_id;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "ss", &user, &path);
- if (r < 0)
- return r;
- user = empty_to_null(user);
- if (isempty(path))
- path = "/bin/sh";
- if (!path_is_absolute(path))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified path '%s' is not absolute", path);
-
- r = sd_bus_message_read_strv(message, &args);
- if (r < 0)
- return r;
- if (strv_isempty(args)) {
- args = strv_free(args);
-
- args = strv_new(path, NULL);
- if (!args)
- return -ENOMEM;
-
- args[0][0] = '-'; /* Tell /bin/sh that this shall be a login shell */
- }
-
- r = sd_bus_message_read_strv(message, &env);
- if (r < 0)
- return r;
- if (!strv_env_is_valid(env))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-shell" : "org.freedesktop.machine1.shell",
- NULL,
- false,
- UID_INVALID,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (master < 0)
- return master;
-
- r = ptsname_namespace(master, &pty_name);
- if (r < 0)
- return r;
-
- p = path_startswith(pty_name, "/dev/pts/");
- assert(p);
-
- slave = machine_open_terminal(m, pty_name, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (slave < 0)
- return slave;
-
- utmp_id = path_startswith(pty_name, "/dev/");
- assert(utmp_id);
-
- r = container_bus_new(m, error, &allocated_bus);
- if (r < 0)
- return r;
-
- container_bus = allocated_bus ?: m->manager->bus;
-
- r = sd_bus_message_new_method_call(
- container_bus,
- &tm,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "StartTransientUnit");
- if (r < 0)
- return r;
-
- /* Name and mode */
- unit = strjoina("container-shell@", p, ".service");
- r = sd_bus_message_append(tm, "ss", unit, "fail");
- if (r < 0)
- return r;
-
- /* Properties */
- r = sd_bus_message_open_container(tm, 'a', "(sv)");
- if (r < 0)
- return r;
-
- description = strjoina("Shell for User ", isempty(user) ? "root" : user);
- r = sd_bus_message_append(tm,
- "(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)",
- "Description", "s", description,
- "StandardInputFileDescriptor", "h", slave,
- "StandardOutputFileDescriptor", "h", slave,
- "StandardErrorFileDescriptor", "h", slave,
- "SendSIGHUP", "b", true,
- "IgnoreSIGPIPE", "b", false,
- "KillMode", "s", "mixed",
- "TTYReset", "b", true,
- "UtmpIdentifier", "s", utmp_id,
- "UtmpMode", "s", "user",
- "PAMName", "s", "login",
- "WorkingDirectory", "s", "-~");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(tm, "(sv)", "User", "s", isempty(user) ? "root" : user);
- if (r < 0)
- return r;
-
- if (!strv_isempty(env)) {
- r = sd_bus_message_open_container(tm, 'r', "sv");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(tm, "s", "Environment");
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(tm, 'v', "as");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append_strv(tm, env);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(tm);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(tm);
- if (r < 0)
- return r;
- }
-
- /* Exec container */
- r = sd_bus_message_open_container(tm, 'r', "sv");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(tm, "s", "ExecStart");
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(tm, 'v', "a(sasb)");
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(tm, 'a', "(sasb)");
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(tm, 'r', "sasb");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(tm, "s", path);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append_strv(tm, args);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(tm, "b", true);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(tm);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(tm);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(tm);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(tm);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(tm);
- if (r < 0)
- return r;
-
- /* Auxiliary units */
- r = sd_bus_message_append(tm, "a(sa(sv))", 0);
- if (r < 0)
- return r;
-
- r = sd_bus_call(container_bus, tm, 0, error, NULL);
- if (r < 0)
- return r;
-
- slave = safe_close(slave);
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(reply, "hs", master, pty_name);
- if (r < 0)
- return r;
-
- return sd_bus_send(NULL, reply, NULL);
-}
-
-int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
- char mount_slave[] = "/tmp/propagate.XXXXXX", *mount_tmp, *mount_outside, *p;
- bool mount_slave_created = false, mount_slave_mounted = false,
- mount_tmp_created = false, mount_tmp_mounted = false,
- mount_outside_created = false, mount_outside_mounted = false;
- const char *dest, *src;
- Machine *m = userdata;
- int read_only, make_directory;
- pid_t child;
- siginfo_t si;
- int r;
-
- assert(message);
- assert(m);
-
- if (m->class != MACHINE_CONTAINER)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Bind mounting is only supported on container machines.");
-
- r = sd_bus_message_read(message, "ssbb", &src, &dest, &read_only, &make_directory);
- if (r < 0)
- return r;
-
- if (!path_is_absolute(src) || !path_is_safe(src))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path must be absolute and not contain ../.");
-
- if (isempty(dest))
- dest = src;
- else if (!path_is_absolute(dest) || !path_is_safe(dest))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute and not contain ../.");
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- "org.freedesktop.machine1.manage-machines",
- NULL,
- false,
- UID_INVALID,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- /* One day, when bind mounting /proc/self/fd/n works across
- * namespace boundaries we should rework this logic to make
- * use of it... */
-
- p = strjoina("/run/systemd/nspawn/propagate/", m->name, "/");
- if (laccess(p, F_OK) < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Container does not allow propagation of mount points.");
-
- /* Our goal is to install a new bind mount into the container,
- possibly read-only. This is irritatingly complex
- unfortunately, currently.
-
- First, we start by creating a private playground in /tmp,
- that we can mount MS_SLAVE. (Which is necessary, since
- MS_MOVE cannot be applied to mounts with MS_SHARED parent
- mounts.) */
-
- if (!mkdtemp(mount_slave))
- return sd_bus_error_set_errnof(error, errno, "Failed to create playground %s: %m", mount_slave);
-
- mount_slave_created = true;
-
- if (mount(mount_slave, mount_slave, NULL, MS_BIND, NULL) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to make bind mount %s: %m", mount_slave);
- goto finish;
- }
-
- mount_slave_mounted = true;
-
- if (mount(NULL, mount_slave, NULL, MS_SLAVE, NULL) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to remount slave %s: %m", mount_slave);
- goto finish;
- }
-
- /* Second, we mount the source directory to a directory inside
- of our MS_SLAVE playground. */
- mount_tmp = strjoina(mount_slave, "/mount");
- if (mkdir(mount_tmp, 0700) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to create temporary mount point %s: %m", mount_tmp);
- goto finish;
- }
-
- mount_tmp_created = true;
-
- if (mount(src, mount_tmp, NULL, MS_BIND, NULL) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to overmount %s: %m", mount_tmp);
- goto finish;
- }
-
- mount_tmp_mounted = true;
-
- /* Third, we remount the new bind mount read-only if requested. */
- if (read_only)
- if (mount(NULL, mount_tmp, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to remount read-only %s: %m", mount_tmp);
- goto finish;
- }
-
- /* Fourth, we move the new bind mount into the propagation
- * directory. This way it will appear there read-only
- * right-away. */
-
- mount_outside = strjoina("/run/systemd/nspawn/propagate/", m->name, "/XXXXXX");
- if (!mkdtemp(mount_outside)) {
- r = sd_bus_error_set_errnof(error, errno, "Cannot create propagation directory %s: %m", mount_outside);
- goto finish;
- }
-
- mount_outside_created = true;
-
- if (mount(mount_tmp, mount_outside, NULL, MS_MOVE, NULL) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to move %s to %s: %m", mount_tmp, mount_outside);
- goto finish;
- }
-
- mount_outside_mounted = true;
- mount_tmp_mounted = false;
-
- (void) rmdir(mount_tmp);
- mount_tmp_created = false;
-
- (void) umount(mount_slave);
- mount_slave_mounted = false;
-
- (void) rmdir(mount_slave);
- mount_slave_created = false;
-
- if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
- goto finish;
- }
-
- child = fork();
- if (child < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
- goto finish;
- }
-
- if (child == 0) {
- const char *mount_inside;
- int mntfd;
- const char *q;
-
- errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
-
- q = procfs_file_alloca(m->leader, "ns/mnt");
- mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
- if (mntfd < 0) {
- r = log_error_errno(errno, "Failed to open mount namespace of leader: %m");
- goto child_fail;
- }
-
- if (setns(mntfd, CLONE_NEWNS) < 0) {
- r = log_error_errno(errno, "Failed to join namespace of leader: %m");
- goto child_fail;
- }
-
- if (make_directory)
- (void) mkdir_p(dest, 0755);
-
- /* Fifth, move the mount to the right place inside */
- mount_inside = strjoina("/run/systemd/nspawn/incoming/", basename(mount_outside));
- if (mount(mount_inside, dest, NULL, MS_MOVE, NULL) < 0) {
- r = log_error_errno(errno, "Failed to mount: %m");
- goto child_fail;
- }
-
- _exit(EXIT_SUCCESS);
-
- child_fail:
- (void) write(errno_pipe_fd[1], &r, sizeof(r));
- errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
-
- _exit(EXIT_FAILURE);
- }
-
- errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
-
- r = wait_for_terminate(child, &si);
- if (r < 0) {
- r = sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
- goto finish;
- }
- if (si.si_code != CLD_EXITED) {
- r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
- goto finish;
- }
- if (si.si_status != EXIT_SUCCESS) {
-
- if (read(errno_pipe_fd[0], &r, sizeof(r)) == sizeof(r))
- r = sd_bus_error_set_errnof(error, r, "Failed to mount: %m");
- else
- r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child failed.");
- goto finish;
- }
-
- r = sd_bus_reply_method_return(message, NULL);
-
-finish:
- if (mount_outside_mounted)
- umount(mount_outside);
- if (mount_outside_created)
- rmdir(mount_outside);
-
- if (mount_tmp_mounted)
- umount(mount_tmp);
- if (mount_tmp_created)
- rmdir(mount_tmp);
-
- if (mount_slave_mounted)
- umount(mount_slave);
- if (mount_slave_created)
- rmdir(mount_slave);
-
- return r;
-}
-
-int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- const char *src, *dest, *host_path, *container_path, *host_basename, *host_dirname, *container_basename, *container_dirname;
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
- _cleanup_close_ int hostfd = -1;
- Machine *m = userdata;
- bool copy_from;
- pid_t child;
- char *t;
- int r;
-
- assert(message);
- assert(m);
-
- if (m->manager->n_operations >= OPERATIONS_MAX)
- return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing copies.");
-
- if (m->class != MACHINE_CONTAINER)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Copying files is only supported on container machines.");
-
- r = sd_bus_message_read(message, "ss", &src, &dest);
- if (r < 0)
- return r;
-
- if (!path_is_absolute(src))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path must be absolute.");
-
- if (isempty(dest))
- dest = src;
- else if (!path_is_absolute(dest))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute.");
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- "org.freedesktop.machine1.manage-machines",
- NULL,
- false,
- UID_INVALID,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- copy_from = strstr(sd_bus_message_get_member(message), "CopyFrom");
-
- if (copy_from) {
- container_path = src;
- host_path = dest;
- } else {
- host_path = src;
- container_path = dest;
- }
-
- host_basename = basename(host_path);
- t = strdupa(host_path);
- host_dirname = dirname(t);
-
- container_basename = basename(container_path);
- t = strdupa(container_path);
- container_dirname = dirname(t);
-
- hostfd = open(host_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
- if (hostfd < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to open host directory %s: %m", host_dirname);
-
- if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
-
- child = fork();
- if (child < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
-
- if (child == 0) {
- int containerfd;
- const char *q;
- int mntfd;
-
- errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
-
- q = procfs_file_alloca(m->leader, "ns/mnt");
- mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
- if (mntfd < 0) {
- r = log_error_errno(errno, "Failed to open mount namespace of leader: %m");
- goto child_fail;
- }
-
- if (setns(mntfd, CLONE_NEWNS) < 0) {
- r = log_error_errno(errno, "Failed to join namespace of leader: %m");
- goto child_fail;
- }
-
- containerfd = open(container_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
- if (containerfd < 0) {
- r = log_error_errno(errno, "Failed top open destination directory: %m");
- goto child_fail;
- }
-
- if (copy_from)
- r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, true);
- else
- r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, true);
-
- hostfd = safe_close(hostfd);
- containerfd = safe_close(containerfd);
-
- if (r < 0) {
- r = log_error_errno(r, "Failed to copy tree: %m");
- goto child_fail;
- }
-
- _exit(EXIT_SUCCESS);
-
- child_fail:
- (void) write(errno_pipe_fd[1], &r, sizeof(r));
- _exit(EXIT_FAILURE);
- }
-
- errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
-
- /* Copying might take a while, hence install a watch on the child, and return */
-
- r = operation_new(m->manager, m, child, message, errno_pipe_fd[0], NULL);
- if (r < 0) {
- (void) sigkill_wait(child);
- return r;
- }
- errno_pipe_fd[0] = -1;
-
- return 1;
-}
-
-int bus_machine_method_open_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_close_ int fd = -1;
- Machine *m = userdata;
- int r;
-
- assert(message);
- assert(m);
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- "org.freedesktop.machine1.manage-machines",
- NULL,
- false,
- UID_INVALID,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- switch (m->class) {
-
- case MACHINE_HOST:
- fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
- if (fd < 0)
- return -errno;
-
- break;
-
- case MACHINE_CONTAINER: {
- _cleanup_close_ int mntns_fd = -1, root_fd = -1;
- _cleanup_close_pair_ int pair[2] = { -1, -1 };
- siginfo_t si;
- pid_t child;
-
- r = namespace_open(m->leader, NULL, &mntns_fd, NULL, NULL, &root_fd);
- if (r < 0)
- return r;
-
- if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
- return -errno;
-
- child = fork();
- if (child < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
-
- if (child == 0) {
- _cleanup_close_ int dfd = -1;
-
- pair[0] = safe_close(pair[0]);
-
- r = namespace_enter(-1, mntns_fd, -1, -1, root_fd);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
- dfd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
- if (dfd < 0)
- _exit(EXIT_FAILURE);
-
- r = send_one_fd(pair[1], dfd, 0);
- dfd = safe_close(dfd);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
- _exit(EXIT_SUCCESS);
- }
-
- pair[1] = safe_close(pair[1]);
-
- r = wait_for_terminate(child, &si);
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
- if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
- return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
-
- fd = receive_one_fd(pair[0], MSG_DONTWAIT);
- if (fd < 0)
- return fd;
-
- break;
- }
-
- default:
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Opening the root directory is only supported on container machines.");
- }
-
- return sd_bus_reply_method_return(message, "h", fd);
-}
-
-const sd_bus_vtable machine_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Id", "ay", property_get_id, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Machine, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Machine, service), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Unit", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
- SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("NetworkInterfaces", "ai", property_get_netif, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
- SD_BUS_METHOD("Terminate", NULL, NULL, bus_machine_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Kill", "si", NULL, bus_machine_method_kill, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetAddresses", NULL, "a(iay)", bus_machine_method_get_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_machine_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("OpenPTY", NULL, "hs", bus_machine_method_open_pty, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("OpenLogin", NULL, "hs", bus_machine_method_open_login, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("OpenShell", "ssasas", "hs", bus_machine_method_open_shell, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("BindMount", "ssbb", NULL, bus_machine_method_bind_mount, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CopyFrom", "ss", NULL, bus_machine_method_copy, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CopyTo", "ss", NULL, bus_machine_method_copy, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("OpenRootDirectory", NULL, "h", bus_machine_method_open_root_directory, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_VTABLE_END
-};
-
-int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- int r;
-
- assert(bus);
- assert(path);
- assert(interface);
- assert(found);
- assert(m);
-
- if (streq(path, "/org/freedesktop/machine1/machine/self")) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- sd_bus_message *message;
- pid_t pid;
-
- message = sd_bus_get_current_message(bus);
- if (!message)
- return 0;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r < 0)
- return r;
-
- r = manager_get_machine_by_pid(m, pid, &machine);
- if (r <= 0)
- return 0;
- } else {
- _cleanup_free_ char *e = NULL;
- const char *p;
-
- p = startswith(path, "/org/freedesktop/machine1/machine/");
- if (!p)
- return 0;
-
- e = bus_label_unescape(p);
- if (!e)
- return -ENOMEM;
-
- machine = hashmap_get(m->machines, e);
- if (!machine)
- return 0;
- }
-
- *found = machine;
- return 1;
-}
-
-char *machine_bus_path(Machine *m) {
- _cleanup_free_ char *e = NULL;
-
- assert(m);
-
- e = bus_label_escape(m->name);
- if (!e)
- return NULL;
-
- return strappend("/org/freedesktop/machine1/machine/", e);
-}
-
-int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
- _cleanup_strv_free_ char **l = NULL;
- Machine *machine = NULL;
- Manager *m = userdata;
- Iterator i;
- int r;
-
- assert(bus);
- assert(path);
- assert(nodes);
-
- HASHMAP_FOREACH(machine, m->machines, i) {
- char *p;
-
- p = machine_bus_path(machine);
- if (!p)
- return -ENOMEM;
-
- r = strv_consume(&l, p);
- if (r < 0)
- return r;
- }
-
- *nodes = l;
- l = NULL;
-
- return 1;
-}
-
-int machine_send_signal(Machine *m, bool new_machine) {
- _cleanup_free_ char *p = NULL;
-
- assert(m);
-
- p = machine_bus_path(m);
- if (!p)
- return -ENOMEM;
-
- return sd_bus_emit_signal(
- m->manager->bus,
- "/org/freedesktop/machine1",
- "org.freedesktop.machine1.Manager",
- new_machine ? "MachineNew" : "MachineRemoved",
- "so", m->name, p);
-}
-
-int machine_send_create_reply(Machine *m, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *c = NULL;
- _cleanup_free_ char *p = NULL;
-
- assert(m);
-
- if (!m->create_message)
- return 0;
-
- c = m->create_message;
- m->create_message = NULL;
-
- if (error)
- return sd_bus_reply_method_error(c, error);
-
- /* Update the machine state file before we notify the client
- * about the result. */
- machine_save(m);
-
- p = machine_bus_path(m);
- if (!p)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(c, "o", p);
-}
diff --git a/src/grp-machine/systemd-machined/machine-dbus.h b/src/grp-machine/systemd-machined/machine-dbus.h
deleted file mode 100644
index d3faf5cb07..0000000000
--- a/src/grp-machine/systemd-machined/machine-dbus.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <systemd/sd-bus.h>
-
-#include "machine.h"
-
-extern const sd_bus_vtable machine_vtable[];
-
-char *machine_bus_path(Machine *s);
-int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
-int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
-
-int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_machine_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_machine_method_open_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error);
-
-int machine_send_signal(Machine *m, bool new_machine);
-int machine_send_create_reply(Machine *m, sd_bus_error *error);
diff --git a/src/grp-machine/systemd-machined/machine.c b/src/grp-machine/systemd-machined/machine.c
deleted file mode 100644
index 701fec0e67..0000000000
--- a/src/grp-machine/systemd-machined/machine.c
+++ /dev/null
@@ -1,631 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <systemd/sd-messages.h>
-
-#include "basic/alloc-util.h"
-#include "basic/escape.h"
-#include "basic/extract-word.h"
-#include "basic/fd-util.h"
-#include "basic/fileio.h"
-#include "basic/formats-util.h"
-#include "basic/hashmap.h"
-#include "basic/mkdir.h"
-#include "basic/parse-util.h"
-#include "basic/process-util.h"
-#include "basic/special.h"
-#include "basic/string-table.h"
-#include "basic/terminal-util.h"
-#include "basic/unit-name.h"
-#include "basic/util.h"
-#include "sd-bus/bus-error.h"
-#include "shared/bus-util.h"
-
-#include "machine-dbus.h"
-#include "machine.h"
-
-Machine* machine_new(Manager *manager, MachineClass class, const char *name) {
- Machine *m;
-
- assert(manager);
- assert(class < _MACHINE_CLASS_MAX);
- assert(name);
-
- /* Passing class == _MACHINE_CLASS_INVALID here is fine. It
- * means as much as "we don't know yet", and that we'll figure
- * it out later when loading the state file. */
-
- m = new0(Machine, 1);
- if (!m)
- return NULL;
-
- m->name = strdup(name);
- if (!m->name)
- goto fail;
-
- if (class != MACHINE_HOST) {
- m->state_file = strappend("/run/systemd/machines/", m->name);
- if (!m->state_file)
- goto fail;
- }
-
- m->class = class;
-
- if (hashmap_put(manager->machines, m->name, m) < 0)
- goto fail;
-
- m->manager = manager;
-
- return m;
-
-fail:
- free(m->state_file);
- free(m->name);
- free(m);
-
- return NULL;
-}
-
-void machine_free(Machine *m) {
- assert(m);
-
- while (m->operations)
- operation_free(m->operations);
-
- if (m->in_gc_queue)
- LIST_REMOVE(gc_queue, m->manager->machine_gc_queue, m);
-
- machine_release_unit(m);
-
- free(m->scope_job);
-
- (void) hashmap_remove(m->manager->machines, m->name);
-
- if (m->manager->host_machine == m)
- m->manager->host_machine = NULL;
-
- if (m->leader > 0)
- (void) hashmap_remove_value(m->manager->machine_leaders, PID_TO_PTR(m->leader), m);
-
- sd_bus_message_unref(m->create_message);
-
- free(m->name);
- free(m->state_file);
- free(m->service);
- free(m->root_directory);
- free(m->netif);
- free(m);
-}
-
-int machine_save(Machine *m) {
- _cleanup_free_ char *temp_path = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- int r;
-
- assert(m);
-
- if (!m->state_file)
- return 0;
-
- if (!m->started)
- return 0;
-
- r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0);
- if (r < 0)
- goto fail;
-
- r = fopen_temporary(m->state_file, &f, &temp_path);
- if (r < 0)
- goto fail;
-
- (void) fchmod(fileno(f), 0644);
-
- fprintf(f,
- "# This is private data. Do not parse.\n"
- "NAME=%s\n",
- m->name);
-
- if (m->unit) {
- _cleanup_free_ char *escaped;
-
- escaped = cescape(m->unit);
- if (!escaped) {
- r = -ENOMEM;
- goto fail;
- }
-
- fprintf(f, "SCOPE=%s\n", escaped); /* We continue to call this "SCOPE=" because it is internal only, and we want to stay compatible with old files */
- }
-
- if (m->scope_job)
- fprintf(f, "SCOPE_JOB=%s\n", m->scope_job);
-
- if (m->service) {
- _cleanup_free_ char *escaped;
-
- escaped = cescape(m->service);
- if (!escaped) {
- r = -ENOMEM;
- goto fail;
- }
- fprintf(f, "SERVICE=%s\n", escaped);
- }
-
- if (m->root_directory) {
- _cleanup_free_ char *escaped;
-
- escaped = cescape(m->root_directory);
- if (!escaped) {
- r = -ENOMEM;
- goto fail;
- }
- fprintf(f, "ROOT=%s\n", escaped);
- }
-
- if (!sd_id128_is_null(m->id))
- fprintf(f, "ID=" SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->id));
-
- if (m->leader != 0)
- fprintf(f, "LEADER="PID_FMT"\n", m->leader);
-
- if (m->class != _MACHINE_CLASS_INVALID)
- fprintf(f, "CLASS=%s\n", machine_class_to_string(m->class));
-
- if (dual_timestamp_is_set(&m->timestamp))
- fprintf(f,
- "REALTIME="USEC_FMT"\n"
- "MONOTONIC="USEC_FMT"\n",
- m->timestamp.realtime,
- m->timestamp.monotonic);
-
- if (m->n_netif > 0) {
- unsigned i;
-
- fputs("NETIF=", f);
-
- for (i = 0; i < m->n_netif; i++) {
- if (i != 0)
- fputc(' ', f);
-
- fprintf(f, "%i", m->netif[i]);
- }
-
- fputc('\n', f);
- }
-
- r = fflush_and_check(f);
- if (r < 0)
- goto fail;
-
- if (rename(temp_path, m->state_file) < 0) {
- r = -errno;
- goto fail;
- }
-
- if (m->unit) {
- char *sl;
-
- /* Create a symlink from the unit name to the machine
- * name, so that we can quickly find the machine for
- * each given unit. Ignore error. */
- sl = strjoina("/run/systemd/machines/unit:", m->unit);
- (void) symlink(m->name, sl);
- }
-
- return 0;
-
-fail:
- (void) unlink(m->state_file);
-
- if (temp_path)
- (void) unlink(temp_path);
-
- return log_error_errno(r, "Failed to save machine data %s: %m", m->state_file);
-}
-
-static void machine_unlink(Machine *m) {
- assert(m);
-
- if (m->unit) {
-
- char *sl;
-
- sl = strjoina("/run/systemd/machines/unit:", m->unit);
- (void) unlink(sl);
- }
-
- if (m->state_file)
- (void) unlink(m->state_file);
-}
-
-int machine_load(Machine *m) {
- _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL, *netif = NULL;
- int r;
-
- assert(m);
-
- if (!m->state_file)
- return 0;
-
- r = parse_env_file(m->state_file, NEWLINE,
- "SCOPE", &m->unit,
- "SCOPE_JOB", &m->scope_job,
- "SERVICE", &m->service,
- "ROOT", &m->root_directory,
- "ID", &id,
- "LEADER", &leader,
- "CLASS", &class,
- "REALTIME", &realtime,
- "MONOTONIC", &monotonic,
- "NETIF", &netif,
- NULL);
- if (r < 0) {
- if (r == -ENOENT)
- return 0;
-
- return log_error_errno(r, "Failed to read %s: %m", m->state_file);
- }
-
- if (id)
- sd_id128_from_string(id, &m->id);
-
- if (leader)
- parse_pid(leader, &m->leader);
-
- if (class) {
- MachineClass c;
-
- c = machine_class_from_string(class);
- if (c >= 0)
- m->class = c;
- }
-
- if (realtime)
- timestamp_deserialize(realtime, &m->timestamp.realtime);
- if (monotonic)
- timestamp_deserialize(monotonic, &m->timestamp.monotonic);
-
- if (netif) {
- size_t allocated = 0, nr = 0;
- const char *p;
- int *ni = NULL;
-
- p = netif;
- for (;;) {
- _cleanup_free_ char *word = NULL;
- int ifi;
-
- r = extract_first_word(&p, &word, NULL, 0);
- if (r == 0)
- break;
- if (r == -ENOMEM)
- return log_oom();
- if (r < 0) {
- log_warning_errno(r, "Failed to parse NETIF: %s", netif);
- break;
- }
-
- if (parse_ifindex(word, &ifi) < 0)
- continue;
-
- if (!GREEDY_REALLOC(ni, allocated, nr+1)) {
- free(ni);
- return log_oom();
- }
-
- ni[nr++] = ifi;
- }
-
- free(m->netif);
- m->netif = ni;
- m->n_netif = nr;
- }
-
- return r;
-}
-
-static int machine_start_scope(Machine *m, sd_bus_message *properties, sd_bus_error *error) {
- int r = 0;
-
- assert(m);
- assert(m->class != MACHINE_HOST);
-
- if (!m->unit) {
- _cleanup_free_ char *escaped = NULL;
- char *scope, *description, *job = NULL;
-
- escaped = unit_name_escape(m->name);
- if (!escaped)
- return log_oom();
-
- scope = strjoin("machine-", escaped, ".scope", NULL);
- if (!scope)
- return log_oom();
-
- description = strjoina(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name);
-
- r = manager_start_scope(m->manager, scope, m->leader, SPECIAL_MACHINE_SLICE, description, properties, error, &job);
- if (r < 0) {
- log_error("Failed to start machine scope: %s", bus_error_message(error, r));
- free(scope);
- return r;
- } else {
- m->unit = scope;
-
- free(m->scope_job);
- m->scope_job = job;
- }
- }
-
- if (m->unit)
- hashmap_put(m->manager->machine_units, m->unit, m);
-
- return r;
-}
-
-int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) {
- int r;
-
- assert(m);
-
- if (!IN_SET(m->class, MACHINE_CONTAINER, MACHINE_VM))
- return -EOPNOTSUPP;
-
- if (m->started)
- return 0;
-
- r = hashmap_put(m->manager->machine_leaders, PID_TO_PTR(m->leader), m);
- if (r < 0)
- return r;
-
- /* Create cgroup */
- r = machine_start_scope(m, properties, error);
- if (r < 0)
- return r;
-
- log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_MACHINE_START),
- "NAME=%s", m->name,
- "LEADER="PID_FMT, m->leader,
- LOG_MESSAGE("New machine %s.", m->name),
- NULL);
-
- if (!dual_timestamp_is_set(&m->timestamp))
- dual_timestamp_get(&m->timestamp);
-
- m->started = true;
-
- /* Save new machine data */
- machine_save(m);
-
- machine_send_signal(m, true);
-
- return 0;
-}
-
-static int machine_stop_scope(Machine *m) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- char *job = NULL;
- int r;
-
- assert(m);
- assert(m->class != MACHINE_HOST);
-
- if (!m->unit)
- return 0;
-
- r = manager_stop_unit(m->manager, m->unit, &error, &job);
- if (r < 0) {
- log_error("Failed to stop machine scope: %s", bus_error_message(&error, r));
- return r;
- }
-
- free(m->scope_job);
- m->scope_job = job;
-
- return 0;
-}
-
-int machine_stop(Machine *m) {
- int r;
- assert(m);
-
- if (!IN_SET(m->class, MACHINE_CONTAINER, MACHINE_VM))
- return -EOPNOTSUPP;
-
- r = machine_stop_scope(m);
-
- m->stopping = true;
-
- machine_save(m);
-
- return r;
-}
-
-int machine_finalize(Machine *m) {
- assert(m);
-
- if (m->started)
- log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_MACHINE_STOP),
- "NAME=%s", m->name,
- "LEADER="PID_FMT, m->leader,
- LOG_MESSAGE("Machine %s terminated.", m->name),
- NULL);
-
- machine_unlink(m);
- machine_add_to_gc_queue(m);
-
- if (m->started) {
- machine_send_signal(m, false);
- m->started = false;
- }
-
- return 0;
-}
-
-bool machine_check_gc(Machine *m, bool drop_not_started) {
- assert(m);
-
- if (m->class == MACHINE_HOST)
- return true;
-
- if (drop_not_started && !m->started)
- return false;
-
- if (m->scope_job && manager_job_is_active(m->manager, m->scope_job))
- return true;
-
- if (m->unit && manager_unit_is_active(m->manager, m->unit))
- return true;
-
- return false;
-}
-
-void machine_add_to_gc_queue(Machine *m) {
- assert(m);
-
- if (m->in_gc_queue)
- return;
-
- LIST_PREPEND(gc_queue, m->manager->machine_gc_queue, m);
- m->in_gc_queue = true;
-}
-
-MachineState machine_get_state(Machine *s) {
- assert(s);
-
- if (s->class == MACHINE_HOST)
- return MACHINE_RUNNING;
-
- if (s->stopping)
- return MACHINE_CLOSING;
-
- if (s->scope_job)
- return MACHINE_OPENING;
-
- return MACHINE_RUNNING;
-}
-
-int machine_kill(Machine *m, KillWho who, int signo) {
- assert(m);
-
- if (!IN_SET(m->class, MACHINE_VM, MACHINE_CONTAINER))
- return -EOPNOTSUPP;
-
- if (!m->unit)
- return -ESRCH;
-
- if (who == KILL_LEADER) {
- /* If we shall simply kill the leader, do so directly */
-
- if (kill(m->leader, signo) < 0)
- return -errno;
-
- return 0;
- }
-
- /* Otherwise, make PID 1 do it for us, for the entire cgroup */
- return manager_kill_unit(m->manager, m->unit, signo, NULL);
-}
-
-int machine_openpt(Machine *m, int flags) {
- assert(m);
-
- switch (m->class) {
-
- case MACHINE_HOST: {
- int fd;
-
- fd = posix_openpt(flags);
- if (fd < 0)
- return -errno;
-
- if (unlockpt(fd) < 0)
- return -errno;
-
- return fd;
- }
-
- case MACHINE_CONTAINER:
- if (m->leader <= 0)
- return -EINVAL;
-
- return openpt_in_namespace(m->leader, flags);
-
- default:
- return -EOPNOTSUPP;
- }
-}
-
-int machine_open_terminal(Machine *m, const char *path, int mode) {
- assert(m);
-
- switch (m->class) {
-
- case MACHINE_HOST:
- return open_terminal(path, mode);
-
- case MACHINE_CONTAINER:
- if (m->leader <= 0)
- return -EINVAL;
-
- return open_terminal_in_namespace(m->leader, path, mode);
-
- default:
- return -EOPNOTSUPP;
- }
-}
-
-void machine_release_unit(Machine *m) {
- assert(m);
-
- if (!m->unit)
- return;
-
- (void) hashmap_remove(m->manager->machine_units, m->unit);
- m->unit = mfree(m->unit);
-}
-
-static const char* const machine_class_table[_MACHINE_CLASS_MAX] = {
- [MACHINE_CONTAINER] = "container",
- [MACHINE_VM] = "vm",
- [MACHINE_HOST] = "host",
-};
-
-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);
diff --git a/src/grp-machine/systemd-machined/machine.h b/src/grp-machine/systemd-machined/machine.h
deleted file mode 100644
index e93f0cf222..0000000000
--- a/src/grp-machine/systemd-machined/machine.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "basic/list.h"
-
-typedef enum KillWho KillWho;
-typedef struct Machine Machine;
-
-#include "machined.h"
-#include "operation.h"
-
-typedef enum MachineState {
- MACHINE_OPENING, /* Machine is being registered */
- MACHINE_RUNNING, /* Machine is running */
- MACHINE_CLOSING, /* Machine is terminating */
- _MACHINE_STATE_MAX,
- _MACHINE_STATE_INVALID = -1
-} MachineState;
-
-typedef enum MachineClass {
- MACHINE_CONTAINER,
- MACHINE_VM,
- MACHINE_HOST,
- _MACHINE_CLASS_MAX,
- _MACHINE_CLASS_INVALID = -1
-} MachineClass;
-
-enum KillWho {
- KILL_LEADER,
- KILL_ALL,
- _KILL_WHO_MAX,
- _KILL_WHO_INVALID = -1
-};
-
-struct Machine {
- Manager *manager;
-
- char *name;
- sd_id128_t id;
-
- MachineClass class;
-
- char *state_file;
- char *service;
- char *root_directory;
-
- char *unit;
- char *scope_job;
-
- pid_t leader;
-
- dual_timestamp timestamp;
-
- bool in_gc_queue:1;
- bool started:1;
- bool stopping:1;
-
- sd_bus_message *create_message;
-
- int *netif;
- unsigned n_netif;
-
- LIST_HEAD(Operation, operations);
-
- LIST_FIELDS(Machine, gc_queue);
-};
-
-Machine* machine_new(Manager *manager, MachineClass class, const char *name);
-void machine_free(Machine *m);
-bool machine_check_gc(Machine *m, bool drop_not_started);
-void machine_add_to_gc_queue(Machine *m);
-int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error);
-int machine_stop(Machine *m);
-int machine_finalize(Machine *m);
-int machine_save(Machine *m);
-int machine_load(Machine *m);
-int machine_kill(Machine *m, KillWho who, int signo);
-
-void machine_release_unit(Machine *m);
-
-MachineState machine_get_state(Machine *u);
-
-const char* machine_class_to_string(MachineClass t) _const_;
-MachineClass machine_class_from_string(const char *s) _pure_;
-
-const char* machine_state_to_string(MachineState t) _const_;
-MachineState machine_state_from_string(const char *s) _pure_;
-
-const char *kill_who_to_string(KillWho k) _const_;
-KillWho kill_who_from_string(const char *s) _pure_;
-
-int machine_openpt(Machine *m, int flags);
-int machine_open_terminal(Machine *m, const char *path, int mode);
diff --git a/src/grp-machine/systemd-machined/machined-dbus.c b/src/grp-machine/systemd-machined/machined-dbus.c
deleted file mode 100644
index 349ffcf298..0000000000
--- a/src/grp-machine/systemd-machined/machined-dbus.c
+++ /dev/null
@@ -1,1805 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <systemd/sd-id128.h>
-
-#include "basic/alloc-util.h"
-#include "basic/btrfs-util.h"
-#include "basic/cgroup-util.h"
-#include "basic/fd-util.h"
-#include "basic/fileio.h"
-#include "basic/formats-util.h"
-#include "basic/hostname-util.h"
-#include "basic/io-util.h"
-#include "basic/path-util.h"
-#include "basic/process-util.h"
-#include "basic/stdio-util.h"
-#include "basic/strv.h"
-#include "basic/unit-name.h"
-#include "basic/user-util.h"
-#include "sd-bus/bus-common-errors.h"
-#include "shared/bus-util.h"
-#include "shared/machine-image.h"
-#include "shared/machine-pool.h"
-
-#include "image-dbus.h"
-#include "machine-dbus.h"
-#include "machined.h"
-
-static int property_get_pool_path(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- assert(bus);
- assert(reply);
-
- return sd_bus_message_append(reply, "s", "/var/lib/machines");
-}
-
-static int property_get_pool_usage(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- _cleanup_close_ int fd = -1;
- uint64_t usage = (uint64_t) -1;
- struct stat st;
-
- assert(bus);
- assert(reply);
-
- /* We try to read the quota info from /var/lib/machines, as
- * well as the usage of the loopback file
- * /var/lib/machines.raw, and pick the larger value. */
-
- fd = open("/var/lib/machines", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
- if (fd >= 0) {
- BtrfsQuotaInfo q;
-
- if (btrfs_subvol_get_subtree_quota_fd(fd, 0, &q) >= 0)
- usage = q.referenced;
- }
-
- if (stat("/var/lib/machines.raw", &st) >= 0) {
- if (usage == (uint64_t) -1 || st.st_blocks * 512ULL > usage)
- usage = st.st_blocks * 512ULL;
- }
-
- return sd_bus_message_append(reply, "t", usage);
-}
-
-static int property_get_pool_limit(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- _cleanup_close_ int fd = -1;
- uint64_t size = (uint64_t) -1;
- struct stat st;
-
- assert(bus);
- assert(reply);
-
- /* We try to read the quota limit from /var/lib/machines, as
- * well as the size of the loopback file
- * /var/lib/machines.raw, and pick the smaller value. */
-
- fd = open("/var/lib/machines", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
- if (fd >= 0) {
- BtrfsQuotaInfo q;
-
- if (btrfs_subvol_get_subtree_quota_fd(fd, 0, &q) >= 0)
- size = q.referenced_max;
- }
-
- if (stat("/var/lib/machines.raw", &st) >= 0) {
- if (size == (uint64_t) -1 || (uint64_t) st.st_size < size)
- size = st.st_size;
- }
-
- return sd_bus_message_append(reply, "t", size);
-}
-
-static int method_get_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *p = NULL;
- Manager *m = userdata;
- Machine *machine;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- p = machine_bus_path(machine);
- if (!p)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "o", p);
-}
-
-static int method_get_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *p = NULL;
- Manager *m = userdata;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- r = image_find(name, NULL);
- if (r == 0)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
- if (r < 0)
- return r;
-
- p = image_bus_path(name);
- if (!p)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "o", p);
-}
-
-static int method_get_machine_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *p = NULL;
- Manager *m = userdata;
- Machine *machine = NULL;
- pid_t pid;
- int r;
-
- assert(message);
- assert(m);
-
- assert_cc(sizeof(pid_t) == sizeof(uint32_t));
-
- r = sd_bus_message_read(message, "u", &pid);
- if (r < 0)
- return r;
-
- if (pid < 0)
- return -EINVAL;
-
- if (pid == 0) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r < 0)
- return r;
- }
-
- r = manager_get_machine_by_pid(m, pid, &machine);
- if (r < 0)
- return r;
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_MACHINE_FOR_PID, "PID "PID_FMT" does not belong to any known machine", pid);
-
- p = machine_bus_path(machine);
- if (!p)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "o", p);
-}
-
-static int method_list_machines(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- Manager *m = userdata;
- Machine *machine;
- Iterator i;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
-
- r = sd_bus_message_open_container(reply, 'a', "(ssso)");
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
-
- HASHMAP_FOREACH(machine, m->machines, i) {
- _cleanup_free_ char *p = NULL;
-
- p = machine_bus_path(machine);
- if (!p)
- return -ENOMEM;
-
- r = sd_bus_message_append(reply, "(ssso)",
- machine->name,
- strempty(machine_class_to_string(machine->class)),
- machine->service,
- p);
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
-
- return sd_bus_send(NULL, reply, NULL);
-}
-
-static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, bool read_network, Machine **_m, sd_bus_error *error) {
- const char *name, *service, *class, *root_directory;
- const int32_t *netif = NULL;
- MachineClass c;
- uint32_t leader;
- sd_id128_t id;
- const void *v;
- Machine *m;
- size_t n, n_netif = 0;
- int r;
-
- assert(manager);
- assert(message);
- assert(_m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
- if (!machine_name_is_valid(name))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine name");
-
- r = sd_bus_message_read_array(message, 'y', &v, &n);
- if (r < 0)
- return r;
- if (n == 0)
- id = SD_ID128_NULL;
- else if (n == 16)
- memcpy(&id, v, n);
- else
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine ID parameter");
-
- r = sd_bus_message_read(message, "ssus", &service, &class, &leader, &root_directory);
- if (r < 0)
- return r;
-
- if (read_network) {
- size_t i;
-
- r = sd_bus_message_read_array(message, 'i', (const void**) &netif, &n_netif);
- if (r < 0)
- return r;
-
- n_netif /= sizeof(int32_t);
-
- for (i = 0; i < n_netif; i++) {
- if (netif[i] <= 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid network interface index %i", netif[i]);
- }
- }
-
- if (isempty(class))
- c = _MACHINE_CLASS_INVALID;
- else {
- c = machine_class_from_string(class);
- if (c < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine class parameter");
- }
-
- if (leader == 1)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
-
- if (!isempty(root_directory) && !path_is_absolute(root_directory))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root directory must be empty or an absolute path");
-
- if (leader == 0) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- assert_cc(sizeof(uint32_t) == sizeof(pid_t));
-
- r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
- if (r < 0)
- return r;
- }
-
- if (hashmap_get(manager->machines, name))
- return sd_bus_error_setf(error, BUS_ERROR_MACHINE_EXISTS, "Machine '%s' already exists", name);
-
- r = manager_add_machine(manager, name, &m);
- if (r < 0)
- return r;
-
- m->leader = leader;
- m->class = c;
- m->id = id;
-
- if (!isempty(service)) {
- m->service = strdup(service);
- if (!m->service) {
- r = -ENOMEM;
- goto fail;
- }
- }
-
- if (!isempty(root_directory)) {
- m->root_directory = strdup(root_directory);
- if (!m->root_directory) {
- r = -ENOMEM;
- goto fail;
- }
- }
-
- if (n_netif > 0) {
- assert_cc(sizeof(int32_t) == sizeof(int));
- m->netif = memdup(netif, sizeof(int32_t) * n_netif);
- if (!m->netif) {
- r = -ENOMEM;
- goto fail;
- }
-
- m->n_netif = n_netif;
- }
-
- *_m = m;
-
- return 1;
-
-fail:
- machine_add_to_gc_queue(m);
- return r;
-}
-
-static int method_create_machine_internal(sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
- Manager *manager = userdata;
- Machine *m = NULL;
- int r;
-
- assert(message);
- assert(manager);
-
- r = method_create_or_register_machine(manager, message, read_network, &m, error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_enter_container(message, 'a', "(sv)");
- if (r < 0)
- goto fail;
-
- r = machine_start(m, message, error);
- if (r < 0)
- goto fail;
-
- m->create_message = sd_bus_message_ref(message);
- return 1;
-
-fail:
- machine_add_to_gc_queue(m);
- return r;
-}
-
-static int method_create_machine_with_network(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_create_machine_internal(message, true, userdata, error);
-}
-
-static int method_create_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_create_machine_internal(message, false, userdata, error);
-}
-
-static int method_register_machine_internal(sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
- Manager *manager = userdata;
- _cleanup_free_ char *p = NULL;
- Machine *m = NULL;
- int r;
-
- assert(message);
- assert(manager);
-
- r = method_create_or_register_machine(manager, message, read_network, &m, error);
- if (r < 0)
- return r;
-
- r = cg_pid_get_unit(m->leader, &m->unit);
- if (r < 0) {
- r = sd_bus_error_set_errnof(error, r, "Failed to determine unit of process "PID_FMT" : %s", m->leader, strerror(-r));
- goto fail;
- }
-
- r = machine_start(m, NULL, error);
- if (r < 0)
- goto fail;
-
- p = machine_bus_path(m);
- if (!p) {
- r = -ENOMEM;
- goto fail;
- }
-
- return sd_bus_reply_method_return(message, "o", p);
-
-fail:
- machine_add_to_gc_queue(m);
- return r;
-}
-
-static int method_register_machine_with_network(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_register_machine_internal(message, true, userdata, error);
-}
-
-static int method_register_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_register_machine_internal(message, false, userdata, error);
-}
-
-static int method_terminate_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- return bus_machine_method_terminate(message, machine, error);
-}
-
-static int method_kill_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- return bus_machine_method_kill(message, machine, error);
-}
-
-static int method_get_machine_addresses(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- return bus_machine_method_get_addresses(message, machine, error);
-}
-
-static int method_get_machine_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- return bus_machine_method_get_os_release(message, machine, error);
-}
-
-static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
- Manager *m = userdata;
- Image *image;
- Iterator i;
- int r;
-
- assert(message);
- assert(m);
-
- images = hashmap_new(&string_hash_ops);
- if (!images)
- return -ENOMEM;
-
- r = image_discover(images);
- if (r < 0)
- return r;
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(reply, 'a', "(ssbttto)");
- if (r < 0)
- return r;
-
- HASHMAP_FOREACH(image, images, i) {
- _cleanup_free_ char *p = NULL;
-
- p = image_bus_path(image->name);
- if (!p)
- return -ENOMEM;
-
- r = sd_bus_message_append(reply, "(ssbttto)",
- image->name,
- image_type_to_string(image->type),
- image->read_only,
- image->crtime,
- image->mtime,
- image->usage,
- p);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
-
- return sd_bus_send(NULL, reply, NULL);
-}
-
-static int method_open_machine_pty(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- return bus_machine_method_open_pty(message, machine, error);
-}
-
-static int method_open_machine_login(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- return bus_machine_method_open_login(message, machine, error);
-}
-
-static int method_open_machine_shell(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- const char *name;
-
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- return bus_machine_method_open_shell(message, machine, error);
-}
-
-static int method_bind_mount_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- return bus_machine_method_bind_mount(message, machine, error);
-}
-
-static int method_copy_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- return bus_machine_method_copy(message, machine, error);
-}
-
-static int method_open_machine_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- const char *name;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- return bus_machine_method_open_root_directory(message, machine, error);
-}
-
-static int method_remove_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(image_unrefp) Image* i = NULL;
- const char *name;
- int r;
-
- assert(message);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- if (!image_name_is_valid(name))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
-
- r = image_find(name, &i);
- if (r < 0)
- return r;
- if (r == 0)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
-
- i->userdata = userdata;
- return bus_image_method_remove(message, i, error);
-}
-
-static int method_rename_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(image_unrefp) Image* i = NULL;
- const char *old_name;
- int r;
-
- assert(message);
-
- r = sd_bus_message_read(message, "s", &old_name);
- if (r < 0)
- return r;
-
- if (!image_name_is_valid(old_name))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name);
-
- r = image_find(old_name, &i);
- if (r < 0)
- return r;
- if (r == 0)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", old_name);
-
- i->userdata = userdata;
- return bus_image_method_rename(message, i, error);
-}
-
-static int method_clone_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(image_unrefp) Image *i = NULL;
- const char *old_name;
- int r;
-
- assert(message);
-
- r = sd_bus_message_read(message, "s", &old_name);
- if (r < 0)
- return r;
-
- if (!image_name_is_valid(old_name))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name);
-
- r = image_find(old_name, &i);
- if (r < 0)
- return r;
- if (r == 0)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", old_name);
-
- i->userdata = userdata;
- return bus_image_method_clone(message, i, error);
-}
-
-static int method_mark_image_read_only(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(image_unrefp) Image *i = NULL;
- const char *name;
- int r;
-
- assert(message);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- if (!image_name_is_valid(name))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
-
- r = image_find(name, &i);
- if (r < 0)
- return r;
- if (r == 0)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
-
- i->userdata = userdata;
- return bus_image_method_mark_read_only(message, i, error);
-}
-
-static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- bool success;
- size_t n;
- int r;
-
- assert(operation);
- assert(operation->extra_fd >= 0);
-
- if (lseek(operation->extra_fd, 0, SEEK_SET) == (off_t) -1)
- return -errno;
-
- f = fdopen(operation->extra_fd, "re");
- if (!f)
- return -errno;
-
- operation->extra_fd = -1;
-
- /* The resulting temporary file starts with a boolean value that indicates success or not. */
- errno = 0;
- n = fread(&success, 1, sizeof(success), f);
- if (n != sizeof(success))
- return ret < 0 ? ret : (errno != 0 ? -errno : -EIO);
-
- if (ret < 0) {
- _cleanup_free_ char *name = NULL;
-
- /* The clean-up operation failed. In this case the resulting temporary file should contain a boolean
- * set to false followed by the name of the failed image. Let's try to read this and use it for the
- * error message. If we can't read it, don't mind, and return the naked error. */
-
- if (success) /* The resulting temporary file could not be updated, ignore it. */
- return ret;
-
- r = read_nul_string(f, &name);
- if (r < 0 || isempty(name)) /* Same here... */
- return ret;
-
- return sd_bus_error_set_errnof(error, ret, "Failed to remove image %s: %m", name);
- }
-
- assert(success);
-
- r = sd_bus_message_new_method_return(operation->message, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(reply, 'a', "(st)");
- if (r < 0)
- return r;
-
- /* On success the resulting temporary file will contain a list of image names that were removed followed by
- * their size on disk. Let's read that and turn it into a bus message. */
- for (;;) {
- _cleanup_free_ char *name = NULL;
- uint64_t size;
-
- r = read_nul_string(f, &name);
- if (r < 0)
- return r;
- if (isempty(name)) /* reached the end */
- break;
-
- errno = 0;
- n = fread(&size, 1, sizeof(size), f);
- if (n != sizeof(size))
- return errno != 0 ? -errno : -EIO;
-
- r = sd_bus_message_append(reply, "(st)", name, size);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
-
- return sd_bus_send(NULL, reply, NULL);
-}
-
-static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- enum {
- REMOVE_ALL,
- REMOVE_HIDDEN,
- } mode;
-
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
- _cleanup_close_ int result_fd = -1;
- Manager *m = userdata;
- Operation *operation;
- const char *mm;
- pid_t child;
- int r;
-
- assert(message);
-
- if (m->n_operations >= OPERATIONS_MAX)
- return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
-
- r = sd_bus_message_read(message, "s", &mm);
- if (r < 0)
- return r;
-
- if (streq(mm, "all"))
- mode = REMOVE_ALL;
- else if (streq(mm, "hidden"))
- mode = REMOVE_HIDDEN;
- else
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mode '%s'.", mm);
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- "org.freedesktop.machine1.manage-machines",
- NULL,
- false,
- UID_INVALID,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
-
- /* Create a temporary file we can dump information about deleted images into. We use a temporary file for this
- * instead of a pipe or so, since this might grow quit large in theory and we don't want to process this
- * continuously */
- result_fd = open_tmpfile_unlinkable("/tmp/", O_RDWR|O_CLOEXEC);
- if (result_fd < 0)
- return -errno;
-
- /* This might be a slow operation, run it asynchronously in a background process */
- child = fork();
- if (child < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
-
- if (child == 0) {
- _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
- bool success = true;
- Image *image;
- Iterator i;
- ssize_t l;
-
- errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
-
- images = hashmap_new(&string_hash_ops);
- if (!images) {
- r = -ENOMEM;
- goto child_fail;
- }
-
- r = image_discover(images);
- if (r < 0)
- goto child_fail;
-
- l = write(result_fd, &success, sizeof(success));
- if (l < 0) {
- r = -errno;
- goto child_fail;
- }
-
- HASHMAP_FOREACH(image, images, i) {
-
- /* We can't remove vendor images (i.e. those in /usr) */
- if (IMAGE_IS_VENDOR(image))
- continue;
-
- if (IMAGE_IS_HOST(image))
- continue;
-
- if (mode == REMOVE_HIDDEN && !IMAGE_IS_HIDDEN(image))
- continue;
-
- r = image_remove(image);
- if (r == -EBUSY) /* keep images that are currently being used. */
- continue;
- if (r < 0) {
- /* If the operation failed, let's override everything we wrote, and instead write there at which image we failed. */
- success = false;
- (void) ftruncate(result_fd, 0);
- (void) lseek(result_fd, 0, SEEK_SET);
- (void) write(result_fd, &success, sizeof(success));
- (void) write(result_fd, image->name, strlen(image->name)+1);
- goto child_fail;
- }
-
- l = write(result_fd, image->name, strlen(image->name)+1);
- if (l < 0) {
- r = -errno;
- goto child_fail;
- }
-
- l = write(result_fd, &image->usage_exclusive, sizeof(image->usage_exclusive));
- if (l < 0) {
- r = -errno;
- goto child_fail;
- }
- }
-
- result_fd = safe_close(result_fd);
- _exit(EXIT_SUCCESS);
-
- child_fail:
- (void) write(errno_pipe_fd[1], &r, sizeof(r));
- _exit(EXIT_FAILURE);
- }
-
- errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
-
- /* The clean-up might take a while, hence install a watch on the child and return */
-
- r = operation_new(m, NULL, child, message, errno_pipe_fd[0], &operation);
- if (r < 0) {
- (void) sigkill_wait(child);
- return r;
- }
-
- operation->extra_fd = result_fd;
- operation->done = clean_pool_done;
-
- result_fd = -1;
- errno_pipe_fd[0] = -1;
-
- return 1;
-}
-
-static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- uint64_t limit;
- int r;
-
- assert(message);
-
- r = sd_bus_message_read(message, "t", &limit);
- if (r < 0)
- return r;
- if (!FILE_SIZE_VALID_OR_INFINITY(limit))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
-
- r = bus_verify_polkit_async(
- message,
- CAP_SYS_ADMIN,
- "org.freedesktop.machine1.manage-machines",
- NULL,
- false,
- UID_INVALID,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
-
- /* Set up the machine directory if necessary */
- r = setup_machine_directory(limit, error);
- if (r < 0)
- return r;
-
- /* Resize the backing loopback device, if there is one, except if we asked to drop any limit */
- if (limit != (uint64_t) -1) {
- r = btrfs_resize_loopback("/var/lib/machines", limit, false);
- if (r == -ENOTTY)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs.");
- if (r < 0 && r != -ENODEV) /* ignore ENODEV, as that's what is returned if the file system is not on loopback */
- return sd_bus_error_set_errnof(error, r, "Failed to adjust loopback limit: %m");
- }
-
- (void) btrfs_qgroup_set_limit("/var/lib/machines", 0, limit);
-
- r = btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, limit);
- if (r == -ENOTTY)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs.");
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to adjust quota limit: %m");
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_set_image_limit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(image_unrefp) Image *i = NULL;
- const char *name;
- int r;
-
- assert(message);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- if (!image_name_is_valid(name))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
-
- r = image_find(name, &i);
- if (r < 0)
- return r;
- if (r == 0)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
-
- i->userdata = userdata;
- return bus_image_method_set_limit(message, i, error);
-}
-
-static int method_map_from_machine_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_fclose_ FILE *f = NULL;
- Manager *m = userdata;
- const char *name, *p;
- Machine *machine;
- uint32_t uid;
- int r;
-
- r = sd_bus_message_read(message, "su", &name, &uid);
- if (r < 0)
- return r;
-
- if (!uid_is_valid(uid))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- if (machine->class != MACHINE_CONTAINER)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Not supported for non-container machines.");
-
- p = procfs_file_alloca(machine->leader, "uid_map");
- f = fopen(p, "re");
- if (!f)
- return -errno;
-
- for (;;) {
- uid_t uid_base, uid_shift, uid_range, converted;
- int k;
-
- errno = 0;
- k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range);
- if (k < 0 && feof(f))
- break;
- if (k != 3) {
- if (ferror(f) && errno > 0)
- return -errno;
-
- return -EIO;
- }
-
- if (uid < uid_base || uid >= uid_base + uid_range)
- continue;
-
- converted = uid - uid_base + uid_shift;
- if (!uid_is_valid(converted))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
-
- return sd_bus_reply_method_return(message, "u", (uint32_t) converted);
- }
-
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER_MAPPING, "Machine '%s' has no matching user mappings.", name);
-}
-
-static int method_map_to_machine_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- uid_t uid;
- Iterator i;
- int r;
-
- r = sd_bus_message_read(message, "u", &uid);
- if (r < 0)
- return r;
- if (!uid_is_valid(uid))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
- if (uid < 0x10000)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER_MAPPING, "User " UID_FMT " belongs to host UID range", uid);
-
- HASHMAP_FOREACH(machine, m->machines, i) {
- _cleanup_fclose_ FILE *f = NULL;
- char p[strlen("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
-
- if (machine->class != MACHINE_CONTAINER)
- continue;
-
- xsprintf(p, "/proc/" UID_FMT "/uid_map", machine->leader);
- f = fopen(p, "re");
- if (!f) {
- log_warning_errno(errno, "Failed top open %s, ignoring,", p);
- continue;
- }
-
- for (;;) {
- _cleanup_free_ char *o = NULL;
- uid_t uid_base, uid_shift, uid_range, converted;
- int k;
-
- errno = 0;
- k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range);
- if (k < 0 && feof(f))
- break;
- if (k != 3) {
- if (ferror(f) && errno > 0)
- return -errno;
-
- return -EIO;
- }
-
- if (uid < uid_shift || uid >= uid_shift + uid_range)
- continue;
-
- converted = (uid - uid_shift + uid_base);
- if (!uid_is_valid(converted))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
-
- o = machine_bus_path(machine);
- if (!o)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "sou", machine->name, o, (uint32_t) converted);
- }
- }
-
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER_MAPPING, "No matching user mapping for " UID_FMT ".", uid);
-}
-
-static int method_map_from_machine_group(sd_bus_message *message, void *groupdata, sd_bus_error *error) {
- _cleanup_fclose_ FILE *f = NULL;
- Manager *m = groupdata;
- const char *name, *p;
- Machine *machine;
- uint32_t gid;
- int r;
-
- r = sd_bus_message_read(message, "su", &name, &gid);
- if (r < 0)
- return r;
-
- if (!gid_is_valid(gid))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
-
- machine = hashmap_get(m->machines, name);
- if (!machine)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
-
- if (machine->class != MACHINE_CONTAINER)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Not supported for non-container machines.");
-
- p = procfs_file_alloca(machine->leader, "gid_map");
- f = fopen(p, "re");
- if (!f)
- return -errno;
-
- for (;;) {
- gid_t gid_base, gid_shift, gid_range, converted;
- int k;
-
- errno = 0;
- k = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT, &gid_base, &gid_shift, &gid_range);
- if (k < 0 && feof(f))
- break;
- if (k != 3) {
- if (ferror(f) && errno > 0)
- return -errno;
-
- return -EIO;
- }
-
- if (gid < gid_base || gid >= gid_base + gid_range)
- continue;
-
- converted = gid - gid_base + gid_shift;
- if (!gid_is_valid(converted))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
-
- return sd_bus_reply_method_return(message, "u", (uint32_t) converted);
- }
-
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_GROUP_MAPPING, "Machine '%s' has no matching group mappings.", name);
-}
-
-static int method_map_to_machine_group(sd_bus_message *message, void *groupdata, sd_bus_error *error) {
- Manager *m = groupdata;
- Machine *machine;
- gid_t gid;
- Iterator i;
- int r;
-
- r = sd_bus_message_read(message, "u", &gid);
- if (r < 0)
- return r;
- if (!gid_is_valid(gid))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
- if (gid < 0x10000)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_GROUP_MAPPING, "Group " GID_FMT " belongs to host GID range", gid);
-
- HASHMAP_FOREACH(machine, m->machines, i) {
- _cleanup_fclose_ FILE *f = NULL;
- char p[strlen("/proc//gid_map") + DECIMAL_STR_MAX(pid_t) + 1];
-
- if (machine->class != MACHINE_CONTAINER)
- continue;
-
- xsprintf(p, "/proc/" GID_FMT "/gid_map", machine->leader);
- f = fopen(p, "re");
- if (!f) {
- log_warning_errno(errno, "Failed top open %s, ignoring,", p);
- continue;
- }
-
- for (;;) {
- _cleanup_free_ char *o = NULL;
- gid_t gid_base, gid_shift, gid_range, converted;
- int k;
-
- errno = 0;
- k = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT, &gid_base, &gid_shift, &gid_range);
- if (k < 0 && feof(f))
- break;
- if (k != 3) {
- if (ferror(f) && errno > 0)
- return -errno;
-
- return -EIO;
- }
-
- if (gid < gid_shift || gid >= gid_shift + gid_range)
- continue;
-
- converted = (gid - gid_shift + gid_base);
- if (!gid_is_valid(converted))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
-
- o = machine_bus_path(machine);
- if (!o)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "sou", machine->name, o, (uint32_t) converted);
- }
- }
-
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_GROUP_MAPPING, "No matching group mapping for " GID_FMT ".", gid);
-}
-
-const sd_bus_vtable manager_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("PoolPath", "s", property_get_pool_path, 0, 0),
- SD_BUS_PROPERTY("PoolUsage", "t", property_get_pool_usage, 0, 0),
- SD_BUS_PROPERTY("PoolLimit", "t", property_get_pool_limit, 0, 0),
- SD_BUS_METHOD("GetMachine", "s", "o", method_get_machine, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetImage", "s", "o", method_get_image, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetMachineByPID", "u", "o", method_get_machine_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ListMachines", NULL, "a(ssso)", method_list_machines, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ListImages", NULL, "a(ssbttto)", method_list_images, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CreateMachine", "sayssusa(sv)", "o", method_create_machine, 0),
- SD_BUS_METHOD("CreateMachineWithNetwork", "sayssusaia(sv)", "o", method_create_machine_with_network, 0),
- SD_BUS_METHOD("RegisterMachine", "sayssus", "o", method_register_machine, 0),
- SD_BUS_METHOD("RegisterMachineWithNetwork", "sayssusai", "o", method_register_machine_with_network, 0),
- SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("KillMachine", "ssi", NULL, method_kill_machine, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetMachineAddresses", "s", "a(iay)", method_get_machine_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetMachineOSRelease", "s", "a{ss}", method_get_machine_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("OpenMachinePTY", "s", "hs", method_open_machine_pty, 0),
- SD_BUS_METHOD("OpenMachineLogin", "s", "hs", method_open_machine_login, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("OpenMachineShell", "sssasas", "hs", method_open_machine_shell, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("BindMountMachine", "sssbb", NULL, method_bind_mount_machine, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CopyFromMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CopyToMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("OpenMachineRootDirectory", "s", "h", method_open_machine_root_directory, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("RemoveImage", "s", NULL, method_remove_image, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("RenameImage", "ss", NULL, method_rename_image, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CloneImage", "ssb", NULL, method_clone_image, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("MarkImageReadOnly", "sb", NULL, method_mark_image_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("SetPoolLimit", "t", NULL, method_set_pool_limit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("SetImageLimit", "st", NULL, method_set_image_limit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CleanPool", "s", "a(st)", method_clean_pool, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("MapFromMachineUser", "su", "u", method_map_from_machine_user, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("MapToMachineUser", "u", "sou", method_map_to_machine_user, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("MapFromMachineGroup", "su", "u", method_map_from_machine_group, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("MapToMachineGroup", "u", "sou", method_map_to_machine_group, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_SIGNAL("MachineNew", "so", 0),
- SD_BUS_SIGNAL("MachineRemoved", "so", 0),
- SD_BUS_VTABLE_END
-};
-
-int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- const char *path, *result, *unit;
- Manager *m = userdata;
- Machine *machine;
- uint32_t id;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
- if (r < 0) {
- bus_log_parse_error(r);
- return 0;
- }
-
- machine = hashmap_get(m->machine_units, unit);
- if (!machine)
- return 0;
-
- if (streq_ptr(path, machine->scope_job)) {
- machine->scope_job = mfree(machine->scope_job);
-
- if (machine->started) {
- if (streq(result, "done"))
- machine_send_create_reply(machine, NULL);
- else {
- _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
-
- sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
-
- machine_send_create_reply(machine, &e);
- }
- }
-
- machine_save(machine);
- }
-
- machine_add_to_gc_queue(machine);
- return 0;
-}
-
-int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *unit = NULL;
- const char *path;
- Manager *m = userdata;
- Machine *machine;
- int r;
-
- assert(message);
- assert(m);
-
- path = sd_bus_message_get_path(message);
- if (!path)
- return 0;
-
- r = unit_name_from_dbus_path(path, &unit);
- if (r == -EINVAL) /* not for a unit */
- return 0;
- if (r < 0) {
- log_oom();
- return 0;
- }
-
- machine = hashmap_get(m->machine_units, unit);
- if (!machine)
- return 0;
-
- machine_add_to_gc_queue(machine);
- return 0;
-}
-
-int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- const char *path, *unit;
- Manager *m = userdata;
- Machine *machine;
- int r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "so", &unit, &path);
- if (r < 0) {
- bus_log_parse_error(r);
- return 0;
- }
-
- machine = hashmap_get(m->machine_units, unit);
- if (!machine)
- return 0;
-
- machine_add_to_gc_queue(machine);
- return 0;
-}
-
-int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- Machine *machine;
- Iterator i;
- int b, r;
-
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0) {
- bus_log_parse_error(r);
- return 0;
- }
- if (b)
- return 0;
-
- /* systemd finished reloading, let's recheck all our machines */
- log_debug("System manager has been reloaded, rechecking machines...");
-
- HASHMAP_FOREACH(machine, m->machines, i)
- machine_add_to_gc_queue(machine);
-
- return 0;
-}
-
-int manager_start_scope(
- Manager *manager,
- const char *scope,
- pid_t pid,
- const char *slice,
- const char *description,
- sd_bus_message *more_properties,
- sd_bus_error *error,
- char **job) {
-
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
- int r;
-
- assert(manager);
- assert(scope);
- assert(pid > 1);
-
- r = sd_bus_message_new_method_call(
- manager->bus,
- &m,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "StartTransientUnit");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(m, 'a', "(sv)");
- if (r < 0)
- return r;
-
- if (!isempty(slice)) {
- r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
- if (r < 0)
- return r;
- }
-
- if (!isempty(description)) {
- r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(m, "(sv)", "Delegate", "b", 1);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", UINT64_C(16384));
- if (r < 0)
- return bus_log_create_error(r);
-
- if (more_properties) {
- r = sd_bus_message_copy(m, more_properties, true);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(m, "a(sa(sv))", 0);
- if (r < 0)
- return r;
-
- r = sd_bus_call(manager->bus, m, 0, error, &reply);
- if (r < 0)
- return r;
-
- if (job) {
- const char *j;
- char *copy;
-
- r = sd_bus_message_read(reply, "o", &j);
- if (r < 0)
- return r;
-
- copy = strdup(j);
- if (!copy)
- return -ENOMEM;
-
- *job = copy;
- }
-
- return 1;
-}
-
-int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- int r;
-
- assert(manager);
- assert(unit);
-
- r = sd_bus_call_method(
- manager->bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "StopUnit",
- error,
- &reply,
- "ss", unit, "fail");
- if (r < 0) {
- if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
- sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
-
- if (job)
- *job = NULL;
-
- sd_bus_error_free(error);
- return 0;
- }
-
- return r;
- }
-
- if (job) {
- const char *j;
- char *copy;
-
- r = sd_bus_message_read(reply, "o", &j);
- if (r < 0)
- return r;
-
- copy = strdup(j);
- if (!copy)
- return -ENOMEM;
-
- *job = copy;
- }
-
- return 1;
-}
-
-int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error) {
- assert(manager);
- assert(unit);
-
- return sd_bus_call_method(
- manager->bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "KillUnit",
- error,
- NULL,
- "ssi", unit, "all", signo);
-}
-
-int manager_unit_is_active(Manager *manager, const char *unit) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_free_ char *path = NULL;
- const char *state;
- int r;
-
- assert(manager);
- assert(unit);
-
- path = unit_dbus_path_from_name(unit);
- if (!path)
- return -ENOMEM;
-
- r = sd_bus_get_property(
- manager->bus,
- "org.freedesktop.systemd1",
- path,
- "org.freedesktop.systemd1.Unit",
- "ActiveState",
- &error,
- &reply,
- "s");
- if (r < 0) {
- if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
- sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
- return true;
-
- if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
- sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
- return false;
-
- return r;
- }
-
- r = sd_bus_message_read(reply, "s", &state);
- if (r < 0)
- return -EINVAL;
-
- return !STR_IN_SET(state, "inactive", "failed");
-}
-
-int manager_job_is_active(Manager *manager, const char *path) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- int r;
-
- assert(manager);
- assert(path);
-
- r = sd_bus_get_property(
- manager->bus,
- "org.freedesktop.systemd1",
- path,
- "org.freedesktop.systemd1.Job",
- "State",
- &error,
- &reply,
- "s");
- if (r < 0) {
- if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
- sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
- return true;
-
- if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
- return false;
-
- return r;
- }
-
- /* We don't actually care about the state really. The fact
- * that we could read the job state is enough for us */
-
- return true;
-}
-
-int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) {
- Machine *mm;
- int r;
-
- assert(m);
- assert(pid >= 1);
- assert(machine);
-
- mm = hashmap_get(m->machine_leaders, PID_TO_PTR(pid));
- if (!mm) {
- _cleanup_free_ char *unit = NULL;
-
- r = cg_pid_get_unit(pid, &unit);
- if (r >= 0)
- mm = hashmap_get(m->machine_units, unit);
- }
- if (!mm)
- return 0;
-
- *machine = mm;
- return 1;
-}
-
-int manager_add_machine(Manager *m, const char *name, Machine **_machine) {
- Machine *machine;
-
- assert(m);
- assert(name);
-
- machine = hashmap_get(m->machines, name);
- if (!machine) {
- machine = machine_new(m, _MACHINE_CLASS_INVALID, name);
- if (!machine)
- return -ENOMEM;
- }
-
- if (_machine)
- *_machine = machine;
-
- return 0;
-}
diff --git a/src/grp-machine/systemd-machined/machined.c b/src/grp-machine/systemd-machined/machined.c
index a01d1820a1..361d85cb3f 100644
--- a/src/grp-machine/systemd-machined/machined.c
+++ b/src/grp-machine/systemd-machined/machined.c
@@ -23,19 +23,18 @@
#include <systemd/sd-daemon.h>
-#include "basic/alloc-util.h"
-#include "basic/cgroup-util.h"
-#include "basic/dirent-util.h"
-#include "basic/fd-util.h"
-#include "basic/formats-util.h"
-#include "basic/hostname-util.h"
-#include "basic/label.h"
-#include "basic/signal-util.h"
-#include "sd-bus/bus-error.h"
-#include "shared/bus-util.h"
-#include "shared/machine-image.h"
-
#include "machined.h"
+#include "sd-bus/bus-error.h"
+#include "sd-bus/bus-util.h"
+#include "systemd-basic/alloc-util.h"
+#include "systemd-basic/cgroup-util.h"
+#include "systemd-basic/dirent-util.h"
+#include "systemd-basic/fd-util.h"
+#include "systemd-basic/formats-util.h"
+#include "systemd-basic/hostname-util.h"
+#include "systemd-basic/label.h"
+#include "systemd-basic/signal-util.h"
+#include "systemd-shared/machine-image.h"
Manager *manager_new(void) {
Manager *m;
diff --git a/src/grp-machine/systemd-machined/machined.h b/src/grp-machine/systemd-machined/machined.h
deleted file mode 100644
index b16ea3ef15..0000000000
--- a/src/grp-machine/systemd-machined/machined.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
-
-#include "basic/hashmap.h"
-#include "basic/list.h"
-
-typedef struct Manager Manager;
-
-#include "image-dbus.h"
-#include "machine-dbus.h"
-#include "machine.h"
-#include "operation.h"
-
-struct Manager {
- sd_event *event;
- sd_bus *bus;
-
- Hashmap *machines;
- Hashmap *machine_units;
- Hashmap *machine_leaders;
-
- Hashmap *polkit_registry;
-
- Hashmap *image_cache;
- sd_event_source *image_cache_defer_event;
-
- LIST_HEAD(Machine, machine_gc_queue);
-
- Machine *host_machine;
-
- LIST_HEAD(Operation, operations);
- unsigned n_operations;
-};
-
-Manager *manager_new(void);
-void manager_free(Manager *m);
-
-int manager_add_machine(Manager *m, const char *name, Machine **_machine);
-int manager_enumerate_machines(Manager *m);
-
-int manager_startup(Manager *m);
-int manager_run(Manager *m);
-
-void manager_gc(Manager *m, bool drop_not_started);
-
-int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine);
-
-extern const sd_bus_vtable manager_vtable[];
-
-int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error);
-
-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, sd_bus_message *more_properties, sd_bus_error *error, char **job);
-int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
-int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error);
-int manager_unit_is_active(Manager *manager, const char *unit);
-int manager_job_is_active(Manager *manager, const char *path);
diff --git a/src/grp-machine/systemd-machined/operation.c b/src/grp-machine/systemd-machined/operation.c
deleted file mode 100644
index f16c38c47a..0000000000
--- a/src/grp-machine/systemd-machined/operation.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2016 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "basic/alloc-util.h"
-#include "basic/fd-util.h"
-#include "basic/process-util.h"
-
-#include "operation.h"
-
-static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdata) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- Operation *o = userdata;
- int r;
-
- assert(o);
- assert(si);
-
- log_debug("Operating " PID_FMT " is now complete with code=%s status=%i",
- o->pid,
- sigchld_code_to_string(si->si_code), si->si_status);
-
- o->pid = 0;
-
- if (si->si_code != CLD_EXITED) {
- r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
- goto fail;
- }
-
- if (si->si_status == EXIT_SUCCESS)
- r = 0;
- else if (read(o->errno_fd, &r, sizeof(r)) != sizeof(r)) { /* Try to acquire error code for failed operation */
- r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Child failed.");
- goto fail;
- }
-
- if (o->done) {
- /* A completion routine is set for this operation, call it. */
- r = o->done(o, r, &error);
- if (r < 0) {
- if (!sd_bus_error_is_set(&error))
- sd_bus_error_set_errno(&error, r);
-
- goto fail;
- }
-
- } else {
- /* The default operation when done is to simply return an error on failure or an empty success
- * message on success. */
- if (r < 0)
- goto fail;
-
- r = sd_bus_reply_method_return(o->message, NULL);
- if (r < 0)
- log_error_errno(r, "Failed to reply to message: %m");
- }
-
- operation_free(o);
- return 0;
-
-fail:
- r = sd_bus_reply_method_error(o->message, &error);
- if (r < 0)
- log_error_errno(r, "Failed to reply to message: %m");
-
- operation_free(o);
- return 0;
-}
-
-int operation_new(Manager *manager, Machine *machine, pid_t child, sd_bus_message *message, int errno_fd, Operation **ret) {
- Operation *o;
- int r;
-
- assert(manager);
- assert(child > 1);
- assert(message);
- assert(errno_fd >= 0);
-
- o = new0(Operation, 1);
- if (!o)
- return -ENOMEM;
-
- o->extra_fd = -1;
-
- r = sd_event_add_child(manager->event, &o->event_source, child, WEXITED, operation_done, o);
- if (r < 0) {
- free(o);
- return r;
- }
-
- o->pid = child;
- o->message = sd_bus_message_ref(message);
- o->errno_fd = errno_fd;
-
- LIST_PREPEND(operations, manager->operations, o);
- manager->n_operations++;
- o->manager = manager;
-
- if (machine) {
- LIST_PREPEND(operations_by_machine, machine->operations, o);
- o->machine = machine;
- }
-
- log_debug("Started new operation " PID_FMT ".", child);
-
- /* At this point we took ownership of both the child and the errno file descriptor! */
-
- if (ret)
- *ret = o;
-
- return 0;
-}
-
-Operation *operation_free(Operation *o) {
- if (!o)
- return NULL;
-
- sd_event_source_unref(o->event_source);
-
- safe_close(o->errno_fd);
- safe_close(o->extra_fd);
-
- if (o->pid > 1)
- (void) sigkill_wait(o->pid);
-
- sd_bus_message_unref(o->message);
-
- if (o->manager) {
- LIST_REMOVE(operations, o->manager->operations, o);
- o->manager->n_operations--;
- }
-
- if (o->machine)
- LIST_REMOVE(operations_by_machine, o->machine->operations, o);
-
- free(o);
- return NULL;
-}
diff --git a/src/grp-machine/systemd-machined/operation.h b/src/grp-machine/systemd-machined/operation.h
deleted file mode 100644
index 713ffe88c4..0000000000
--- a/src/grp-machine/systemd-machined/operation.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2016 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/types.h>
-
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
-
-#include "basic/list.h"
-
-typedef struct Operation Operation;
-
-#include "machined.h"
-
-#define OPERATIONS_MAX 64
-
-struct Operation {
- Manager *manager;
- Machine *machine;
- pid_t pid;
- sd_bus_message *message;
- int errno_fd;
- int extra_fd;
- sd_event_source *event_source;
- int (*done)(Operation *o, int ret, sd_bus_error *error);
- LIST_FIELDS(Operation, operations);
- LIST_FIELDS(Operation, operations_by_machine);
-};
-
-int operation_new(Manager *manager, Machine *machine, pid_t child, sd_bus_message *message, int errno_fd, Operation **ret);
-Operation *operation_free(Operation *o);
diff --git a/src/grp-machine/systemd-machined/test-machine-tables.c b/src/grp-machine/systemd-machined/test-machine-tables.c
deleted file mode 100644
index 7d44c55a4b..0000000000
--- a/src/grp-machine/systemd-machined/test-machine-tables.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/***
- This file is part of systemd
-
- Copyright 2013 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "shared/test-tables.h"
-
-#include "machine.h"
-
-int main(int argc, char **argv) {
- test_table(machine_class, MACHINE_CLASS);
- test_table(machine_state, MACHINE_STATE);
- test_table(kill_who, KILL_WHO);
-
- return EXIT_SUCCESS;
-}