3e5111
From b5c438b6dba5efe46a8489bde49201d953367c07 Mon Sep 17 00:00:00 2001
3e5111
Message-Id: <b5c438b6dba5efe46a8489bde49201d953367c07@dist-git>
3e5111
From: Pavel Hrdina <phrdina@redhat.com>
3e5111
Date: Tue, 16 May 2017 11:46:13 +0200
3e5111
Subject: [PATCH] qemu: improve detection of UNIX path generated by libvirt
3e5111
3e5111
Currently we consider all UNIX paths with specific prefix as generated
3e5111
by libvirt, but that's a wrong assumption.  Let's make the detection
3e5111
better by actually checking whether the whole path matches one of the
3e5111
paths that we generate or generated in the past.
3e5111
3e5111
The UNIX path isn't stored in config XML since libvirt-1.3.1.
3e5111
3e5111
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1446980
3e5111
3e5111
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
3e5111
(cherry picked from commit ed996604464ab1652ad8d2de3ac446f460dd2ab1)
3e5111
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
3e5111
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
3e5111
---
3e5111
 src/qemu/qemu_domain.c                             | 66 +++++++++++++++++-----
3e5111
 .../qemuxml2argv-channel-unix-source-path.xml      | 29 ++++++++++
3e5111
 .../qemuxml2xmlout-channel-unix-source-path.xml    | 45 +++++++++++++++
3e5111
 tests/qemuxml2xmltest.c                            |  2 +
3e5111
 4 files changed, 128 insertions(+), 14 deletions(-)
3e5111
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-unix-source-path.xml
3e5111
 create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-channel-unix-source-path.xml
3e5111
3e5111
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
3e5111
index 5ef3d0577..117c6142b 100644
3e5111
--- a/src/qemu/qemu_domain.c
3e5111
+++ b/src/qemu/qemu_domain.c
3e5111
@@ -3123,24 +3123,58 @@ qemuDomainDefaultNetModel(const virDomainDef *def,
3e5111
 
3e5111
 
3e5111
 /*
3e5111
- * Clear auto generated unix socket path, i.e., the one which starts with our
3e5111
- * channel directory.
3e5111
+ * Clear auto generated unix socket paths:
3e5111
+ *
3e5111
+ * libvirt 1.2.18 and older:
3e5111
+ *     {cfg->channelTargetDir}/{dom-name}.{target-name}
3e5111
+ *
3e5111
+ * libvirt 1.2.19 - 1.3.2:
3e5111
+ *     {cfg->channelTargetDir}/domain-{dom-name}/{target-name}
3e5111
+ *
3e5111
+ * libvirt 1.3.3 and newer:
3e5111
+ *     {cfg->channelTargetDir}/domain-{dom-id}-{short-dom-name}/{target-name}
3e5111
+ *
3e5111
+ * The unix socket path was stored in config XML until libvirt 1.3.0.
3e5111
+ * If someone specifies the same path as we generate, they shouldn't do it.
3e5111
+ *
3e5111
+ * This function clears the path for migration as well, so we need to clear
3e5111
+ * the path even if we are not storing it in the XML.
3e5111
  */
3e5111
-static void
3e5111
+static int
3e5111
 qemuDomainChrDefDropDefaultPath(virDomainChrDefPtr chr,
3e5111
                                 virQEMUDriverPtr driver)
3e5111
 {
3e5111
-    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
3e5111
+    virQEMUDriverConfigPtr cfg;
3e5111
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
3e5111
+    char *regexp = NULL;
3e5111
+    int ret = -1;
3e5111
 
3e5111
-    if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
3e5111
-        chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO &&
3e5111
-        chr->source->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
3e5111
-        chr->source->data.nix.path &&
3e5111
-        STRPREFIX(chr->source->data.nix.path, cfg->channelTargetDir)) {
3e5111
-        VIR_FREE(chr->source->data.nix.path);
3e5111
+    if (chr->deviceType != VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL ||
3e5111
+        chr->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO ||
3e5111
+        chr->source->type != VIR_DOMAIN_CHR_TYPE_UNIX ||
3e5111
+        !chr->source->data.nix.path) {
3e5111
+        return 0;
3e5111
     }
3e5111
 
3e5111
+    cfg = virQEMUDriverGetConfig(driver);
3e5111
+
3e5111
+    virBufferEscapeRegex(&buf, "^%s", cfg->channelTargetDir);
3e5111
+    virBufferAddLit(&buf, "/([^/]+\\.)|(domain-[^/]+/)");
3e5111
+    virBufferEscapeRegex(&buf, "%s$", chr->target.name);
3e5111
+
3e5111
+    if (virBufferCheckError(&buf) < 0)
3e5111
+        goto cleanup;
3e5111
+
3e5111
+    regexp = virBufferContentAndReset(&buf;;
3e5111
+
3e5111
+    if (virStringMatch(chr->source->data.nix.path, regexp))
3e5111
+        VIR_FREE(chr->source->data.nix.path);
3e5111
+
3e5111
+    ret = 0;
3e5111
+ cleanup:
3e5111
+    VIR_FREE(regexp);
3e5111
     virObjectUnref(cfg);
3e5111
+    return ret;
3e5111
 }
3e5111
 
3e5111
 
3e5111
@@ -3408,8 +3442,10 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
3e5111
 
3e5111
     /* clear auto generated unix socket path for inactive definitions */
3e5111
     if ((parseFlags & VIR_DOMAIN_DEF_PARSE_INACTIVE) &&
3e5111
-        dev->type == VIR_DOMAIN_DEVICE_CHR)
3e5111
-        qemuDomainChrDefDropDefaultPath(dev->data.chr, driver);
3e5111
+        dev->type == VIR_DOMAIN_DEVICE_CHR) {
3e5111
+        if (qemuDomainChrDefDropDefaultPath(dev->data.chr, driver) < 0)
3e5111
+            goto cleanup;
3e5111
+    }
3e5111
 
3e5111
     /* forbid capabilities mode hostdev in this kind of hypervisor */
3e5111
     if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
3e5111
@@ -4195,8 +4231,10 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
3e5111
             }
