]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/nspawn/nspawn-register.c
tree-wide: Add allow_pidfd argument to bus_append_scope_pidref()
[thirdparty/systemd.git] / src / nspawn / nspawn-register.c
index b2d931a8d32cd0cb717f98f016307bd98018ba41..b63516d13efc0d87b34825e1ad518d64080c5623 100644 (file)
@@ -1,22 +1,24 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include "sd-bus.h"
 
 #include "bus-error.h"
+#include "bus-locator.h"
 #include "bus-unit-util.h"
 #include "bus-util.h"
 #include "bus-wait-for-jobs.h"
 #include "nspawn-register.h"
+#include "nspawn-settings.h"
 #include "special.h"
 #include "stat-util.h"
 #include "strv.h"
-#include "util.h"
 
 static int append_machine_properties(
                 sd_bus_message *m,
                 CustomMount *mounts,
                 unsigned n_mounts,
-                int kill_signal) {
+                int kill_signal,
+                bool coredump_receive) {
 
         unsigned j;
         int r;
@@ -79,6 +81,12 @@ static int append_machine_properties(
                         return bus_log_create_error(r);
         }
 
+        if (coredump_receive) {
+                r = sd_bus_message_append(m, "(sv)", "CoredumpReceive", "b", true);
+                if (r < 0)
+                        return bus_log_create_error(r);
+        }
+
         return 0;
 }
 
@@ -100,6 +108,32 @@ static int append_controller_property(sd_bus *bus, sd_bus_message *m) {
         return 0;
 }
 
