nspawn: split out machined registration code to nspawn-register.[ch]
authorLennart Poettering <lennart@poettering.net>
Mon, 7 Sep 2015 16:36:05 +0000 (18:36 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 7 Sep 2015 16:44:31 +0000 (18:44 +0200)
Makefile.am
src/nspawn/nspawn-register.c [new file with mode: 0644]
src/nspawn/nspawn-register.h [new file with mode: 0644]
src/nspawn/nspawn.c

index 8c652be..6852a3a 100644 (file)
@@ -2789,6 +2789,8 @@ systemd_nspawn_SOURCES = \
        src/nspawn/nspawn-expose-ports.h \
        src/nspawn/nspawn-cgroup.c \
        src/nspawn/nspawn-cgroup.h \
+       src/nspawn/nspawn-register.c \
+       src/nspawn/nspawn-register.h \
        src/core/mount-setup.c \
        src/core/mount-setup.h \
        src/core/loopback-setup.c \
diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c
new file mode 100644 (file)
index 0000000..0f3a5d6
--- /dev/null
@@ -0,0 +1,245 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2015 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 "sd-bus.h"
+
+#include "util.h"
+#include "strv.h"
+#include "bus-util.h"
+#include "bus-error.h"
+
+#include "nspawn.h"
+#include "nspawn-register.h"
+
+int register_machine(
+                const char *machine_name,
+                pid_t pid,
+                const char *directory,
+                sd_id128_t uuid,
+                int local_ifindex,
+                const char *slice,
+                CustomMount *mounts,
+                unsigned n_mounts,
+                int kill_signal,
+                char **properties,
+                bool keep_unit) {
+
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
+        int r;
+
+        r = sd_bus_default_system(&bus);
+        if (r < 0)
+                return log_error_errno(r, "Failed to open system bus: %m");
+
+        if (keep_unit) {
+                r = sd_bus_call_method(
+                                bus,
+                                "org.freedesktop.machine1",
+                                "/org/freedesktop/machine1",
+                                "org.freedesktop.machine1.Manager",
+                                "RegisterMachineWithNetwork",
+                                &error,
+                                NULL,
+                                "sayssusai",
+                                machine_name,
+                                SD_BUS_MESSAGE_APPEND_ID128(uuid),
+                                "nspawn",
+                                "container",
+                                (uint32_t) pid,
+                                strempty(directory),
+                                local_ifindex > 0 ? 1 : 0, local_ifindex);
+        } else {
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+                char **i;
+                unsigned j;
+
+                r = sd_bus_message_new_method_call(
+                                bus,
+                                &m,
+                                "org.freedesktop.machine1",
+                                "/org/freedesktop/machine1",
+                                "org.freedesktop.machine1.Manager",
+                                "CreateMachineWithNetwork");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append(
+                                m,
+                                "sayssusai",
+                                machine_name,
+                                SD_BUS_MESSAGE_APPEND_ID128(uuid),
+                                "nspawn",
+                                "container",
+                                (uint32_t) pid,
+                                strempty(directory),
+                                local_ifindex > 0 ? 1 : 0, local_ifindex);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_open_container(m, 'a', "(sv)");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                if (!isempty(slice)) {
+                        r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
+                        if (r < 0)
+                                return bus_log_create_error(r);
+                }
+
+                r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "strict");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                /* If you make changes here, also make sure to update
+                 * systemd-nspawn@.service, to keep the device
+                 * policies in sync regardless if we are run with or
+                 * without the --keep-unit switch. */
+                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 9,
+                                          /* Allow the container to
+                                           * access and create the API
+                                           * device nodes, so that
+                                           * PrivateDevices= in the
+                                           * container can work
+                                           * fine */
+                                          "/dev/null", "rwm",
+                                          "/dev/zero", "rwm",
+                                          "/dev/full", "rwm",
+                                          "/dev/random", "rwm",
+                                          "/dev/urandom", "rwm",
+                                          "/dev/tty", "rwm",
+                                          "/dev/net/tun", "rwm",
+                                          /* Allow the container
+                                           * access to ptys. However,
+                                           * do not permit the
+                                           * container to ever create
+                                           * these device nodes. */
+                                          "/dev/pts/ptmx", "rw",
+                                          "char-pts", "rw");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                for (j = 0; j < n_mounts; j++) {
+                        CustomMount *cm = mounts + j;
+
+                        if (cm->type != CUSTOM_MOUNT_BIND)
+                                continue;
+
+                        r = is_device_node(cm->source);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to stat %s: %m", cm->source);
+
+                        if (r) {
+                                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
+                                        cm->source, cm->read_only ? "r" : "rw");
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to append message arguments: %m");
+                        }
+                }
+
+                if (kill_signal != 0) {
+                        r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal);
+                        if (r < 0)
+                                return bus_log_create_error(r);
+
+                        r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
+                        if (r < 0)
+                                return bus_log_create_error(r);
+                }
+
+                STRV_FOREACH(i, properties) {
+                        r = sd_bus_message_open_container(m, 'r', "sv");
+                        if (r < 0)
+                                return bus_log_create_error(r);
+
+                        r = bus_append_unit_property_assignment(m, *i);
+                        if (r < 0)
+                                return r;
+
+                        r = sd_bus_message_close_container(m);
+                        if (r < 0)
+                                return bus_log_create_error(r);
+                }
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_call(bus, m, 0, &error, NULL);
+        }
+
+        if (r < 0) {
+                log_error("Failed to register machine: %s", bus_error_message(&error, r));
+                return r;
+        }
+
+        return 0;
+}
+
+int terminate_machine(pid_t pid) {
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
+        const char *path;
+        int r;
+
+        r = sd_bus_default_system(&bus);
+        if (r < 0)
+                return log_error_errno(r, "Failed to open system bus: %m");
+
+        r = sd_bus_call_method(
+                        bus,
+                        "org.freedesktop.machine1",
+                        "/org/freedesktop/machine1",
+                        "org.freedesktop.machine1.Manager",
+                        "GetMachineByPID",
+                        &error,
+                        &reply,
+                        "u",
+                        (uint32_t) pid);
+        if (r < 0) {
+                /* Note that the machine might already have been
+                 * cleaned up automatically, hence don't consider it a
+                 * failure if we cannot get the machine object. */
+                log_debug("Failed to get machine: %s", bus_error_message(&error, r));
+                return 0;
+        }
+
+        r = sd_bus_message_read(reply, "o", &path);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_call_method(
+                        bus,
+                        "org.freedesktop.machine1",
+                        path,
+                        "org.freedesktop.machine1.Machine",
+                        "Terminate",
+                        &error,
+                        NULL,
+                        NULL);
+        if (r < 0) {
+                log_debug("Failed to terminate machine: %s", bus_error_message(&error, r));
+                return 0;
+        }
+
+        return 0;
+}
diff --git a/src/nspawn/nspawn-register.h b/src/nspawn/nspawn-register.h
new file mode 100644 (file)
index 0000000..b27841f
--- /dev/null
@@ -0,0 +1,31 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2015 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 "sd-id128.h"
+
+#include "nspawn-mount.h"
+
+int register_machine(const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, bool keep_unit);
+int terminate_machine(pid_t pid);
index c106b58..fcabe24 100644 (file)
 #include "nspawn-network.h"
 #include "nspawn-expose-ports.h"
 #include "nspawn-cgroup.h"
