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