X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fnspawn%2Fnspawn.c;h=06d627c0a9ce1840c938af070385073a292c7080;hb=5b30bef856e89a571df57b7b953e9a1409d9aced;hp=14774566a64dfe2c5f71946f88855a5c136003ad;hpb=04d39279245834494baccfdb9349db8bf80abd13;p=elogind.git diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 14774566a..06d627c0a 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 @@ -167,7 +165,7 @@ static int parse_argv(int argc, char *argv[]) { { "bind-ro", required_argument, NULL, ARG_BIND_RO }, { "machine", required_argument, NULL, 'M' }, { "slice", required_argument, NULL, 'S' }, - { NULL, 0, NULL, 0 } + {} }; int c, r; @@ -180,8 +178,7 @@ static int parse_argv(int argc, char *argv[]) { switch (c) { case 'h': - help(); - return 0; + return help(); case ARG_VERSION: puts(PACKAGE_STRING); @@ -224,6 +221,9 @@ static int parse_argv(int argc, char *argv[]) { case 'S': arg_slice = strdup(optarg); + if (!arg_slice) + return log_oom(); + break; case 'M': @@ -315,11 +315,11 @@ static int parse_argv(int argc, char *argv[]) { r = strv_extend(x, a); if (r < 0) - return r; + return log_oom(); r = strv_extend(x, b); if (r < 0) - return r; + return log_oom(); break; } @@ -328,8 +328,7 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); - return -EINVAL; + assert_not_reached("Unhandled option"); } } @@ -952,13 +951,65 @@ 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) + return bus_log_parse_error(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; +} + static bool audit_enabled(void) { int fd; @@ -1388,6 +1439,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);