[libvirt] [PATCH 0/5] introduce reconnect feature for chardev devices

Pavel Hrdina (5): qemu: introduce QEMU_CAPS_CHARDEV_RECONNECT conf: introduce reconnect element for chardev source tests: add generic xml chardev reconnect tests qemu: implement chardev source reconnect tests: add qemu chardev srouce reconnect tests docs/formatdomain.html.in | 11 ++ docs/schemas/domaincommon.rng | 12 +++ src/conf/domain_conf.c | 119 +++++++++++++++++++-- src/conf/domain_conf.h | 11 ++ src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 17 +++ src/qemu/qemu_domain.c | 101 +++++++++++++++++ .../generic-chardev-reconnect-invalid-mode.xml | 26 +++++ .../generic-chardev-reconnect-missing-timeout.xml | 26 +++++ .../generic-chardev-reconnect.xml | 32 ++++++ .../generic-chardev-reconnect.xml | 33 ++++++ tests/genericxml2xmltest.c | 5 + tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 1 + .../caps_2.6.0-gicv2.aarch64.xml | 1 + .../caps_2.6.0-gicv3.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 1 + .../qemuxml2argv-channel-reconnect.args | 31 ++++++ ...uxml2argv-chardev-reconnect-invalid-timeout.xml | 23 ++++ .../qemuxml2argv-chardev-reconnect.args | 40 +++++++ .../qemuxml2argv-chardev-reconnect.xml | 46 ++++++++ tests/qemuxml2argvtest.c | 11 ++ 31 files changed, 552 insertions(+), 8 deletions(-) create mode 100644 tests/genericxml2xmlindata/generic-chardev-reconnect-invalid-mode.xml create mode 100644 tests/genericxml2xmlindata/generic-chardev-reconnect-missing-timeout.xml create mode 100644 tests/genericxml2xmlindata/generic-chardev-reconnect.xml create mode 100644 tests/genericxml2xmloutdata/generic-chardev-reconnect.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect-invalid-timeout.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.xml -- 2.13.5

Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 1 + 15 files changed, 16 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 38a9f09f53..fa8d026b21 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -437,6 +437,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "spapr-pci-host-bridge.numa_node", "vnc-multi-servers", "virtio-net.tx_queue_size", + "chardev-reconnect", ); @@ -3235,6 +3236,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = { { "machine", "kernel_irqchip", QEMU_CAPS_MACHINE_KERNEL_IRQCHIP }, { "machine", "loadparm", QEMU_CAPS_LOADPARM }, { "vnc", "vnc", QEMU_CAPS_VNC_MULTI_SERVERS }, + { "chardev", "reconnect", QEMU_CAPS_CHARDEV_RECONNECT }, }; static int diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 8804cc7819..7b59619497 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -423,6 +423,7 @@ typedef enum { QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, /* spapr-pci-host-bridge.numa_node= */ QEMU_CAPS_VNC_MULTI_SERVERS, /* -vnc vnc=unix:/path */ QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE, /* virtio-net-*.tx_queue_size */ + QEMU_CAPS_CHARDEV_RECONNECT, /* -chardev *,reconnect */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml index 11c8765738..5cd4772fdf 100644 --- a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml @@ -186,6 +186,7 @@ <flag name='query-named-block-nodes'/> <flag name='kernel-irqchip'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2004000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml index eee1ab24d9..3ad458121b 100644 --- a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml @@ -192,6 +192,7 @@ <flag name='query-named-block-nodes'/> <flag name='kernel-irqchip'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2005000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml index f8746f4c1e..032ffb0810 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml @@ -170,6 +170,7 @@ <flag name='kernel-irqchip'/> <flag name='kernel-irqchip.split'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml index 0ce1c8a333..ce95a325ed 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml @@ -170,6 +170,7 @@ <flag name='kernel-irqchip'/> <flag name='kernel-irqchip.split'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml index 92dba13b06..5f2ddf90d2 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml @@ -165,6 +165,7 @@ <flag name='kernel-irqchip.split'/> <flag name='spapr-pci-host-bridge'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml index 1937dc9c11..cfe04eda29 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml @@ -202,6 +202,7 @@ <flag name='kernel-irqchip'/> <flag name='kernel-irqchip.split'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml index 1c1aab8dec..81189960eb 100644 --- a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml @@ -132,6 +132,7 @@ <flag name='kernel-irqchip'/> <flag name='kernel-irqchip.split'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2007000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml index b484411314..a388515bae 100644 --- a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml @@ -205,6 +205,7 @@ <flag name='kernel-irqchip.split'/> <flag name='intel-iommu.intremap'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2007000</version> <kvmVersion>0</kvmVersion> <package> (v2.7.0)</package> diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml index 5a326d9881..8b05c091ed 100644 --- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml @@ -134,6 +134,7 @@ <flag name='kernel-irqchip'/> <flag name='kernel-irqchip.split'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2007093</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml index e31abd4b8b..18119a15be 100644 --- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml @@ -207,6 +207,7 @@ <flag name='intel-iommu.intremap'/> <flag name='intel-iommu.eim'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2008000</version> <kvmVersion>0</kvmVersion> <package> (v2.8.0)</package> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml index f80bfc434c..7d6af50fc9 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml @@ -170,6 +170,7 @@ <flag name='spapr-pci-host-bridge'/> <flag name='spapr-pci-host-bridge.numa_node'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <package> (v2.9.0)</package> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml index bed2c2da93..7db2554d72 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml @@ -135,6 +135,7 @@ <flag name='virtio.iommu_platform'/> <flag name='virtio.ats'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml index 2b406704a6..028e596b60 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml @@ -218,6 +218,7 @@ <flag name='virtio.iommu_platform'/> <flag name='virtio.ats'/> <flag name='vnc-multi-servers'/> + <flag name='chardev-reconnect'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <package> (v2.9.0)</package> -- 2.13.5

On Mon, Aug 28, 2017 at 02:56:49PM +0200, Pavel Hrdina wrote:
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 1 + 15 files changed, 16 insertions(+)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 8804cc7819..7b59619497 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -423,6 +423,7 @@ typedef enum { QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, /* spapr-pci-host-bridge.numa_node= */ QEMU_CAPS_VNC_MULTI_SERVERS, /* -vnc vnc=unix:/path */ QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE, /* virtio-net-*.tx_queue_size */ + QEMU_CAPS_CHARDEV_RECONNECT, /* -chardev *,reconnect */
We use a dot to separate the attributes in the rest of the comments.
QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags;
Jan

On Mon, Aug 28, 2017 at 03:07:25PM +0200, Ján Tomko wrote:
On Mon, Aug 28, 2017 at 02:56:49PM +0200, Pavel Hrdina wrote:
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 1 + 15 files changed, 16 insertions(+)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 8804cc7819..7b59619497 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -423,6 +423,7 @@ typedef enum { QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, /* spapr-pci-host-bridge.numa_node= */ QEMU_CAPS_VNC_MULTI_SERVERS, /* -vnc vnc=unix:/path */ QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE, /* virtio-net-*.tx_queue_size */ + QEMU_CAPS_CHARDEV_RECONNECT, /* -chardev *,reconnect */
We use a dot to separate the attributes in the rest of the comments.
We use the dot for devices, this is not a device. I can change it to /* -chardev reconnect */. Pavel

Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- docs/formatdomain.html.in | 11 ++++ docs/schemas/domaincommon.rng | 12 +++++ src/conf/domain_conf.c | 119 +++++++++++++++++++++++++++++++++++++++--- src/conf/domain_conf.h | 11 ++++ 4 files changed, 145 insertions(+), 8 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fba8cfc6f3..205122f28e 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -6298,6 +6298,17 @@ qemu-kvm -net nic,model=? /dev/null slot. </p> + <p> + For character device with type <code>unix</code> or <code>tcp</code> + the <code>source</code> has an optional element <code>reconnect</code> + which configures reconnect timeout if the connection is lost. + There are two attributes, <code>enabled</code> where possible + values are <code>yes</code> and <code>no</code> and <code>timeout</code> + which is in seconds. The <code>reconnect</code> attribute is valid only + for <code>connect</code> mode. + <span class="since">Since 3.7.0 (QEMU driver only)</span>. + </p> + <h5><a id="elementsCharGuestInterface">Guest interface</a></h5> <p> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 3f56d8f45b..06c5a91b3d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3634,6 +3634,18 @@ <ref name="virYesNo"/> </attribute> </optional> + <optional> + <element name="reconnect"> + <attribute name="enabled"> + <ref name="virYesNo"/> + </attribute> + <optional> + <attribute name="timeout"> + <ref name="unsignedInt"/> + </attribute> + </optional> + </element> + </optional> <zeroOrMore> <ref name='devSeclabel'/> </zeroOrMore> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5bad3976cf..e291d13ac5 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5130,6 +5130,12 @@ virDomainChrSourceDefValidate(const virDomainChrSourceDef *def, _("Missing source service attribute for char device")); return -1; } + + if (def->data.tcp.listen && def->data.tcp.reconnect.enabled) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("chardev reconnect is possible only for connect mode")); + return -1; + } break; case VIR_DOMAIN_CHR_TYPE_UDP: @@ -5150,6 +5156,12 @@ virDomainChrSourceDefValidate(const virDomainChrSourceDef *def, _("Missing source path attribute for char device")); return -1; } + + if (def->data.nix.listen && def->data.nix.reconnect.enabled) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("chardev reconnect is possible only for connect mode")); + return -1; + } break; case VIR_DOMAIN_CHR_TYPE_SPICEPORT: @@ -11115,6 +11127,56 @@ virDomainChrDefParseTargetXML(virDomainChrDefPtr def, return ret; } +static int +virDomainChrSourceReconnectDefParseXML(virDomainChrSourceReconnectDefPtr def, + xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + int ret = -1; + int tmpVal; + char *tmp = NULL; + xmlNodePtr saveNode = ctxt->node; + xmlNodePtr cur; + + ctxt->node = node; + + if ((cur = virXPathNode("./reconnect", ctxt))) { + if ((tmp = virXMLPropString(cur, "enabled"))) { + if ((tmpVal = virTristateBoolTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid reconnect enabled value: '%s'"), + tmp); + goto cleanup; + } + def->enabled = tmpVal; + VIR_FREE(tmp); + } + + if (def->enabled == VIR_TRISTATE_BOOL_YES) { + if ((tmp = virXMLPropString(cur, "timeout"))) { + if (virStrToLong_ui(tmp, NULL, 10, &def->timeout) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid reconnect enabled value: '%s'"), + tmp); + goto cleanup; + } + VIR_FREE(tmp); + } else { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing timeout for chardev with " + "reconnect enabled")); + goto cleanup; + } + } + } + + ret = 0; + cleanup: + ctxt->node = saveNode; + VIR_FREE(tmp); + return ret; +} + typedef enum { VIR_DOMAIN_CHR_SOURCE_MODE_CONNECT, @@ -11152,6 +11214,7 @@ virDomainChrSourceDefParseMode(xmlNodePtr source) static int virDomainChrSourceDefParseTCP(virDomainChrSourceDefPtr def, xmlNodePtr source, + xmlXPathContextPtr ctxt, unsigned int flags) { int mode; @@ -11187,6 +11250,12 @@ virDomainChrSourceDefParseTCP(virDomainChrSourceDefPtr def, VIR_FREE(tmp); } + if (virDomainChrSourceReconnectDefParseXML(&def->data.tcp.reconnect, + source, + ctxt) < 0) { + goto error; + } + return 0; error: @@ -11220,7 +11289,8 @@ virDomainChrSourceDefParseUDP(virDomainChrSourceDefPtr def, static int virDomainChrSourceDefParseUnix(virDomainChrSourceDefPtr def, - xmlNodePtr source) + xmlNodePtr source, + xmlXPathContextPtr ctxt) { int mode; @@ -11231,6 +11301,12 @@ virDomainChrSourceDefParseUnix(virDomainChrSourceDefPtr def, def->data.nix.listen = mode == VIR_DOMAIN_CHR_SOURCE_MODE_BIND; def->data.nix.path = virXMLPropString(source, "path"); + if (virDomainChrSourceReconnectDefParseXML(&def->data.nix.reconnect, + source, + ctxt) < 0) { + return -1; + } + return 0; } @@ -11359,7 +11435,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, break; case VIR_DOMAIN_CHR_TYPE_UNIX: - if (virDomainChrSourceDefParseUnix(def, cur) < 0) + if (virDomainChrSourceDefParseUnix(def, cur, ctxt) < 0) goto error; break; @@ -11369,7 +11445,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, break; case VIR_DOMAIN_CHR_TYPE_TCP: - if (virDomainChrSourceDefParseTCP(def, cur, flags) < 0) + if (virDomainChrSourceDefParseTCP(def, cur, ctxt, flags) < 0) goto error; break; @@ -11613,6 +11689,7 @@ virDomainChrDefParseXML(virDomainXMLOptionPtr xmlopt, static virDomainSmartcardDefPtr virDomainSmartcardDefParseXML(virDomainXMLOptionPtr xmlopt, xmlNodePtr node, + xmlXPathContextPtr ctxt, unsigned int flags) { xmlNodePtr cur; @@ -11705,7 +11782,7 @@ virDomainSmartcardDefParseXML(virDomainXMLOptionPtr xmlopt, cur = node->children; if (virDomainChrSourceDefParseXML(def->data.passthru, cur, flags, - NULL, NULL, NULL, 0) < 0) + NULL, ctxt, NULL, 0) < 0) goto error; if (def->data.passthru->type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) { @@ -14183,6 +14260,7 @@ virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt, static virDomainRedirdevDefPtr virDomainRedirdevDefParseXML(virDomainXMLOptionPtr xmlopt, xmlNodePtr node, + xmlXPathContextPtr ctxt, virHashTablePtr bootHash, unsigned int flags) { @@ -14224,7 +14302,7 @@ virDomainRedirdevDefParseXML(virDomainXMLOptionPtr xmlopt, /* boot gets parsed in virDomainDeviceInfoParseXML * source gets parsed in virDomainChrSourceDefParseXML */ if (virDomainChrSourceDefParseXML(def->source, cur, flags, - NULL, NULL, NULL, 0) < 0) + NULL, ctxt, NULL, 0) < 0) goto error; if (def->source->type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) @@ -14883,7 +14961,7 @@ virDomainDeviceDefParse(const char *xmlStr, break; case VIR_DOMAIN_DEVICE_REDIRDEV: if (!(dev->data.redirdev = virDomainRedirdevDefParseXML(xmlopt, node, - NULL, flags))) + ctxt, NULL, flags))) goto error; break; case VIR_DOMAIN_DEVICE_RNG: @@ -14902,7 +14980,7 @@ virDomainDeviceDefParse(const char *xmlStr, break; case VIR_DOMAIN_DEVICE_SMARTCARD: if (!(dev->data.smartcard = virDomainSmartcardDefParseXML(xmlopt, node, - flags))) + ctxt, flags))) goto error; break; case VIR_DOMAIN_DEVICE_MEMBALLOON: @@ -18600,6 +18678,7 @@ virDomainDefParseXML(xmlDocPtr xml, for (i = 0; i < n; i++) { virDomainSmartcardDefPtr card = virDomainSmartcardDefParseXML(xmlopt, nodes[i], + ctxt, flags); if (!card) goto error; @@ -18949,7 +19028,7 @@ virDomainDefParseXML(xmlDocPtr xml, goto error; for (i = 0; i < n; i++) { virDomainRedirdevDefPtr redirdev = - virDomainRedirdevDefParseXML(xmlopt, nodes[i], bootHash, flags); + virDomainRedirdevDefParseXML(xmlopt, nodes[i], ctxt, bootHash, flags); if (!redirdev) goto error; @@ -23070,6 +23149,24 @@ virDomainChrAttrsDefFormat(virBufferPtr buf, return 0; } + +static void +virDomainChrSourceReconnectDefFormat(virBufferPtr buf, + virDomainChrSourceReconnectDefPtr def) +{ + if (def->enabled == VIR_TRISTATE_BOOL_ABSENT) + return; + + virBufferAsprintf(buf, "<reconnect enabled='%s'", + virTristateBoolTypeToString(def->enabled)); + + if (def->enabled == VIR_TRISTATE_BOOL_YES) + virBufferAsprintf(buf, " timeout='%u'", def->timeout); + + virBufferAddLit(buf, "/>\n"); +} + + static int virDomainChrSourceDefFormat(virBufferPtr buf, virDomainChrSourceDefPtr def, @@ -23150,6 +23247,9 @@ virDomainChrSourceDefFormat(virBufferPtr buf, virBufferAsprintf(&attrBuf, " tlsFromConfig='%d'", def->data.tcp.tlsFromConfig); + virDomainChrSourceReconnectDefFormat(&childBuf, + &def->data.tcp.reconnect); + if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0) goto error; @@ -23166,6 +23266,9 @@ virDomainChrSourceDefFormat(virBufferPtr buf, virDomainSourceDefFormatSeclabel(&childBuf, def->nseclabels, def->seclabels, flags); + virDomainChrSourceReconnectDefFormat(&childBuf, + &def->data.nix.reconnect); + if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0) goto error; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index c3d6845032..e2d0bb1b50 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1137,6 +1137,15 @@ typedef enum { VIR_DOMAIN_CHR_SPICEVMC_LAST } virDomainChrSpicevmcName; + +struct _virDomainChrSourceReconnectDef { + virTristateBool enabled; + unsigned int timeout; +}; +typedef struct _virDomainChrSourceReconnectDef virDomainChrSourceReconnectDef; +typedef virDomainChrSourceReconnectDef *virDomainChrSourceReconnectDefPtr; + + /* The host side information for a character device. */ struct _virDomainChrSourceDef { int type; /* virDomainChrType */ @@ -1159,6 +1168,7 @@ struct _virDomainChrSourceDef { bool tlscreds; int haveTLS; /* enum virTristateBool */ bool tlsFromConfig; + virDomainChrSourceReconnectDef reconnect; } tcp; struct { char *bindHost; @@ -1169,6 +1179,7 @@ struct _virDomainChrSourceDef { struct { char *path; bool listen; + virDomainChrSourceReconnectDef reconnect; } nix; int spicevmc; struct { -- 2.13.5

On Mon, Aug 28, 2017 at 02:56:50PM +0200, Pavel Hrdina wrote:
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- docs/formatdomain.html.in | 11 ++++ docs/schemas/domaincommon.rng | 12 +++++ src/conf/domain_conf.c | 119 +++++++++++++++++++++++++++++++++++++++--- src/conf/domain_conf.h | 11 ++++ 4 files changed, 145 insertions(+), 8 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fba8cfc6f3..205122f28e 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -6298,6 +6298,17 @@ qemu-kvm -net nic,model=? /dev/null slot. </p>
+ <p> + For character device with type <code>unix</code> or <code>tcp</code> + the <code>source</code> has an optional element <code>reconnect</code> + which configures reconnect timeout if the connection is lost. + There are two attributes, <code>enabled</code> where possible + values are <code>yes</code> and <code>no</code> and <code>timeout</code>
Please put the possible values for 'enabled' attribute in parentheses to differentiate them from the attribute names.
+ which is in seconds. The <code>reconnect</code> attribute is valid only + for <code>connect</code> mode. + <span class="since">Since 3.7.0 (QEMU driver only)</span>. + </p> + <h5><a id="elementsCharGuestInterface">Guest interface</a></h5>
<p> @@ -11115,6 +11127,56 @@ virDomainChrDefParseTargetXML(virDomainChrDefPtr def, return ret; }
+static int +virDomainChrSourceReconnectDefParseXML(virDomainChrSourceReconnectDefPtr def, + xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + int ret = -1; + int tmpVal; + char *tmp = NULL; + xmlNodePtr saveNode = ctxt->node; + xmlNodePtr cur; + + ctxt->node = node; + + if ((cur = virXPathNode("./reconnect", ctxt))) { + if ((tmp = virXMLPropString(cur, "enabled"))) { + if ((tmpVal = virTristateBoolTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid reconnect enabled value: '%s'"), + tmp); + goto cleanup; + } + def->enabled = tmpVal; + VIR_FREE(tmp); + } + + if (def->enabled == VIR_TRISTATE_BOOL_YES) { + if ((tmp = virXMLPropString(cur, "timeout"))) { + if (virStrToLong_ui(tmp, NULL, 10, &def->timeout) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid reconnect enabled value: '%s'"),
s/enabled/timeout/ Jan
+ tmp); + goto cleanup; + } + VIR_FREE(tmp);

Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- .../generic-chardev-reconnect-invalid-mode.xml | 26 +++++++++++++++++ .../generic-chardev-reconnect-missing-timeout.xml | 26 +++++++++++++++++ .../generic-chardev-reconnect.xml | 32 +++++++++++++++++++++ .../generic-chardev-reconnect.xml | 33 ++++++++++++++++++++++ tests/genericxml2xmltest.c | 5 ++++ 5 files changed, 122 insertions(+) create mode 100644 tests/genericxml2xmlindata/generic-chardev-reconnect-invalid-mode.xml create mode 100644 tests/genericxml2xmlindata/generic-chardev-reconnect-missing-timeout.xml create mode 100644 tests/genericxml2xmlindata/generic-chardev-reconnect.xml create mode 100644 tests/genericxml2xmloutdata/generic-chardev-reconnect.xml diff --git a/tests/genericxml2xmlindata/generic-chardev-reconnect-invalid-mode.xml b/tests/genericxml2xmlindata/generic-chardev-reconnect-invalid-mode.xml new file mode 100644 index 0000000000..3fce6c4d37 --- /dev/null +++ b/tests/genericxml2xmlindata/generic-chardev-reconnect-invalid-mode.xml @@ -0,0 +1,26 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <controller type='virtio-serial' index='0'/> + <channel type='tcp'> + <source mode='bind' host='localhost' service='5678'> + <reconnect enabled='yes' timeout='10'/> + </source> + <target type='virtio' name='test1'/> + </channel> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/genericxml2xmlindata/generic-chardev-reconnect-missing-timeout.xml b/tests/genericxml2xmlindata/generic-chardev-reconnect-missing-timeout.xml new file mode 100644 index 0000000000..010dc6cc80 --- /dev/null +++ b/tests/genericxml2xmlindata/generic-chardev-reconnect-missing-timeout.xml @@ -0,0 +1,26 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <controller type='virtio-serial' index='0'/> + <channel type='tcp'> + <source mode='connect' host='localhost' service='5678'> + <reconnect enabled='yes'/> + </source> + <target type='virtio' name='test1'/> + </channel> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/genericxml2xmlindata/generic-chardev-reconnect.xml b/tests/genericxml2xmlindata/generic-chardev-reconnect.xml new file mode 100644 index 0000000000..1bd69ecc73 --- /dev/null +++ b/tests/genericxml2xmlindata/generic-chardev-reconnect.xml @@ -0,0 +1,32 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <controller type='virtio-serial' index='0'/> + <channel type='tcp'> + <source mode='connect' host='localhost' service='5678'> + <reconnect enabled='yes' timeout='10'/> + </source> + <target type='virtio' name='test1'/> + </channel> + <channel type='unix'> + <source mode='connect' path='/unix/socket/path'> + <reconnect enabled='no'/> + </source> + <target type='virtio' name='test2'/> + </channel> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/genericxml2xmloutdata/generic-chardev-reconnect.xml b/tests/genericxml2xmloutdata/generic-chardev-reconnect.xml new file mode 100644 index 0000000000..d0e2cd23da --- /dev/null +++ b/tests/genericxml2xmloutdata/generic-chardev-reconnect.xml @@ -0,0 +1,33 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <controller type='virtio-serial' index='0'/> + <channel type='tcp'> + <source mode='connect' host='localhost' service='5678'> + <reconnect enabled='yes' timeout='10'/> + </source> + <protocol type='raw'/> + <target type='virtio' name='test1'/> + </channel> + <channel type='unix'> + <source mode='connect' path='/unix/socket/path'> + <reconnect enabled='no'/> + </source> + <target type='virtio' name='test2'/> + </channel> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c index 03913a68c9..0377a05e9c 100644 --- a/tests/genericxml2xmltest.c +++ b/tests/genericxml2xmltest.c @@ -124,6 +124,11 @@ mymain(void) TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); DO_TEST_FULL("chardev-unix-rng-missing-path", 0, false, TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); + DO_TEST_DIFFERENT("chardev-reconnect"); + DO_TEST_FULL("chardev-reconnect-missing-timeout", 0, false, + TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); + DO_TEST_FULL("chardev-reconnect-invalid-mode", 0, false, + TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); virObjectUnref(caps); virObjectUnref(xmlopt); -- 2.13.5

The reconnect attribute for chardev devices in QEMU is used to configure the reconnect timeout in seconds. Setting '0' value disables the reconnect functionality thus we don't allow to set '0' for QEMU. To disable the reconnect user should use <reconnect enabled='no'/>. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1254971 Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- src/qemu/qemu_command.c | 17 ++++++++ src/qemu/qemu_domain.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a68ff717fd..53b79ac976 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5044,6 +5044,19 @@ qemuBuildChrChardevFileStr(virLogManagerPtr logManager, return 0; } + +static void +qemuBuildChrChardevReconnectStr(virBufferPtr buf, + const virDomainChrSourceReconnectDef *def) +{ + if (def->enabled == VIR_TRISTATE_BOOL_YES) { + virBufferAsprintf(buf, ",reconnect=%u", def->timeout); + } else if (def->enabled == VIR_TRISTATE_BOOL_NO) { + virBufferAddLit(buf, ",reconnect=0"); + } +} + + /* This function outputs a -chardev command line option which describes only the * host side of the character device */ static char * @@ -5142,6 +5155,8 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager, if (dev->data.tcp.listen) virBufferAdd(&buf, nowait ? ",server,nowait" : ",server", -1); + qemuBuildChrChardevReconnectStr(&buf, &dev->data.tcp.reconnect); + if (dev->data.tcp.haveTLS == VIR_TRISTATE_BOOL_YES) { qemuDomainChrSourcePrivatePtr chrSourcePriv = QEMU_DOMAIN_CHR_SOURCE_PRIVATE(dev); @@ -5175,6 +5190,8 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager, virQEMUBuildBufferEscapeComma(&buf, dev->data.nix.path); if (dev->data.nix.listen) virBufferAdd(&buf, nowait ? ",server,nowait" : ",server", -1); + + qemuBuildChrChardevReconnectStr(&buf, &dev->data.nix.reconnect); break; case VIR_DOMAIN_CHR_TYPE_SPICEVMC: diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 2c77a64424..05bf1c7d02 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3211,6 +3211,95 @@ qemuDomainNetSupportsCoalesce(virDomainNetType type) static int +qemuDomainChrSourceReconnectDefValidate(const virDomainChrSourceReconnectDef *def) +{ + if (def->enabled == VIR_TRISTATE_BOOL_YES && + def->timeout == 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("chardev reconnect source timeout cannot be '0'")); + return -1; + } + + return 0; +} + + +static int +qemuDomainChrSourceDefValidate(const virDomainChrSourceDef *def) +{ + switch ((virDomainChrType)def->type) { + case VIR_DOMAIN_CHR_TYPE_TCP: + if (qemuDomainChrSourceReconnectDefValidate(&def->data.tcp.reconnect) < 0) + return -1; + break; + + case VIR_DOMAIN_CHR_TYPE_UNIX: + if (qemuDomainChrSourceReconnectDefValidate(&def->data.nix.reconnect) < 0) + return -1; + break; + + case VIR_DOMAIN_CHR_TYPE_NULL: + case VIR_DOMAIN_CHR_TYPE_VC: + case VIR_DOMAIN_CHR_TYPE_PTY: + case VIR_DOMAIN_CHR_TYPE_DEV: + case VIR_DOMAIN_CHR_TYPE_FILE: + case VIR_DOMAIN_CHR_TYPE_PIPE: + case VIR_DOMAIN_CHR_TYPE_STDIO: + case VIR_DOMAIN_CHR_TYPE_UDP: + case VIR_DOMAIN_CHR_TYPE_SPICEVMC: + case VIR_DOMAIN_CHR_TYPE_SPICEPORT: + case VIR_DOMAIN_CHR_TYPE_NMDM: + case VIR_DOMAIN_CHR_TYPE_LAST: + break; + } + + return 0; +} + + +static int +qemuDomainChrDefValidate(const virDomainChrDef *def) +{ + if (qemuDomainChrSourceDefValidate(def->source) < 0) + return -1; + + return 0; +} + + +static int +qemuDomainSmartcardDefValidate(const virDomainSmartcardDef *def) +{ + if (def->type == VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH && + qemuDomainChrSourceDefValidate(def->data.passthru) < 0) + return -1; + + return 0; +} + + +static int +qemuDomainRNGDefValidate(const virDomainRNGDef *def) +{ + if (def->backend == VIR_DOMAIN_RNG_BACKEND_EGD && + qemuDomainChrSourceDefValidate(def->source.chardev) < 0) + return -1; + + return 0; +} + + +static int +qemuDomainRedirdevDefValidate(const virDomainRedirdevDef *def) +{ + if (qemuDomainChrSourceDefValidate(def->source) < 0) + return -1; + + return 0; +} + + +static int qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, const virDomainDef *def ATTRIBUTE_UNUSED, void *opaque) @@ -3257,6 +3346,18 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, virDomainNetTypeToString(net->type)); goto cleanup; } + } else if (dev->type == VIR_DOMAIN_DEVICE_CHR) { + if (qemuDomainChrDefValidate(dev->data.chr) < 0) + goto cleanup; + } else if (dev->type == VIR_DOMAIN_DEVICE_SMARTCARD) { + if (qemuDomainSmartcardDefValidate(dev->data.smartcard) < 0) + goto cleanup; + } else if (dev->type == VIR_DOMAIN_DEVICE_RNG) { + if (qemuDomainRNGDefValidate(dev->data.rng) < 0) + goto cleanup; + } else if (dev->type == VIR_DOMAIN_DEVICE_REDIRDEV) { + if (qemuDomainRedirdevDefValidate(dev->data.redirdev) < 0) + goto cleanup; } /* forbid capabilities mode hostdev in this kind of hypervisor */ -- 2.13.5

Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- .../qemuxml2argv-channel-reconnect.args | 31 +++++++++++++++ ...uxml2argv-chardev-reconnect-invalid-timeout.xml | 23 +++++++++++ .../qemuxml2argv-chardev-reconnect.args | 40 +++++++++++++++++++ .../qemuxml2argv-chardev-reconnect.xml | 46 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 11 ++++++ 5 files changed, 151 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect-invalid-timeout.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args new file mode 100644 index 0000000000..43a5d5bb3e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args @@ -0,0 +1,31 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefconfig \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-device virtio-serial-pci,id=virtio-serial1,bus=pci.0,addr=0xa \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x3 \ +-usb \ +-chardev socket,id=charchannel0,host=localhost,port=1234,reconnect=10 \ +-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\ +id=channel0,name=asdf \ +-chardev socket,id=charchannel1,path=/tmp/channel/domain--1-QEMUGuest1/fdsa,\ +server,nowait,reconnect=10 \ +-device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,\ +id=channel1,name=fdsa diff --git a/tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect-invalid-timeout.xml b/tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect-invalid-timeout.xml new file mode 100644 index 0000000000..73dac66816 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect-invalid-timeout.xml @@ -0,0 +1,23 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <controller type='virtio-serial' index='1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + </controller> + <channel type='tcp'> + <source host='localhost' service='1234'> + <reconnect enabled='yes' timeout='0'/> + </source> + <target type='virtio' name='asdf'/> + </channel> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.args b/tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.args new file mode 100644 index 0000000000..133a2c6039 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.args @@ -0,0 +1,40 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefconfig \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-device virtio-serial-pci,id=virtio-serial1,bus=pci.0,addr=0xa \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x3 \ +-device usb-ccid,id=ccid0,bus=usb.0,port=1 \ +-usb \ +-chardev socket,id=charsmartcard0,path=/tmp/channel/domain-oldname/asdf,\ +reconnect=20 \ +-device ccid-card-passthru,chardev=charsmartcard0,id=smartcard0,bus=ccid0.0 \ +-chardev socket,id=charchannel0,host=localhost,port=1234,reconnect=10 \ +-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\ +id=channel0,name=asdf \ +-chardev socket,id=charchannel1,path=/tmp/channel/domain--1-QEMUGuest1/fdsa,\ +server,nowait,reconnect=0 \ +-device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,\ +id=channel1,name=fdsa \ +-chardev socket,id=charredir0,host=localhost,port=3456,reconnect=15 \ +-device usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 \ +-chardev socket,id=charrng0,host=localhost,port=2345,reconnect=5 \ +-object rng-egd,id=objrng0,chardev=charrng0 \ +-device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.xml b/tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.xml new file mode 100644 index 0000000000..e0664b2a95 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.xml @@ -0,0 +1,46 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <controller type='virtio-serial' index='1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + </controller> + <redirdev bus='usb' type='tcp'> + <source mode='connect' host='localhost' service='3456'> + <reconnect enabled='yes' timeout='15'/> + </source> + </redirdev> + <smartcard mode='passthrough' type='unix'> + <source mode='connect' path='/tmp/channel/domain-oldname/asdf'> + <reconnect enabled='yes' timeout='20'/> + </source> + </smartcard> + <channel type='tcp'> + <source mode='connect' host='localhost' service='1234'> + <reconnect enabled='yes' timeout='10'/> + </source> + <target type='virtio' name='asdf'/> + </channel> + <channel type='unix'> + <source mode='connect' path='/tmp/channel/domain-oldname/fdsa'> + <reconnect enabled='no'/> + </source> + <target type='virtio' name='fdsa'/> + </channel> + <memballoon model='none'/> + <rng model='virtio'> + <backend model='egd' type='tcp'> + <source mode='connect' host='localhost' service='2345'> + <reconnect enabled='yes' timeout='5'/> + </source> + </backend> + </rng> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 5cdbc78eb8..39f8d66c04 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1341,6 +1341,17 @@ mymain(void) QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_CCID_EMULATED); + DO_TEST("chardev-reconnect", + QEMU_CAPS_NODEFCONFIG, + QEMU_CAPS_CHARDEV_RECONNECT, + QEMU_CAPS_USB_REDIR, + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_EGD, + QEMU_CAPS_CCID_PASSTHRU); + DO_TEST_PARSE_ERROR("chardev-reconnect-invalid-timeout", + QEMU_CAPS_NODEFCONFIG, + QEMU_CAPS_CHARDEV_RECONNECT); + DO_TEST("usb-controller", QEMU_CAPS_NODEFCONFIG); DO_TEST("usb-piix3-controller", -- 2.13.5

s/srouce/source/ Jan

On 08/28/2017 02:56 PM, Pavel Hrdina wrote:
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- .../qemuxml2argv-channel-reconnect.args | 31 +++++++++++++++ ...uxml2argv-chardev-reconnect-invalid-timeout.xml | 23 +++++++++++ .../qemuxml2argv-chardev-reconnect.args | 40 +++++++++++++++++++ .../qemuxml2argv-chardev-reconnect.xml | 46 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 11 ++++++ 5 files changed, 151 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect-invalid-timeout.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.xml
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args new file mode 100644 index 0000000000..43a5d5bb3e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args @@ -0,0 +1,31 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefconfig \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-device virtio-serial-pci,id=virtio-serial1,bus=pci.0,addr=0xa \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x3 \ +-usb \ +-chardev socket,id=charchannel0,host=localhost,port=1234,reconnect=10 \ +-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\ +id=channel0,name=asdf \ +-chardev socket,id=charchannel1,path=/tmp/channel/domain--1-QEMUGuest1/fdsa,\ +server,nowait,reconnect=10 \
This doesn't look right. How come a server can have reconnect at the same time? Michal

On Tue, Aug 29, 2017 at 11:17:13AM +0200, Michal Privoznik wrote:
On 08/28/2017 02:56 PM, Pavel Hrdina wrote:
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- .../qemuxml2argv-channel-reconnect.args | 31 +++++++++++++++ ...uxml2argv-chardev-reconnect-invalid-timeout.xml | 23 +++++++++++ .../qemuxml2argv-chardev-reconnect.args | 40 +++++++++++++++++++ .../qemuxml2argv-chardev-reconnect.xml | 46 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 11 ++++++ 5 files changed, 151 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect-invalid-timeout.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.xml
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args new file mode 100644 index 0000000000..43a5d5bb3e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args @@ -0,0 +1,31 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefconfig \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-device virtio-serial-pci,id=virtio-serial1,bus=pci.0,addr=0xa \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x3 \ +-usb \ +-chardev socket,id=charchannel0,host=localhost,port=1234,reconnect=10 \ +-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\ +id=channel0,name=asdf \ +-chardev socket,id=charchannel1,path=/tmp/channel/domain--1-QEMUGuest1/fdsa,\ +server,nowait,reconnect=10 \
This doesn't look right. How come a server can have reconnect at the same time?
Yes, that is strange. If you look at the XML the mode is connect so there is something else going on. I'll investigate the issue. Also I've noticed that one file [1] shouldn't be included in that patch. I'll send a followup to clean that file. Pavel [1] <tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args>

On Tue, Aug 29, 2017 at 11:17:13AM +0200, Michal Privoznik wrote:
On 08/28/2017 02:56 PM, Pavel Hrdina wrote:
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- .../qemuxml2argv-channel-reconnect.args | 31 +++++++++++++++ ...uxml2argv-chardev-reconnect-invalid-timeout.xml | 23 +++++++++++ .../qemuxml2argv-chardev-reconnect.args | 40 +++++++++++++++++++ .../qemuxml2argv-chardev-reconnect.xml | 46 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 11 ++++++ 5 files changed, 151 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect-invalid-timeout.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.xml
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args new file mode 100644 index 0000000000..43a5d5bb3e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args @@ -0,0 +1,31 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefconfig \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-device virtio-serial-pci,id=virtio-serial1,bus=pci.0,addr=0xa \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x3 \ +-usb \ +-chardev socket,id=charchannel0,host=localhost,port=1234,reconnect=10 \ +-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\ +id=channel0,name=asdf \ +-chardev socket,id=charchannel1,path=/tmp/channel/domain--1-QEMUGuest1/fdsa,\ +server,nowait,reconnect=10 \
This doesn't look right. How come a server can have reconnect at the same time?
So there are two issues with our code: 1. We successfully parse this configuration: ... <channel type='unix'> <source mode='connect'/> <target type='virtio' name='test'/> </channel> ... While formatting the XML we ignore the source element if there is no path and the code starting a domain generates a new path and set's the mode to 'bind'. With the reconnect patches if we parse the reconnect it's unconditionally put to the command line if it was parsed even though the mode was changed. 2. This test uses a path that matches a pattern of automatically generated paths by libvirt: ... <source mode='connect' path='/tmp/channel/domain-oldname/fdsa'> <reconnect enabled='no'/> </source> ... and our code removes that path in order to get it automatically generated following new rules and also changes the mode to "bind" and that leads to the same issue as for the first example. I'll send a patches to fix it. Pavel

On Mon, Aug 28, 2017 at 02:56:48PM +0200, Pavel Hrdina wrote:
Pavel Hrdina (5): qemu: introduce QEMU_CAPS_CHARDEV_RECONNECT conf: introduce reconnect element for chardev source tests: add generic xml chardev reconnect tests qemu: implement chardev source reconnect tests: add qemu chardev srouce reconnect tests
docs/formatdomain.html.in | 11 ++ docs/schemas/domaincommon.rng | 12 +++ src/conf/domain_conf.c | 119 +++++++++++++++++++-- src/conf/domain_conf.h | 11 ++ src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 17 +++ src/qemu/qemu_domain.c | 101 +++++++++++++++++ .../generic-chardev-reconnect-invalid-mode.xml | 26 +++++ .../generic-chardev-reconnect-missing-timeout.xml | 26 +++++ .../generic-chardev-reconnect.xml | 32 ++++++ .../generic-chardev-reconnect.xml | 33 ++++++ tests/genericxml2xmltest.c | 5 + tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 1 + .../caps_2.6.0-gicv2.aarch64.xml | 1 + .../caps_2.6.0-gicv3.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 1 + .../qemuxml2argv-channel-reconnect.args | 31 ++++++ ...uxml2argv-chardev-reconnect-invalid-timeout.xml | 23 ++++ .../qemuxml2argv-chardev-reconnect.args | 40 +++++++ .../qemuxml2argv-chardev-reconnect.xml | 46 ++++++++ tests/qemuxml2argvtest.c | 11 ++ 31 files changed, 552 insertions(+), 8 deletions(-) create mode 100644 tests/genericxml2xmlindata/generic-chardev-reconnect-invalid-mode.xml create mode 100644 tests/genericxml2xmlindata/generic-chardev-reconnect-missing-timeout.xml create mode 100644 tests/genericxml2xmlindata/generic-chardev-reconnect.xml create mode 100644 tests/genericxml2xmloutdata/generic-chardev-reconnect.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect-invalid-timeout.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-chardev-reconnect.xml
ACK series Jan
participants (3)
-
Ján Tomko
-
Michal Privoznik
-
Pavel Hrdina