3e5111
         }
3e5111
 
3e5111
-        for (i = 0; i < def->nchannels; i++)
3e5111
-            qemuDomainChrDefDropDefaultPath(def->channels[i], driver);
3e5111
+        for (i = 0; i < def->nchannels; i++) {
3e5111
+            if (qemuDomainChrDefDropDefaultPath(def->channels[i], driver) < 0)
3e5111
+                goto cleanup;
3e5111
+        }
3e5111
     }
3e5111
 
3e5111
  format:
3e5111
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-unix-source-path.xml b/tests/qemuxml2argvdata/qemuxml2argv-channel-unix-source-path.xml
3e5111
new file mode 100644
3e5111
index 000000000..42cb3c387
3e5111
--- /dev/null
3e5111
+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-unix-source-path.xml
3e5111
@@ -0,0 +1,29 @@
3e5111
+<domain type='qemu'>
3e5111
+  <name>QEMUGuest1</name>
3e5111
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
3e5111
+  <memory unit='KiB'>219100</memory>
3e5111
+  <vcpu placement='static'>1</vcpu>
3e5111
+  <os>
3e5111
+    <type arch='x86_64' machine='pc'>hvm</type>
3e5111
+  </os>
3e5111
+  <devices>
3e5111
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
3e5111
+    <channel type='unix'>
3e5111
+      <source mode='bind' path='/tmp/channel/QEMUGuest1.org.qemu.guest_agent.0'/>
3e5111
+      <target type='virtio' name='org.qemu.guest_agent.0'/>
3e5111
+    </channel>
3e5111
+    <channel type='unix'>
3e5111
+      <source mode='bind' path='/tmp/channel/domain-QEMUGuest1/org.qemu.guest_agent.1'/>
3e5111
+      <target type='virtio' name='org.qemu.guest_agent.1'/>
3e5111
+    </channel>
3e5111
+    <channel type='unix'>
3e5111
+      <source mode='bind' path='/tmp/channel/domain-1-QEMUGuest1/org.qemu.guest_agent.2'/>
3e5111
+      <target type='virtio' name='org.qemu.guest_agent.2'/>
3e5111
+    </channel>
3e5111
+    <channel type='unix'>
3e5111
+      <source mode='bind' path='/tmp/channel/QEMUGuest1/org.qemu.guest_agent.3'/>
3e5111
+      <target type='virtio' name='org.qemu.guest_agent.3'/>
3e5111
+    </channel>
3e5111
+    <memballoon model='none'/>
3e5111
+  </devices>
3e5111
+</domain>
3e5111
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-channel-unix-source-path.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-channel-unix-source-path.xml
3e5111
new file mode 100644
3e5111
index 000000000..2d8fa1e3a
3e5111
--- /dev/null
3e5111
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-channel-unix-source-path.xml
3e5111
@@ -0,0 +1,45 @@
3e5111
+<domain type='qemu'>
3e5111
+  <name>QEMUGuest1</name>
3e5111
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
3e5111
+  <memory unit='KiB'>219100</memory>
3e5111
+  <currentMemory unit='KiB'>219100</currentMemory>
3e5111
+  <vcpu placement='static'>1</vcpu>
3e5111
+  <os>
3e5111
+    <type arch='x86_64' machine='pc'>hvm</type>
3e5111
+    <boot dev='hd'/>
3e5111
+  </os>
3e5111
+  <clock offset='utc'/>
3e5111
+  <on_poweroff>destroy</on_poweroff>
3e5111
+  <on_reboot>restart</on_reboot>
3e5111
+  <on_crash>destroy</on_crash>
3e5111
+  <devices>
3e5111
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
3e5111
+    <controller type='usb' index='0'>
3e5111
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
3e5111
+    </controller>
3e5111
+    <controller type='pci' index='0' model='pci-root'/>
3e5111
+    <controller type='virtio-serial' index='0'>
3e5111
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
3e5111
+    </controller>
3e5111
+    <channel type='unix'>
3e5111
+      <target type='virtio' name='org.qemu.guest_agent.0'/>
3e5111
+      <address type='virtio-serial' controller='0' bus='0' port='1'/>
3e5111
+    </channel>
3e5111
+    <channel type='unix'>
3e5111
+      <target type='virtio' name='org.qemu.guest_agent.1'/>
3e5111
+      <address type='virtio-serial' controller='0' bus='0' port='2'/>
3e5111
+    </channel>
3e5111
+    <channel type='unix'>
3e5111
+      <target type='virtio' name='org.qemu.guest_agent.2'/>
3e5111
+      <address type='virtio-serial' controller='0' bus='0' port='3'/>
3e5111
+    </channel>
3e5111
+    <channel type='unix'>
3e5111
+      <source mode='bind' path='/tmp/channel/QEMUGuest1/org.qemu.guest_agent.3'/>
3e5111
+      <target type='virtio' name='org.qemu.guest_agent.3'/>
3e5111
+      <address type='virtio-serial' controller='0' bus='0' port='4'/>
3e5111
+    </channel>
3e5111
+    <input type='mouse' bus='ps2'/>
3e5111
+    <input type='keyboard' bus='ps2'/>
3e5111
+    <memballoon model='none'/>
3e5111
+  </devices>
3e5111
+</domain>
3e5111
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
3e5111
index 26a2259fd..ff533ab19 100644
3e5111
--- a/tests/qemuxml2xmltest.c
3e5111
+++ b/tests/qemuxml2xmltest.c
3e5111
@@ -555,6 +555,8 @@ mymain(void)
3e5111
     DO_TEST("channel-virtio", NONE);
3e5111
     DO_TEST("channel-virtio-state", NONE);
3e5111
 
3e5111
+    DO_TEST_FULL("channel-unix-source-path", WHEN_INACTIVE, GIC_NONE, NONE);
3e5111
+
3e5111
     DO_TEST("hostdev-usb-address", NONE);
3e5111
     DO_TEST("hostdev-pci-address", NONE);
3e5111
     DO_TEST("hostdev-vfio", NONE);
3e5111
-- 
3e5111
2.13.0
3e5111