diff --git a/TODO b/TODO
index 1ac6ee4bfe..dba4fb6843 100644
--- a/TODO
+++ b/TODO
@@ -43,6 +43,9 @@ Features:
* support the bind/connect/sendmsg cgroup stuff for sandboxing, and possibly
patching around
+* maybe implicitly attach monotonic+realtime timestamps to outgoing messages in
+ log.c and sd-journal-send
+
* chown() tty a service is attached to after the service goes down
* optionally: turn on cgroup delegation for per-session scope units
diff --git a/man/rules/meson.build b/man/rules/meson.build
index 1a6debaaff..b93ed99713 100644
--- a/man/rules/meson.build
+++ b/man/rules/meson.build
@@ -298,6 +298,7 @@ manpages = [
'sd_bus_release_name_async',
'sd_bus_request_name_async'],
''],
+ ['sd_bus_set_close_on_exit', '3', ['sd_bus_get_close_on_exit'], ''],
['sd_bus_set_connected_signal', '3', ['sd_bus_get_connected_signal'], ''],
['sd_bus_set_description',
'3',
diff --git a/man/sd-bus.xml b/man/sd-bus.xml
index 949e320c75..c1aef96024 100644
--- a/man/sd-bus.xml
+++ b/man/sd-bus.xml
@@ -85,6 +85,7 @@
sd_bus_set_description3,
sd_bus_set_sender3,
sd_bus_set_watch_bind3
+sd_bus_set_close_on_exit3
sd_bus_slot_set_description3,
sd_bus_slot_set_destroy_callback3,
sd_bus_slot_set_floating3,
diff --git a/man/sd_bus_set_close_on_exit.xml b/man/sd_bus_set_close_on_exit.xml
new file mode 100644
index 0000000000..dc4f6a3e15
--- /dev/null
+++ b/man/sd_bus_set_close_on_exit.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+ sd_bus_set_close_on_exit
+ systemd
+
+
+
+ sd_bus_set_close_on_exit
+ 3
+
+
+
+ sd_bus_set_close_on_exit
+ sd_bus_get_close_on_exit
+
+ Control whether to close the bus connection during the event loop exit phase
+
+
+
+
+ #include <systemd/sd-bus.h>
+
+
+ int sd_bus_set_close_on_exit
+ sd_bus *bus
+ int b
+
+
+
+ int sd_bus_get_close_on_exit
+ sd_bus *bus
+
+
+
+
+
+
+ Description
+
+ sd_bus_set_close_on_exit() may be used to enable or disable whether the bus connection
+ is automatically flushed (as in
+ sd_bus_flush3) and closed (as in
+ sd_bus_close3) during the exit
+ phase of the event loop. This logic only applies to bus connections that are attached to an
+ sd-event3 event loop, see
+ sd_bus_attach_event3. By default
+ this mechanism is enabled and makes sure that any pending messages that have not been written to the bus connection
+ are written out when the event loop is shutting down. In some cases this behaviour is not desirable, for example
+ when the bus connection shall remain usable until after the event loop exited. If b is
+ true, the feature is enabled (which is the default), otherwise disabled.
+
+ sd_bus_get_close_on_exit() may be used to query the current setting of this feature. It
+ returns zero when the feature is disabled, and positive if enabled.
+
+
+
+ Return Value
+
+ On success, sd_bus_set_close_on_exit() returns 0 or a positive integer. On failure, it returns a negative errno-style
+ error code.
+
+ sd_bus_get_close_on_exit() returns 0 if the feature is currently turned off or a
+ positive integer if it is on. On failure, it returns a negative errno-style error code.
+
+
+
+ Errors
+
+ Returned errors may indicate the following problems:
+
+
+
+ -ECHILD
+
+ The bus connection has been created in a different process.
+
+
+
+
+
+
+
+ See Also
+
+
+ systemd1,
+ sd-bus3,
+ sd_bus_flush3,
+ sd_bus_attach_event3,
+ sd-event3,
+ sd_event_add_exit3
+
+
+
+
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 677d9c3226..2e38088d0f 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -12,6 +12,7 @@
#include "dbus-execute.h"
#include "dbus-job.h"
#include "dbus-manager.h"
+#include "dbus-scope.h"
#include "dbus-unit.h"
#include "dbus.h"
#include "env-util.h"
@@ -2422,6 +2423,29 @@ static int method_get_job_waiting(sd_bus_message *message, void *userdata, sd_bu
return bus_job_method_get_waiting_jobs(message, j, error);
}
+static int method_abandon_scope(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ Manager *m = userdata;
+ const char *name;
+ Unit *u;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_read(message, "s", &name);
+ if (r < 0)
+ return r;
+
+ r = bus_get_unit_by_name(m, message, name, &u, error);
+ if (r < 0)
+ return r;
+
+ if (u->type != UNIT_SCOPE)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit '%s' is not a scope unit, refusing.", name);
+
+ return bus_scope_method_abandon(message, u, error);
+}
+
const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_VTABLE_START(0),
@@ -2537,6 +2561,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetUnitProcesses", "s", "a(sus)", method_get_unit_processes, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("AttachProcessesToUnit", "ssau", NULL, method_attach_processes_to_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("AbandonScope", "s", NULL, method_abandon_scope, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetJobAfter", "u", "a(usssoo)", method_get_job_waiting, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetJobBefore", "u", "a(usssoo)", method_get_job_waiting, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c
index 6725f62794..5d9fe98857 100644
--- a/src/core/dbus-scope.c
+++ b/src/core/dbus-scope.c
@@ -14,7 +14,7 @@
#include "selinux-access.h"
#include "unit.h"
-static int bus_scope_abandon(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+int bus_scope_method_abandon(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Scope *s = userdata;
int r;
@@ -48,7 +48,7 @@ const sd_bus_vtable bus_scope_vtable[] = {
SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Scope, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_SIGNAL("RequestStop", NULL, 0),
- SD_BUS_METHOD("Abandon", NULL, NULL, bus_scope_abandon, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Abandon", NULL, NULL, bus_scope_method_abandon, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
diff --git a/src/core/dbus-scope.h b/src/core/dbus-scope.h
index 7c080dbcf7..702f55898d 100644
--- a/src/core/dbus-scope.h
+++ b/src/core/dbus-scope.h
@@ -14,4 +14,6 @@ int bus_scope_commit_properties(Unit *u);
int bus_scope_send_request_stop(Scope *s);
+int bus_scope_method_abandon(sd_bus_message *message, void *userdata, sd_bus_error *error);
+
int bus_scope_track_controller(Scope *s);
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 97bceb19dd..18e5b8d2df 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -561,6 +561,44 @@ int bus_unit_method_unref(sd_bus_message *message, void *userdata, sd_bus_error
return sd_bus_reply_method_return(message, NULL);
}
+static int property_get_refs(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Unit *u = userdata;
+ const char *i;
+ int r;
+
+ assert(bus);
+ assert(reply);
+
+ r = sd_bus_message_open_container(reply, 'a', "s");
+ if (r < 0)
+ return r;
+
+ for (i = sd_bus_track_first(u->bus_track); i; i = sd_bus_track_next(u->bus_track)) {
+ int c, k;
+
+ c = sd_bus_track_count_name(u->bus_track, i);
+ if (c < 0)
+ return c;
+
+ /* Add the item multiple times if the ref count for each is above 1 */
+ for (k = 0; k < c; k++) {
+ r = sd_bus_message_append(reply, "s", i);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ return sd_bus_message_close_container(reply);
+}
+
const sd_bus_vtable bus_unit_vtable[] = {
SD_BUS_VTABLE_START(0),
@@ -637,6 +675,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("InvocationID", "ay", bus_property_get_id128, offsetof(Unit, invocation_id), 0),
SD_BUS_PROPERTY("CollectMode", "s", property_get_collect_mode, offsetof(Unit, collect_mode), 0),
+ SD_BUS_PROPERTY("Refs", "as", property_get_refs, 0, 0),
SD_BUS_METHOD("Start", "s", "o", method_start, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Stop", "s", "o", method_stop, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -1781,7 +1820,13 @@ static int bus_unit_track_handler(sd_bus_track *t, void *userdata) {
u->bus_track = sd_bus_track_unref(u->bus_track); /* make sure we aren't called again */
+ /* If the client that tracks us disappeared, then there's reason to believe that the cgroup is empty now too,
+ * let's see */
+ unit_add_to_cgroup_empty_queue(u);
+
+ /* Also add the unit to the GC queue, after all if the client left it might be time to GC this unit */
unit_add_to_gc_queue(u);
+
return 0;
}
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 1f2238ca37..6a64b929dd 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -579,6 +579,9 @@ global:
sd_bus_error_move;
+ sd_bus_set_close_on_exit;
+ sd_bus_get_close_on_exit;
+
sd_device_ref;
sd_device_unref;
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index 55f2bc36fb..4bc945d9ee 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -211,6 +211,7 @@ struct sd_bus {
bool accept_fd:1;
bool attach_timestamp:1;
bool connected_signal:1;
+ bool close_on_exit:1;
int use_memfd;
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index bc7d00c3d0..f086d13898 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -232,18 +232,22 @@ _public_ int sd_bus_new(sd_bus **ret) {
assert_return(ret, -EINVAL);
- b = new0(sd_bus, 1);
+ b = new(sd_bus, 1);
if (!b)
return -ENOMEM;
- b->n_ref = REFCNT_INIT;
- b->input_fd = b->output_fd = -1;
- b->inotify_fd = -1;
- b->message_version = 1;
- b->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
- b->accept_fd = true;
- b->original_pid = getpid_cached();
- b->n_groups = (size_t) -1;
+ *b = (sd_bus) {
+ .n_ref = REFCNT_INIT,
+ .input_fd = -1,
+ .output_fd = -1,
+ .inotify_fd = -1,
+ .message_version = 1,
+ .creds_mask = SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME,
+ .accept_fd = true,
+ .original_pid = getpid_cached(),
+ .n_groups = (size_t) -1,
+ .close_on_exit = true,
+ };
assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
@@ -3409,8 +3413,10 @@ static int quit_callback(sd_event_source *event, void *userdata) {
assert(event);
- sd_bus_flush(bus);
- sd_bus_close(bus);
+ if (bus->close_on_exit) {
+ sd_bus_flush(bus);
+ sd_bus_close(bus);
+ }
return 1;
}
@@ -4135,3 +4141,18 @@ _public_ int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret) {
*ret = bus->method_call_timeout = BUS_DEFAULT_TIMEOUT;
return 0;
}
+
+_public_ int sd_bus_set_close_on_exit(sd_bus *bus, int b) {
+ assert_return(bus, -EINVAL);
+ assert_return(bus = bus_resolve(bus), -ENOPKG);
+
+ bus->close_on_exit = b;
+ return 0;
+}
+
+_public_ int sd_bus_get_close_on_exit(sd_bus *bus) {
+ assert_return(bus, -EINVAL);
+ assert_return(bus = bus_resolve(bus), -ENOPKG);
+
+ return bus->close_on_exit;
+}
diff --git a/src/machine/machine.c b/src/machine/machine.c
index 239228b2d2..d5e0d4953f 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -403,7 +403,7 @@ int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) {
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;
+ int r, q;
assert(m);
assert(m->class != MACHINE_HOST);
@@ -412,10 +412,17 @@ static int machine_stop_scope(Machine *m) {
return 0;
r = manager_stop_unit(m->manager, m->unit, &error, &job);
- if (r < 0)
- return log_error_errno(r, "Failed to stop machine scope: %s", bus_error_message(&error, r));
+ if (r < 0) {
+ log_error_errno(r, "Failed to stop machine scope: %s", bus_error_message(&error, r));
+ sd_bus_error_free(&error);
+ } else
+ free_and_replace(m->scope_job, job);
- return free_and_replace(m->scope_job, job);
+ q = manager_unref_unit(m->manager, m->unit, &error);
+ if (q < 0)
+ log_warning_errno(q, "Failed to drop reference to machine scope, ignoring: %s", bus_error_message(&error, r));
+
+ return r;
}
int machine_stop(Machine *m) {
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 32c0b04283..87e6298c78 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -1363,18 +1363,15 @@ int manager_start_scope(
return r;
}
- r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
+ r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)",
+ "PIDs", "au", 1, pid,
+ "Delegate", "b", 1,
+ "CollectMode", "s", "inactive-or-failed",
+ "AddRef", "b", 1,
+ "TasksMax", "t", UINT64_C(16384));
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)
@@ -1411,6 +1408,26 @@ int manager_start_scope(
return 1;
}
+int manager_unref_unit(
+ Manager *m,
+ const char *unit,
+ sd_bus_error *error) {
+
+ assert(m);
+ assert(unit);
+
+ return sd_bus_call_method(
+ m->bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "UnrefUnit",
+ error,
+ NULL,
+ "s",
+ unit);
+}
+
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;
diff --git a/src/machine/machined.h b/src/machine/machined.h
index 3197c1aade..ef63f96e97 100644
--- a/src/machine/machined.h
+++ b/src/machine/machined.h
@@ -50,5 +50,6 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
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_unref_unit(Manager *m, const char *unit, 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/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c
index 85f3cf1c01..a7cdfc1c7d 100644
--- a/src/nspawn/nspawn-register.c
+++ b/src/nspawn/nspawn-register.c
@@ -201,10 +201,11 @@ int register_machine(
return 0;
}
-int terminate_machine(sd_bus *bus, pid_t pid) {
+int terminate_machine(
+ sd_bus *bus,
+ const char *machine_name) {
+
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- const char *path;
int r;
assert(bus);
@@ -214,32 +215,11 @@ int terminate_machine(sd_bus *bus, pid_t pid) {
"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",
+ "TerminateMachine",
&error,
NULL,
- NULL);
+ "s",
+ machine_name);
if (r < 0)
log_debug("Failed to terminate machine: %s", bus_error_message(&error, r));
@@ -256,9 +236,8 @@ int allocate_scope(
int kill_signal,
char **properties) {
+ _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;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
_cleanup_free_ char *scope = NULL;
const char *description, *object;
@@ -295,10 +274,12 @@ int allocate_scope(
description = strjoina("Container ", machine_name);
- r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)",
+ r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)(sv)",
"PIDs", "au", 1, pid,
"Description", "s", description,
"Delegate", "b", 1,
+ "CollectMode", "s", "inactive-or-failed",
+ "AddRef", "b", 1,
"Slice", "s", isempty(slice) ? SPECIAL_MACHINE_SLICE : slice);
if (r < 0)
return bus_log_create_error(r);
@@ -345,3 +326,63 @@ int allocate_scope(
return 0;
}
+
+int terminate_scope(
+ sd_bus *bus,
+ const char *machine_name) {
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *scope = NULL;
+ int r;
+
+ r = unit_name_mangle_with_suffix(machine_name, 0, ".scope", &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);
+ 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(
+ bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "KillUnit",
+ &error,
+ NULL,
+ "ssi",
+ scope,
+ "all",
+ (int32_t) SIGKILL);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to SIGKILL scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
+ 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);
+ if (r < 0)
+ log_debug_errno(r, "Failed to drop reference to scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
+
+ return 0;
+}
diff --git a/src/nspawn/nspawn-register.h b/src/nspawn/nspawn-register.h
index 30807b9687..05f5776f23 100644
--- a/src/nspawn/nspawn-register.h
+++ b/src/nspawn/nspawn-register.h
@@ -8,6 +8,7 @@
#include "nspawn-mount.h"
int register_machine(sd_bus *bus, 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, const char *service);
-int terminate_machine(sd_bus *bus, pid_t pid);
+int terminate_machine(sd_bus *bus, const char *machine_name);
int allocate_scope(sd_bus *bus, const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties);
+int terminate_scope(sd_bus *bus, const char *machine_name);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index ab19d73c27..9f69ee10a8 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -3974,6 +3974,10 @@ static int run(int master,
r = sd_bus_default_system(&bus);
if (r < 0)
return log_error_errno(r, "Failed to open system bus: %m");
+
+ r = sd_bus_set_close_on_exit(bus, false);
+ if (r < 0)
+ return log_error_errno(r, "Failed to disable close-on-exit behaviour: %m");
}
if (!arg_keep_unit) {
@@ -4125,8 +4129,12 @@ static int run(int master,
putc('\n', stdout);
/* Kill if it is not dead yet anyway */
- if (arg_register && !arg_keep_unit && bus)
- terminate_machine(bus, *pid);
+ if (bus) {
+ if (arg_register)
+ terminate_machine(bus, arg_machine);
+ else if (!arg_keep_unit)
+ terminate_scope(bus, arg_machine);
+ }
/* Normally redundant, but better safe than sorry */
(void) kill(*pid, SIGKILL);
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 9c4bbed9dc..220ddb99ec 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -154,6 +154,8 @@ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b);
int sd_bus_get_allow_interactive_authorization(sd_bus *bus);
int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b);
int sd_bus_get_exit_on_disconnect(sd_bus *bus);
+int sd_bus_set_close_on_exit(sd_bus *bus, int b);
+int sd_bus_get_close_on_exit(sd_bus *bus);
int sd_bus_set_watch_bind(sd_bus *bus, int b);
int sd_bus_get_watch_bind(sd_bus *bus);
int sd_bus_set_connected_signal(sd_bus *bus, int b);