+static int can_set_coredump_receive(sd_bus *bus) {
+        _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
+        _cleanup_free_ char *path = NULL;
+        int b, r;
+
+        assert(bus);
+
+        path = unit_dbus_path_from_name(SPECIAL_INIT_SCOPE);
+        if (!path)
+                return log_oom();
+
+        r = sd_bus_get_property_trivial(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        path,
+                        "org.freedesktop.systemd1.Scope",
+                        "CoredumpReceive",
+                        &e,
+                        'b', &b);
+        if (r < 0 && !sd_bus_error_has_names(&e, SD_BUS_ERROR_UNKNOWN_PROPERTY, SD_BUS_ERROR_PROPERTY_READ_ONLY))
+                log_warning_errno(r, "Failed to determine if CoredumpReceive= can be set, assuming it cannot be: %s",
+                                  bus_error_message(&e, r));
+
+        return r >= 0;
+}
+
 int register_machine(
                 sd_bus *bus,
                 const char *machine_name,
@@ -114,7 +148,8 @@ int register_machine(
                 char **properties,
                 sd_bus_message *properties_message,
                 bool keep_unit,
-                const char *service) {
+                const char *service,
+                StartMode start_mode) {
 
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         int r;
@@ -122,11 +157,9 @@ int register_machine(
         assert(bus);
 
         if (keep_unit) {
-                r = sd_bus_call_method(
+                r = bus_call_method(
                                 bus,
-                                "org.freedesktop.machine1",
-                                "/org/freedesktop/machine1",
-                                "org.freedesktop.machine1.Manager",
+                                bus_machine_mgr,
                                 "RegisterMachineWithNetwork",
                                 &error,
                                 NULL,
@@ -141,13 +174,7 @@ int register_machine(
         } else {
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
 
-                r = sd_bus_message_new_method_call(
-                                bus,
-                                &m,
-                                "org.freedesktop.machine1",
-                                "/org/freedesktop/machine1",
-                                "org.freedesktop.machine1.Manager",
-                                "CreateMachineWithNetwork");
+                r = bus_message_new_method_call(bus, &m,  bus_machine_mgr, "CreateMachineWithNetwork");
                 if (r < 0)
                         return bus_log_create_error(r);
 
@@ -182,7 +209,8 @@ int register_machine(
                                 m,
                                 mounts,
                                 n_mounts,
-                                kill_signal);
+                                kill_signal,
+                                start_mode == START_BOOT && can_set_coredump_receive(bus) > 0);
                 if (r < 0)
                         return r;
 
@@ -202,14 +230,13 @@ int register_machine(
 
                 r = sd_bus_call(bus, m, 0, &error, NULL);
         }
-
         if (r < 0)
                 return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r));
 
         return 0;
 }
 
-int terminate_machine(
+int unregister_machine(
                 sd_bus *bus,
                 const char *machine_name) {
 
@@ -218,18 +245,9 @@ int terminate_machine(
 
         assert(bus);
 
-        r = sd_bus_call_method(
-                        bus,
-                        "org.freedesktop.machine1",
-                        "/org/freedesktop/machine1",
-                        "org.freedesktop.machine1.Manager",
-                        "TerminateMachine",
-                        &error,
-                        NULL,
-                        "s",
-                        machine_name);
+        r = bus_call_method(bus, bus_machine_mgr, "UnregisterMachine", &error, NULL, "s", machine_name);
         if (r < 0)
-                log_debug("Failed to terminate machine: %s", bus_error_message(&error, r));
+                log_debug("Failed to unregister machine: %s", bus_error_message(&error, r));
 
         return 0;
 }
@@ -243,7 +261,9 @@ int allocate_scope(
                 unsigned n_mounts,
                 int kill_signal,
                 char **properties,
-                sd_bus_message *properties_message) {
+                sd_bus_message *properties_message,
+                bool allow_pidfd,
+                StartMode start_mode) {
 
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -262,13 +282,7 @@ int allocate_scope(
         if (r < 0)
                 return log_error_errno(r, "Failed to mangle scope name: %m");
 
-        r = sd_bus_message_new_method_call(
-                        bus,
-                        &m,
-                        "org.freedesktop.systemd1",
-                        "/org/freedesktop/systemd1",
-                        "org.freedesktop.systemd1.Manager",
-                        "StartTransientUnit");
+        r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, "StartTransientUnit");
         if (r < 0)
                 return bus_log_create_error(r);
 
@@ -283,8 +297,16 @@ int allocate_scope(
 
         description = strjoina("Container ", machine_name);
 
-        r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)(sv)",
-                                  "PIDs", "au", 1, pid,
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_set_pid(&pidref, pid);
+        if (r < 0)
+                return log_error_errno(r, "Failed to allocate PID reference: %m");
+
+        r = bus_append_scope_pidref(m, &pidref, allow_pidfd);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)",
                                   "Description", "s", description,
                                   "Delegate", "b", 1,
                                   "CollectMode", "s", "inactive-or-failed",
@@ -307,7 +329,8 @@ int allocate_scope(
                         m,
                         mounts,
                         n_mounts,
-                        kill_signal);
+                        kill_signal,
+                        start_mode == START_BOOT && can_set_coredump_receive(bus) > 0);
         if (r < 0)
                 return r;
 
@@ -328,14 +351,25 @@ int allocate_scope(
                 return bus_log_create_error(r);
 
         r = sd_bus_call(bus, m, 0, &error, &reply);
-        if (r < 0)
+        if (r < 0) {
+                /* If this failed with a property we couldn't write, this is quite likely because the server
+                 * doesn't support PIDFDs yet, let's try without. */
+                if (allow_pidfd &&
+                    sd_bus_error_has_names(&error, SD_BUS_ERROR_UNKNOWN_PROPERTY, SD_BUS_ERROR_PROPERTY_READ_ONLY))
+                        return allocate_scope(bus, machine_name, pid, slice, mounts, n_mounts, kill_signal, properties, properties_message, /* allow_pidfd= */ false, start_mode);
+
                 return log_error_errno(r, "Failed to allocate scope: %s", bus_error_message(&error, r));
+        }
 
         r = sd_bus_message_read(reply, "o", &object);
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        r = bus_wait_for_jobs_one(w, object, false);
+        r = bus_wait_for_jobs_one(
+                        w,
+                        object,
+                        BUS_WAIT_JOBS_LOG_ERROR,
+                        /* extra_args= */ NULL);
         if (r < 0)
                 return r;
 
@@ -354,26 +388,15 @@ int terminate_scope(
         if (r < 0)
                 return log_error_errno(r, "Failed to mangle scope name: %m");
 
-        r = sd_bus_call_method(
-                        bus,
-                        "org.freedesktop.systemd1",
-                        "/org/freedesktop/systemd1",
-                        "org.freedesktop.systemd1.Manager",
-                        "AbandonScope",
-                        &error,
-                        NULL,
-                        "s",
-                        scope);
+        r = bus_call_method(bus, bus_systemd_mgr, "AbandonScope", &error, NULL, "s", scope);
         if (r < 0) {
                 log_debug_errno(r, "Failed to abandon scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
                 sd_bus_error_free(&error);
         }
 
-        r = sd_bus_call_method(
+        r = bus_call_method(
                         bus,
-                        "org.freedesktop.systemd1",
-                        "/org/freedesktop/systemd1",
-                        "org.freedesktop.systemd1.Manager",
+                        bus_systemd_mgr,
                         "KillUnit",
                         &error,
                         NULL,
@@ -386,16 +409,7 @@ int terminate_scope(
                 sd_bus_error_free(&error);
         }
 
-        r = sd_bus_call_method(
-                        bus,
-                        "org.freedesktop.systemd1",
-                        "/org/freedesktop/systemd1",
-                        "org.freedesktop.systemd1.Manager",
-                        "UnrefUnit",
-                        &error,
-                        NULL,
-                        "s",
-                        scope);
+        r = bus_call_method(bus, bus_systemd_mgr, "UnrefUnit", &error, NULL, "s", scope);
         if (r < 0)
                 log_debug_errno(r, "Failed to drop reference to scope '%s', ignoring: %s", scope, bus_error_message(&error, r));