forked from pool/libvirt
65c4cfdc02
bd773e74-lxc-terminate-machine.patch bnc#842834 OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=318
248 lines
7.9 KiB
Diff
248 lines
7.9 KiB
Diff
commit bd773e74f0d1d1b9ebbfcaa645178316b4f2265c
|
|
Author: Cédric Bosdonnat <cbosdonnat@suse.com>
|
|
Date: Mon Sep 30 16:46:29 2013 +0200
|
|
|
|
LXC: workaround machined uncleaned data with containers running systemd.
|
|
|
|
The problem is described by [0] but its effect on libvirt is that
|
|
starting a container with a full distro running systemd after having
|
|
stopped it simply fails.
|
|
|
|
The container cleanup now calls the machined Terminate function to make
|
|
sure that everything is in order for the next run.
|
|
|
|
[0]: https://bugs.freedesktop.org/show_bug.cgi?id=68370
|
|
|
|
Index: libvirt-1.1.2/src/libvirt_private.syms
|
|
===================================================================
|
|
--- libvirt-1.1.2.orig/src/libvirt_private.syms
|
|
+++ libvirt-1.1.2/src/libvirt_private.syms
|
|
@@ -1940,8 +1940,10 @@ virSysinfoSetup;
|
|
|
|
# util/virsystemd.h
|
|
virSystemdCreateMachine;
|
|
+virSystemdMakeMachineName;
|
|
virSystemdMakeScopeName;
|
|
virSystemdMakeSliceName;
|
|
+virSystemdTerminateMachine;
|
|
|
|
|
|
# util/virthread.h
|
|
Index: libvirt-1.1.2/src/lxc/lxc_process.c
|
|
===================================================================
|
|
--- libvirt-1.1.2.orig/src/lxc/lxc_process.c
|
|
+++ libvirt-1.1.2/src/lxc/lxc_process.c
|
|
@@ -50,6 +50,7 @@
|
|
#include "virstring.h"
|
|
#include "viratomic.h"
|
|
#include "virprocess.h"
|
|
+#include "virsystemd.h"
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_LXC
|
|
|
|
@@ -210,6 +211,13 @@ static void virLXCProcessCleanup(virLXCD
|
|
virCgroupFree(&priv->cgroup);
|
|
}
|
|
|
|
+ /* Get machined to terminate the machine as it may not have cleaned it
|
|
+ * properly. See https://bugs.freedesktop.org/show_bug.cgi?id=68370 for
|
|
+ * the bug we are working around here.
|
|
+ */
|
|
+ virSystemdTerminateMachine(vm->def->name, "lxc", true);
|
|
+
|
|
+
|
|
/* now that we know it's stopped call the hook if present */
|
|
if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
|
|
char *xml = virDomainDefFormat(vm->def, 0);
|
|
Index: libvirt-1.1.2/src/util/virsystemd.c
|
|
===================================================================
|
|
--- libvirt-1.1.2.orig/src/util/virsystemd.c
|
|
+++ libvirt-1.1.2/src/util/virsystemd.c
|
|
@@ -116,6 +116,27 @@ char *virSystemdMakeSliceName(const char
|
|
return virBufferContentAndReset(&buf);
|
|
}
|
|
|
|
+char *virSystemdMakeMachineName(const char *name,
|
|
+ const char *drivername,
|
|
+ bool privileged)
|
|
+{
|
|
+ char *machinename = NULL;
|
|
+ char *username = NULL;
|
|
+ if (privileged) {
|
|
+ if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
|
|
+ goto cleanup;
|
|
+ } else {
|
|
+ if (!(username = virGetUserName(geteuid())))
|
|
+ goto cleanup;
|
|
+ if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+cleanup:
|
|
+ VIR_FREE(username);
|
|
+
|
|
+ return machinename;
|
|
+}
|
|
|
|
/**
|
|
* virSystemdCreateMachine:
|
|
@@ -142,7 +163,6 @@ int virSystemdCreateMachine(const char *
|
|
DBusConnection *conn;
|
|
char *machinename = NULL;
|
|
char *creatorname = NULL;
|
|
- char *username = NULL;
|
|
char *slicename = NULL;
|
|
|
|
if (!virDBusHasSystemBus())
|
|
@@ -150,15 +170,8 @@ int virSystemdCreateMachine(const char *
|
|
|
|
conn = virDBusGetSystemBus();
|
|
|
|
- if (privileged) {
|
|
- if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
|
|
- goto cleanup;
|
|
- } else {
|
|
- if (!(username = virGetUserName(geteuid())))
|
|
- goto cleanup;
|
|
- if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
|
|
- goto cleanup;
|
|
- }
|
|
+ if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged)))
|
|
+ goto cleanup;
|
|
|
|
if (virAsprintf(&creatorname, "libvirt-%s", drivername) < 0)
|
|
goto cleanup;
|
|
@@ -241,8 +254,52 @@ int virSystemdCreateMachine(const char *
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
- VIR_FREE(username);
|
|
VIR_FREE(creatorname);
|
|
VIR_FREE(machinename);
|
|
return ret;
|
|
}
|
|
+
|
|
+int virSystemdTerminateMachine(const char *name,
|
|
+ const char *drivername,
|
|
+ bool privileged)
|
|
+{
|
|
+ int ret;
|
|
+ DBusConnection *conn;
|
|
+ char *machinename = NULL;
|
|
+
|
|
+ if(!virDBusHasSystemBus())
|
|
+ return -2;
|
|
+
|
|
+ conn = virDBusGetSystemBus();
|
|
+
|
|
+ ret = -1;
|
|
+ if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged)))
|
|
+ goto cleanup;
|
|
+
|
|
+ /*
|
|
+ * The systemd DBus API we're invoking has the
|
|
+ * following signature
|
|
+ *
|
|
+ * TerminateMachine(in s name);
|
|
+ *
|
|
+ * @name a host unique name for the machine. shows up
|
|
+ * in 'ps' listing & similar
|
|
+ */
|
|
+
|
|
+ VIR_DEBUG("Attempting to terminate machine via systemd");
|
|
+ if (virDBusCallMethod(conn,
|
|
+ NULL,
|
|
+ "org.freedesktop.machine1",
|
|
+ "/org/freedesktop/machine1",
|
|
+ "org.freedesktop.machine1.Manager",
|
|
+ "TerminateMachine",
|
|
+ "s",
|
|
+ machinename) < 0)
|
|
+ goto cleanup;
|
|
+
|
|
+ ret = 0;
|
|
+
|
|
+cleanup:
|
|
+ VIR_FREE(machinename);
|
|
+ return ret;
|
|
+}
|
|
Index: libvirt-1.1.2/src/util/virsystemd.h
|
|
===================================================================
|
|
--- libvirt-1.1.2.orig/src/util/virsystemd.h
|
|
+++ libvirt-1.1.2/src/util/virsystemd.h
|
|
@@ -29,6 +29,10 @@ char *virSystemdMakeScopeName(const char
|
|
const char *slicename);
|
|
char *virSystemdMakeSliceName(const char *partition);
|
|
|
|
+char *virSystemdMakeMachineName(const char *name,
|
|
+ const char *drivername,
|
|
+ bool privileged);
|
|
+
|
|
int virSystemdCreateMachine(const char *name,
|
|
const char *drivername,
|
|
bool privileged,
|
|
@@ -38,4 +42,8 @@ int virSystemdCreateMachine(const char *
|
|
bool iscontainer,
|
|
const char *partition);
|
|
|
|
+int virSystemdTerminateMachine(const char *name,
|
|
+ const char *drivername,
|
|
+ bool privileged);
|
|
+
|
|
#endif /* __VIR_SYSTEMD_H__ */
|
|
Index: libvirt-1.1.2/tests/virsystemdtest.c
|
|
===================================================================
|
|
--- libvirt-1.1.2.orig/tests/virsystemdtest.c
|
|
+++ libvirt-1.1.2/tests/virsystemdtest.c
|
|
@@ -51,6 +51,18 @@ static int testCreateContainer(const voi
|
|
return 0;
|
|
}
|
|
|
|
+static int testTerminateContainer(const void *opaque ATTRIBUTE_UNUSED)
|
|
+{
|
|
+ if (virSystemdTerminateMachine("demo",
|
|
+ "lxc",
|
|
+ true) < 0) {
|
|
+ fprintf(stderr, "%s", "Failed to terminate LXC machine\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
|
|
{
|
|
unsigned char uuid[VIR_UUID_BUFLEN] = {
|
|
@@ -74,6 +86,18 @@ static int testCreateMachine(const void
|
|
return 0;
|
|
}
|
|
|
|
+static int testTerminateMachine(const void *opaque ATTRIBUTE_UNUSED)
|
|
+{
|
|
+ if (virSystemdTerminateMachine("demo",
|
|
+ "qemu",
|
|
+ false) < 0) {
|
|
+ fprintf(stderr, "%s", "Failed to terminate KVM machine\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED)
|
|
{
|
|
unsigned char uuid[VIR_UUID_BUFLEN] = {
|
|
@@ -177,8 +201,12 @@ mymain(void)
|
|
|
|
if (virtTestRun("Test create container ", 1, testCreateContainer, NULL) < 0)
|
|
ret = -1;
|
|
+ if (virtTestRun("Test terminate container ", 1, testTerminateContainer, NULL) < 0)
|
|
+ ret = -1;
|
|
if (virtTestRun("Test create machine ", 1, testCreateMachine, NULL) < 0)
|
|
ret = -1;
|
|
+ if (virtTestRun("Test terminate machine ", 1, testTerminateMachine, NULL) < 0)
|
|
+ ret = -1;
|
|
if (virtTestRun("Test create no systemd ", 1, testCreateNoSystemd, NULL) < 0)
|
|
ret = -1;
|
|
if (virtTestRun("Test create bad systemd ", 1, testCreateBadSystemd, NULL) < 0)
|