Blame SOURCES/libvirt-LXC-workaround-machined-uncleaned-data-with-containers-running-systemd.patch

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