]> xenbits.xensource.com Git - libvirt.git/commitdiff
LXC: workaround machined uncleaned data with containers running systemd.
authorCédric Bosdonnat <cbosdonnat@suse.com>
Mon, 30 Sep 2013 14:46:29 +0000 (16:46 +0200)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 30 Sep 2013 15:47:23 +0000 (16:47 +0100)
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

src/libvirt_private.syms
src/lxc/lxc_process.c
src/util/virsystemd.c
src/util/virsystemd.h
tests/virsystemdtest.c

index 48e4b047c8666104c32e8cb54254611952680476..4bc4d69977f2107de3aeaac99c9838d99c76e829 100644 (file)
@@ -1947,8 +1947,10 @@ virSysinfoSetup;
 
 # util/virsystemd.h
 virSystemdCreateMachine;
+virSystemdMakeMachineName;
 virSystemdMakeScopeName;
 virSystemdMakeSliceName;
+virSystemdTerminateMachine;
 
 
 # util/virthread.h
index 4835bd50036b74d2dedd3e6a97822aa2d70f483d..f92c613293c3584314df4477f2f057625c6271f4 100644 (file)
@@ -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(virLXCDriverPtr driver,
         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 e72b7f027624da4b6eea995d7899fa9c536d55ee..1ba37ccdfe74338748cb40342bc3e099eab133b6 100644 (file)
@@ -116,6 +116,27 @@ char *virSystemdMakeSliceName(const char *partition)
     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 *name,
     DBusConnection *conn;
     char *machinename = NULL;
     char *creatorname = NULL;
-    char *username = NULL;
     char *slicename = NULL;
 
     ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
@@ -152,15 +172,8 @@ int virSystemdCreateMachine(const char *name,
     conn = virDBusGetSystemBus();
 
     ret = -1;
-    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;
@@ -236,9 +249,54 @@ int virSystemdCreateMachine(const char *name,
     ret = 0;
 
 cleanup:
-    VIR_FREE(username);
     VIR_FREE(creatorname);
     VIR_FREE(machinename);
     VIR_FREE(slicename);
     return ret;
 }
+
+int virSystemdTerminateMachine(const char *name,
+                               const char *drivername,
+                               bool privileged)
+{
+    int ret;
+    DBusConnection *conn;
+    char *machinename = NULL;
+
+    ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
+    if (ret < 0)
+        return ret;
+
+    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 414ae5ac9fea2793e501f080b76b4721546280f4..d9845e14c2f4f5d69563a47541848726f0627c50 100644 (file)
@@ -29,6 +29,10 @@ char *virSystemdMakeScopeName(const char *name,
                               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 *name,
                             bool iscontainer,
                             const char *partition);
 
+int virSystemdTerminateMachine(const char *name,
+                               const char *drivername,
+                               bool privileged);
+
 #endif /* __VIR_SYSTEMD_H__ */
index e68b3ac664f60628549b6f691779adc54907453e..e6efebf3a8f291b0428af82426ee906f37f1f097 100644 (file)
@@ -54,6 +54,18 @@ static int testCreateContainer(const void *opaque ATTRIBUTE_UNUSED)
     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] = {
@@ -77,6 +89,18 @@ static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
     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] = {
@@ -184,8 +208,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)