|
|
43fe83 |
From 58fab1b319adbb2204df5eca88109426ed867d8e Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <58fab1b319adbb2204df5eca88109426ed867d8e.1381871412.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
|
|
|
43fe83 |
Date: Mon, 14 Oct 2013 16:45:16 +0100
|
|
|
43fe83 |
Subject: [PATCH] LXC: workaround machined uncleaned data with containers
|
|
|
43fe83 |
running systemd.
|
|
|
43fe83 |
|
|
|
43fe83 |
For
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=1018730
|
|
|
43fe83 |
|
|
|
43fe83 |
The problem is described by [0] but its effect on libvirt is that
|
|
|
43fe83 |
starting a container with a full distro running systemd after having
|
|
|
43fe83 |
stopped it simply fails.
|
|
|
43fe83 |
|
|
|
43fe83 |
The container cleanup now calls the machined Terminate function to make
|
|
|
43fe83 |
sure that everything is in order for the next run.
|
|
|
43fe83 |
|
|
|
43fe83 |
[0]: https://bugs.freedesktop.org/show_bug.cgi?id=68370
|
|
|
43fe83 |
|
|
|
43fe83 |
(cherry picked from commit bd773e74f0d1d1b9ebbfcaa645178316b4f2265c)
|
|
|
43fe83 |
|
|
|
43fe83 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/libvirt_private.syms | 2 ++
|
|
|
43fe83 |
src/lxc/lxc_process.c | 8 +++++
|
|
|
43fe83 |
src/util/virsystemd.c | 80 +++++++++++++++++++++++++++++++++++++++++-------
|
|
|
43fe83 |
src/util/virsystemd.h | 8 +++++
|
|
|
43fe83 |
tests/virsystemdtest.c | 28 +++++++++++++++++
|
|
|
43fe83 |
5 files changed, 115 insertions(+), 11 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
43fe83 |
index 47e989c..d9561b8 100644
|
|
|
43fe83 |
--- a/src/libvirt_private.syms
|
|
|
43fe83 |
+++ b/src/libvirt_private.syms
|
|
|
43fe83 |
@@ -1938,8 +1938,10 @@ virSysinfoSetup;
|
|
|
43fe83 |
|
|
|
43fe83 |
# util/virsystemd.h
|
|
|
43fe83 |
virSystemdCreateMachine;
|
|
|
43fe83 |
+virSystemdMakeMachineName;
|
|
|
43fe83 |
virSystemdMakeScopeName;
|
|
|
43fe83 |
virSystemdMakeSliceName;
|
|
|
43fe83 |
+virSystemdTerminateMachine;
|
|
|
43fe83 |
|
|
|
43fe83 |
|
|
|
43fe83 |
# util/virthread.h
|
|
|
43fe83 |
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
|
|
|
43fe83 |
index 47e6dd7..724ffa9 100644
|
|
|
43fe83 |
--- a/src/lxc/lxc_process.c
|
|
|
43fe83 |
+++ b/src/lxc/lxc_process.c
|
|
|
43fe83 |
@@ -50,6 +50,7 @@
|
|
|
43fe83 |
#include "virstring.h"
|
|
|
43fe83 |
#include "viratomic.h"
|
|
|
43fe83 |
#include "virprocess.h"
|
|
|
43fe83 |
+#include "virsystemd.h"
|
|
|
43fe83 |
|
|
|
43fe83 |
#define VIR_FROM_THIS VIR_FROM_LXC
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -209,6 +210,13 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
|
|
|
43fe83 |
virCgroupFree(&priv->cgroup);
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+ /* Get machined to terminate the machine as it may not have cleaned it
|
|
|
43fe83 |
+ * properly. See https://bugs.freedesktop.org/show_bug.cgi?id=68370 for
|
|
|
43fe83 |
+ * the bug we are working around here.
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+ virSystemdTerminateMachine(vm->def->name, "lxc", true);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
/* now that we know it's stopped call the hook if present */
|
|
|
43fe83 |
if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
|
|
|
43fe83 |
char *xml = virDomainDefFormat(vm->def, 0);
|
|
|
43fe83 |
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
|
|
|
43fe83 |
index e72b7f0..1ba37cc 100644
|
|
|
43fe83 |
--- a/src/util/virsystemd.c
|
|
|
43fe83 |
+++ b/src/util/virsystemd.c
|
|
|
43fe83 |
@@ -116,6 +116,27 @@ char *virSystemdMakeSliceName(const char *partition)
|
|
|
43fe83 |
return virBufferContentAndReset(&buf;;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+char *virSystemdMakeMachineName(const char *name,
|
|
|
43fe83 |
+ const char *drivername,
|
|
|
43fe83 |
+ bool privileged)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ char *machinename = NULL;
|
|
|
43fe83 |
+ char *username = NULL;
|
|
|
43fe83 |
+ if (privileged) {
|
|
|
43fe83 |
+ if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ } else {
|
|
|
43fe83 |
+ if (!(username = virGetUserName(geteuid())))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+cleanup:
|
|
|
43fe83 |
+ VIR_FREE(username);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ return machinename;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
|
|
|
43fe83 |
/**
|
|
|
43fe83 |
* virSystemdCreateMachine:
|
|
|
43fe83 |
@@ -142,7 +163,6 @@ int virSystemdCreateMachine(const char *name,
|
|
|
43fe83 |
DBusConnection *conn;
|
|
|
43fe83 |
char *machinename = NULL;
|
|
|
43fe83 |
char *creatorname = NULL;
|
|
|
43fe83 |
- char *username = NULL;
|
|
|
43fe83 |
char *slicename = NULL;
|
|
|
43fe83 |
|
|
|
43fe83 |
ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
|
|
|
43fe83 |
@@ -152,15 +172,8 @@ int virSystemdCreateMachine(const char *name,
|
|
|
43fe83 |
conn = virDBusGetSystemBus();
|
|
|
43fe83 |
|
|
|
43fe83 |
ret = -1;
|
|
|
43fe83 |
- if (privileged) {
|
|
|
43fe83 |
- if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
|
|
|
43fe83 |
- goto cleanup;
|
|
|
43fe83 |
- } else {
|
|
|
43fe83 |
- if (!(username = virGetUserName(geteuid())))
|
|
|
43fe83 |
- goto cleanup;
|
|
|
43fe83 |
- if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
|
|
|
43fe83 |
- goto cleanup;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
+ if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged)))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
|
|
|
43fe83 |
if (virAsprintf(&creatorname, "libvirt-%s", drivername) < 0)
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
@@ -236,9 +249,54 @@ int virSystemdCreateMachine(const char *name,
|
|
|
43fe83 |
ret = 0;
|
|
|
43fe83 |
|
|
|
43fe83 |
cleanup:
|
|
|
43fe83 |
- VIR_FREE(username);
|
|
|
43fe83 |
VIR_FREE(creatorname);
|
|
|
43fe83 |
VIR_FREE(machinename);
|
|
|
43fe83 |
VIR_FREE(slicename);
|
|
|
43fe83 |
return ret;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+int virSystemdTerminateMachine(const char *name,
|
|
|
43fe83 |
+ const char *drivername,
|
|
|
43fe83 |
+ bool privileged)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ int ret;
|
|
|
43fe83 |
+ DBusConnection *conn;
|
|
|
43fe83 |
+ char *machinename = NULL;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
|
|
|
43fe83 |
+ if (ret < 0)
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ conn = virDBusGetSystemBus();
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ ret = -1;
|
|
|
43fe83 |
+ if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged)))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ /*
|
|
|
43fe83 |
+ * The systemd DBus API we're invoking has the
|
|
|
43fe83 |
+ * following signature
|
|
|
43fe83 |
+ *
|
|
|
43fe83 |
+ * TerminateMachine(in s name);
|
|
|
43fe83 |
+ *
|
|
|
43fe83 |
+ * @name a host unique name for the machine. shows up
|
|
|
43fe83 |
+ * in 'ps' listing & similar
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ VIR_DEBUG("Attempting to terminate machine via systemd");
|
|
|
43fe83 |
+ if (virDBusCallMethod(conn,
|
|
|
43fe83 |
+ NULL,
|
|
|
43fe83 |
+ "org.freedesktop.machine1",
|
|
|
43fe83 |
+ "/org/freedesktop/machine1",
|
|
|
43fe83 |
+ "org.freedesktop.machine1.Manager",
|
|
|
43fe83 |
+ "TerminateMachine",
|
|
|
43fe83 |
+ "s",
|
|
|
43fe83 |
+ machinename) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ ret = 0;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+cleanup:
|
|
|
43fe83 |
+ VIR_FREE(machinename);
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h
|
|
|
43fe83 |
index 414ae5a..d9845e1 100644
|
|
|
43fe83 |
--- a/src/util/virsystemd.h
|
|
|
43fe83 |
+++ b/src/util/virsystemd.h
|
|
|
43fe83 |
@@ -29,6 +29,10 @@ char *virSystemdMakeScopeName(const char *name,
|
|
|
43fe83 |
const char *slicename);
|
|
|
43fe83 |
char *virSystemdMakeSliceName(const char *partition);
|
|
|
43fe83 |
|
|
|
43fe83 |
+char *virSystemdMakeMachineName(const char *name,
|
|
|
43fe83 |
+ const char *drivername,
|
|
|
43fe83 |
+ bool privileged);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
int virSystemdCreateMachine(const char *name,
|
|
|
43fe83 |
const char *drivername,
|
|
|
43fe83 |
bool privileged,
|
|
|
43fe83 |
@@ -38,4 +42,8 @@ int virSystemdCreateMachine(const char *name,
|
|
|
43fe83 |
bool iscontainer,
|
|
|
43fe83 |
const char *partition);
|
|
|
43fe83 |
|
|
|
43fe83 |
+int virSystemdTerminateMachine(const char *name,
|
|
|
43fe83 |
+ const char *drivername,
|
|
|
43fe83 |
+ bool privileged);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
#endif /* __VIR_SYSTEMD_H__ */
|
|
|
43fe83 |
diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
|
|
|
43fe83 |
index 7dc7520..b314013 100644
|
|
|
43fe83 |
--- a/tests/virsystemdtest.c
|
|
|
43fe83 |
+++ b/tests/virsystemdtest.c
|
|
|
43fe83 |
@@ -51,6 +51,18 @@ static int testCreateContainer(const void *opaque ATTRIBUTE_UNUSED)
|
|
|
43fe83 |
return 0;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+static int testTerminateContainer(const void *opaque ATTRIBUTE_UNUSED)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ if (virSystemdTerminateMachine("demo",
|
|
|
43fe83 |
+ "lxc",
|
|
|
43fe83 |
+ true) < 0) {
|
|
|
43fe83 |
+ fprintf(stderr, "%s", "Failed to terminate LXC machine\n");
|
|
|
43fe83 |
+ return -1;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ return 0;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
unsigned char uuid[VIR_UUID_BUFLEN] = {
|
|
|
43fe83 |
@@ -74,6 +86,18 @@ static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
|
|
|
43fe83 |
return 0;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+static int testTerminateMachine(const void *opaque ATTRIBUTE_UNUSED)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ if (virSystemdTerminateMachine("demo",
|
|
|
43fe83 |
+ "qemu",
|
|
|
43fe83 |
+ false) < 0) {
|
|
|
43fe83 |
+ fprintf(stderr, "%s", "Failed to terminate KVM machine\n");
|
|
|
43fe83 |
+ return -1;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ return 0;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
unsigned char uuid[VIR_UUID_BUFLEN] = {
|
|
|
43fe83 |
@@ -181,8 +205,12 @@ mymain(void)
|
|
|
43fe83 |
|
|
|
43fe83 |
if (virtTestRun("Test create container ", 1, testCreateContainer, NULL) < 0)
|
|
|
43fe83 |
ret = -1;
|
|
|
43fe83 |
+ if (virtTestRun("Test terminate container ", 1, testTerminateContainer, NULL) < 0)
|
|
|
43fe83 |
+ ret = -1;
|
|
|
43fe83 |
if (virtTestRun("Test create machine ", 1, testCreateMachine, NULL) < 0)
|
|
|
43fe83 |
ret = -1;
|
|
|
43fe83 |
+ if (virtTestRun("Test terminate machine ", 1, testTerminateMachine, NULL) < 0)
|
|
|
43fe83 |
+ ret = -1;
|
|
|
43fe83 |
if (virtTestRun("Test create no systemd ", 1, testCreateNoSystemd, NULL) < 0)
|
|
|
43fe83 |
ret = -1;
|
|
|
43fe83 |
if (virtTestRun("Test create bad systemd ", 1, testCreateBadSystemd, NULL) < 0)
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|