[libvirt] [PATCH 2/5] conf: introduce reconnect element for chardev source

Pavel Hrdina phrdina at redhat.com
Mon Aug 28 12:56:50 UTC 2017


Signed-off-by: Pavel Hrdina <phrdina at 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




More information about the libvir-list mailing list