From 1f0cd86b3dc0f938ce179cdddc62fc0f584e599d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Nov 2013 02:05:06 +0100 Subject: [PATCH] nspawn: explicitly terminate machines when we exit nspawn https://bugs.freedesktop.org/show_bug.cgi?id=68370 https://bugzilla.redhat.com/show_bug.cgi?id=988883 --- src/nspawn/nspawn.c | 69 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 80903a7ae..9f887134c 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -33,8 +33,6 @@ #include #include #include -#include -#include #include #include #include @@ -43,9 +41,9 @@ #include #include -#include -#include - +#include "sd-daemon.h" +#include "sd-bus.h" +#include "sd-id128.h" #include "log.h" #include "util.h" #include "mkdir.h" @@ -56,12 +54,12 @@ #include "strv.h" #include "path-util.h" #include "loopback-setup.h" -#include "sd-id128.h" #include "dev-setup.h" #include "fdset.h" #include "build.h" #include "fileio.h" #include "bus-util.h" +#include "bus-error.h" #include "ptyfwd.h" #ifndef TTY_GID @@ -955,10 +953,64 @@ static int register_machine(void) { strempty(arg_directory), !isempty(arg_slice), "Slice", "s", arg_slice); if (r < 0) { - log_error("Failed to register machine: %s", error.message ? error.message : strerror(-r)); + 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_unref_ sd_bus *bus = NULL; + const char *path; + int r; + + r = sd_bus_open_system(&bus); + if (r < 0) { + log_error("Failed to open system bus: %s", strerror(-r)); + return r; + } + + 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) { + log_error("Failed to parse GetMachineByPID() reply: %s", bus_error_message(&error, r)); return 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; } @@ -1391,6 +1443,9 @@ int main(int argc, char *argv[]) { putc('\n', stdout); /* Kill if it is not dead yet anyway */ + terminate_machine(pid); + + /* Redundant, but better safe than sorry */ kill(pid, SIGKILL); k = wait_for_terminate(pid, &status); -- 2.30.2