+#include "nspawn-register.h"
 
 typedef enum ContainerStatus {
         CONTAINER_TERMINATED,
@@ -1515,220 +1516,6 @@ static int drop_capabilities(void) {
         return capability_bounding_set_drop(~arg_retain, false);
 }
 
-static int register_machine(pid_t pid, int local_ifindex) {
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
-        int r;
-
-        if (!arg_register)
-                return 0;
-
-        r = sd_bus_default_system(&bus);
-        if (r < 0)
-                return log_error_errno(r, "Failed to open system bus: %m");
-
-        if (arg_keep_unit) {
-                r = sd_bus_call_method(
-                                bus,
-                                "org.freedesktop.machine1",
-                                "/org/freedesktop/machine1",
-                                "org.freedesktop.machine1.Manager",
-                                "RegisterMachineWithNetwork",
-                                &error,
-                                NULL,
-                                "sayssusai",
-                                arg_machine,
-                                SD_BUS_MESSAGE_APPEND_ID128(arg_uuid),
-                                "nspawn",
-                                "container",
-                                (uint32_t) pid,
-                                strempty(arg_directory),
-                                local_ifindex > 0 ? 1 : 0, local_ifindex);
-        } else {
-                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
-                char **i;
-                unsigned j;
-
-                r = sd_bus_message_new_method_call(
-                                bus,
-                                &m,
-                                "org.freedesktop.machine1",
-                                "/org/freedesktop/machine1",
-                                "org.freedesktop.machine1.Manager",
-                                "CreateMachineWithNetwork");
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                r = sd_bus_message_append(
-                                m,
-                                "sayssusai",
-                                arg_machine,
-                                SD_BUS_MESSAGE_APPEND_ID128(arg_uuid),
-                                "nspawn",
-                                "container",
-                                (uint32_t) pid,
-                                strempty(arg_directory),
-                                local_ifindex > 0 ? 1 : 0, local_ifindex);
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                r = sd_bus_message_open_container(m, 'a', "(sv)");
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                if (!isempty(arg_slice)) {
-                        r = sd_bus_message_append(m, "(sv)", "Slice", "s", arg_slice);
-                        if (r < 0)
-                                return bus_log_create_error(r);
-                }
-
-                r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "strict");
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                /* If you make changes here, also make sure to update
-                 * systemd-nspawn@.service, to keep the device
-                 * policies in sync regardless if we are run with or
-                 * without the --keep-unit switch. */
-                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 9,
-                                          /* Allow the container to
-                                           * access and create the API
-                                           * device nodes, so that
-                                           * PrivateDevices= in the
-                                           * container can work
-                                           * fine */
-                                          "/dev/null", "rwm",
-                                          "/dev/zero", "rwm",
-                                          "/dev/full", "rwm",
-                                          "/dev/random", "rwm",
-                                          "/dev/urandom", "rwm",
-                                          "/dev/tty", "rwm",
-                                          "/dev/net/tun", "rwm",
-                                          /* Allow the container
-                                           * access to ptys. However,
-                                           * do not permit the
-                                           * container to ever create
-                                           * these device nodes. */
-                                          "/dev/pts/ptmx", "rw",
-                                          "char-pts", "rw");
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                for (j = 0; j < arg_n_custom_mounts; j++) {
-                        CustomMount *cm = &arg_custom_mounts[j];
-
-                        if (cm->type != CUSTOM_MOUNT_BIND)
-                                continue;
-
-                        r = is_device_node(cm->source);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to stat %s: %m", cm->source);
-
-                        if (r) {
-                                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
-                                        cm->source, cm->read_only ? "r" : "rw");
-                                if (r < 0)
-                                        return log_error_errno(r, "Failed to append message arguments: %m");
-                        }
-                }
-
-                if (arg_kill_signal != 0) {
-                        r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", arg_kill_signal);
-                        if (r < 0)
-                                return bus_log_create_error(r);
-
-                        r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
-                        if (r < 0)
-                                return bus_log_create_error(r);
-                }
-
-                STRV_FOREACH(i, arg_property) {
-                        r = sd_bus_message_open_container(m, 'r', "sv");
-                        if (r < 0)
-                                return bus_log_create_error(r);
-
-                        r = bus_append_unit_property_assignment(m, *i);
-                        if (r < 0)
-                                return r;
-
-                        r = sd_bus_message_close_container(m);
-                        if (r < 0)
-                                return bus_log_create_error(r);
-                }
-
-                r = sd_bus_message_close_container(m);
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                r = sd_bus_call(bus, m, 0, &error, NULL);
-        }
-
-        if (r < 0) {
-                log_error("Failed to register machine: %s", bus_error_message(&error, r));
-                return r;
-        }
-
-        return 0;
-}
-
-static int terminate_machine(pid_t pid) {
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
-        const char *path;
-        int r;
-
-        if (!arg_register)
-                return 0;
-
-        /* If we are reusing the unit, then just exit, systemd will do
-         * the right thing when we exit. */
-        if (arg_keep_unit)
-                return 0;
-
-        r = sd_bus_default_system(&bus);
-        if (r < 0)
-                return log_error_errno(r, "Failed to open system bus: %m");
-
-        r = sd_bus_call_method(
-                        bus,
-                        "org.freedesktop.machine1",
-                        "/org/freedesktop/machine1",
-                        "org.freedesktop.machine1.Manager",
-                        "GetMachineByPID",
-                        &error,
-                        &reply,
-                        "u",
-                        (uint32_t) pid);
-        if (r < 0) {
-                /* Note that the machine might already have been
-                 * cleaned up automatically, hence don't consider it a
-                 * failure if we cannot get the machine object. */
-                log_debug("Failed to get machine: %s", bus_error_message(&error, r));
-                return 0;
-        }
-
-        r = sd_bus_message_read(reply, "o", &path);
-        if (r < 0)
-                return bus_log_parse_error(r);
-
-        r = sd_bus_call_method(
-                        bus,
-                        "org.freedesktop.machine1",
-                        path,
-                        "org.freedesktop.machine1.Machine",
-                        "Terminate",
-                        &error,
-                        NULL,
-                        NULL);
-        if (r < 0) {
-                log_debug("Failed to terminate machine: %s", bus_error_message(&error, r));
-                return 0;
-        }
-
-        return 0;
-}
-
 static int reset_audit_loginuid(void) {
         _cleanup_free_ char *p = NULL;
         int r;
@@ -3904,9 +3691,21 @@ int main(int argc, char *argv[]) {
                                 goto finish;
                 }
 
-                r = register_machine(pid, ifi);
-                if (r < 0)
-                        goto finish;
+                if (arg_register) {
+                        r = register_machine(
+                                        arg_machine,
+                                        pid,
+                                        arg_directory,
+                                        arg_uuid,
+                                        ifi,
+                                        arg_slice,
+                                        arg_custom_mounts, arg_n_custom_mounts,
+                                        arg_kill_signal,
+                                        arg_property,
+                                        arg_keep_unit);
+                        if (r < 0)
+                                goto finish;
+                }
 
                 r = sync_cgroup(pid, arg_unified_cgroup_hierarchy);
                 if (r < 0)
@@ -4000,7 +3799,8 @@ int main(int argc, char *argv[]) {
                         putc('\n', stdout);
 
                 /* Kill if it is not dead yet anyway */
-                terminate_machine(pid);
+                if (arg_register && !arg_keep_unit)
+                        terminate_machine(pid);
 
                 /* Normally redundant, but better safe than sorry */
                 kill(pid, SIGKILL);