-/* 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;
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;
}
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,
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;
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,
} 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);
m,
mounts,
n_mounts,
- kill_signal);
+ kill_signal,
+ start_mode == START_BOOT && can_set_coredump_receive(bus) > 0);
if (r < 0)
return r;
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));
assert(bus);
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.machine1",
- "/org/freedesktop/machine1",
- "org.freedesktop.machine1.Manager",
- "UnregisterMachine",
- &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 unregister machine: %s", bus_error_message(&error, r));
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;
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);
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",
m,
mounts,
n_mounts,
- kill_signal);
+ kill_signal,
+ start_mode == START_BOOT && can_set_coredump_receive(bus) > 0);
if (r < 0)
return r;
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;
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,
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));