]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: implement chardev source reconnect
authorPavel Hrdina <phrdina@redhat.com>
Fri, 25 Aug 2017 16:57:15 +0000 (18:57 +0200)
committerPavel Hrdina <phrdina@redhat.com>
Tue, 29 Aug 2017 08:30:05 +0000 (10:30 +0200)
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
src/qemu/qemu_domain.c

index a68ff717fdcc7e00f44bbc7e28b3722be7ac2453..53b79ac9763cb8aa980dd204b1bac6bf6341a91e 100644 (file)
@@ -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:
index 2c77a6442467d80a7ae9925e51fc79d22eced885..05bf1c7d0250bd4da3e364365e4dd1bd80a72efe 100644 (file)
@@ -3210,6 +3210,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,
@@ -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 */