4bff0a
From 37c1da056b63323514d71d2832a01ea916f004cc Mon Sep 17 00:00:00 2001
4bff0a
From: Lennart Poettering <lennart@poettering.net>
4bff0a
Date: Fri, 5 Oct 2018 22:56:40 +0200
4bff0a
Subject: [PATCH] nspawn: rework how we allocate/kill scopes
4bff0a
4bff0a
Fixes: #6347
4bff0a
(cherry picked from commit 1d78fea2d6230e0aafa2603abc8f1f51966ef134)
4bff0a
4bff0a
Resolves: #1697893
4bff0a
---
4bff0a
 src/nspawn/nspawn-register.c | 64 +++++++++++++++++++++++++++++++++++-
4bff0a
 src/nspawn/nspawn-register.h |  1 +
4bff0a
 src/nspawn/nspawn.c          |  8 +++--
4bff0a
 3 files changed, 70 insertions(+), 3 deletions(-)
4bff0a
4bff0a
diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c
4bff0a
index 0d45cce66e..a7cdfc1c7d 100644
4bff0a
--- a/src/nspawn/nspawn-register.c
4bff0a
+++ b/src/nspawn/nspawn-register.c
4bff0a
@@ -274,10 +274,12 @@ int allocate_scope(
4bff0a
 
4bff0a
         description = strjoina("Container ", machine_name);
4bff0a
 
4bff0a
-        r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)",
4bff0a
+        r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)(sv)",
4bff0a
                                   "PIDs", "au", 1, pid,
4bff0a
                                   "Description", "s", description,
4bff0a
                                   "Delegate", "b", 1,
4bff0a
+                                  "CollectMode", "s", "inactive-or-failed",
4bff0a
+                                  "AddRef", "b", 1,
4bff0a
                                   "Slice", "s", isempty(slice) ? SPECIAL_MACHINE_SLICE : slice);
4bff0a
         if (r < 0)
4bff0a
                 return bus_log_create_error(r);
4bff0a
@@ -324,3 +326,63 @@ int allocate_scope(
4bff0a
 
4bff0a
         return 0;
4bff0a
 }
4bff0a
+
4bff0a
+int terminate_scope(
4bff0a
+                sd_bus *bus,
4bff0a
+                const char *machine_name) {
4bff0a
+
4bff0a
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4bff0a
+        _cleanup_free_ char *scope = NULL;
4bff0a
+        int r;
4bff0a
+
4bff0a
+        r = unit_name_mangle_with_suffix(machine_name, 0, ".scope", &scope);
4bff0a
+        if (r < 0)
4bff0a
+                return log_error_errno(r, "Failed to mangle scope name: %m");
4bff0a
+
4bff0a
+        r = sd_bus_call_method(
4bff0a
+                        bus,
4bff0a
+                        "org.freedesktop.systemd1",
4bff0a
+                        "/org/freedesktop/systemd1",
4bff0a
+                        "org.freedesktop.systemd1.Manager",
4bff0a
+                        "AbandonScope",
4bff0a
+                        &error,
4bff0a
+                        NULL,
4bff0a
+                        "s",
4bff0a
+                        scope);
4bff0a
+        if (r < 0) {
4bff0a
+                log_debug_errno(r, "Failed to abandon scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
4bff0a
+                sd_bus_error_free(&error);
4bff0a
+        }
4bff0a
+
4bff0a
+        r = sd_bus_call_method(
4bff0a
+                        bus,
4bff0a
+                        "org.freedesktop.systemd1",
4bff0a
+                        "/org/freedesktop/systemd1",
4bff0a
+                        "org.freedesktop.systemd1.Manager",
4bff0a
+                        "KillUnit",
4bff0a
+                        &error,
4bff0a
+                        NULL,
4bff0a
+                        "ssi",
4bff0a
+                        scope,
4bff0a
+                        "all",
4bff0a
+                        (int32_t) SIGKILL);
4bff0a
+        if (r < 0) {
4bff0a
+                log_debug_errno(r, "Failed to SIGKILL scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
4bff0a
+                sd_bus_error_free(&error);
4bff0a
+        }
4bff0a
+
4bff0a
+        r = sd_bus_call_method(
4bff0a
+                        bus,
4bff0a
+                        "org.freedesktop.systemd1",
4bff0a
+                        "/org/freedesktop/systemd1",
4bff0a
+                        "org.freedesktop.systemd1.Manager",
4bff0a
+                        "UnrefUnit",
4bff0a
+                        &error,
4bff0a
+                        NULL,
4bff0a
+                        "s",
4bff0a
+                        scope);
4bff0a
+        if (r < 0)
4bff0a
+                log_debug_errno(r, "Failed to drop reference to scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
4bff0a
+
4bff0a
+        return 0;
4bff0a
+}
4bff0a
diff --git a/src/nspawn/nspawn-register.h b/src/nspawn/nspawn-register.h
4bff0a
index ddd8b053a3..05f5776f23 100644
4bff0a
--- a/src/nspawn/nspawn-register.h
4bff0a
+++ b/src/nspawn/nspawn-register.h
4bff0a
@@ -11,3 +11,4 @@ int register_machine(sd_bus *bus, const char *machine_name, pid_t pid, const cha
4bff0a
 int terminate_machine(sd_bus *bus, const char *machine_name);
4bff0a
 
4bff0a
 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);
4bff0a
+int terminate_scope(sd_bus *bus, const char *machine_name);
4bff0a
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
4bff0a
index c4943f6eb7..b40411dcd0 100644
4bff0a
--- a/src/nspawn/nspawn.c
4bff0a
+++ b/src/nspawn/nspawn.c
4bff0a
@@ -4065,8 +4065,12 @@ static int run(int master,
4bff0a
                 putc('\n', stdout);
4bff0a
 
4bff0a
         /* Kill if it is not dead yet anyway */
4bff0a
-        if (arg_register && !arg_keep_unit && bus)
4bff0a
-                terminate_machine(bus, arg_machine);
4bff0a
+        if (bus) {
4bff0a
+                if (arg_register)
4bff0a
+                        terminate_machine(bus, arg_machine);
4bff0a
+                else if (!arg_keep_unit)
4bff0a
+                        terminate_scope(bus, arg_machine);
4bff0a
+        }
4bff0a
 
4bff0a
         /* Normally redundant, but better safe than sorry */
4bff0a
         (void) kill(*pid, SIGKILL);