[libvirt] [PATCH] vhost-user: add support reconnect for vhost-user ports

ZhiPeng Lu lu.zhipeng at zte.com.cn
Fri Sep 8 09:12:09 UTC 2017


For vhost-user ports, Open vSwitch acts as the server and QEMU the client.
When OVS crashed or restart, QEMU shoule be reconnect to OVS.

Signed-off-by: ZhiPeng Lu <lu.zhipeng at zte.com.cn>
---
 docs/formatdomain.html.in                          |  6 +++--
 docs/schemas/domaincommon.rng                      |  5 ++++
 src/conf/domain_conf.c                             | 28 ++++++++++++++++++++--
 .../qemuxml2argv-net-vhostuser-multiq.args         |  2 +-
 .../qemuxml2argv-net-vhostuser-multiq.xml          |  2 +-
 5 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 8ca7637..ffe45c2 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -5660,7 +5660,7 @@ qemu-kvm -net nic,model=? /dev/null
   </interface>
   <interface type='vhostuser'>
     <mac address='52:54:00:3b:83:1b'/>
-    <source type='unix' path='/tmp/vhost2.sock' mode='client'/>
+    <source type='unix' path='/tmp/vhost2.sock' mode='client' reconnect='10'/>
     <model type='virtio'/>
     <driver queues='5'/>
   </interface>
@@ -5675,7 +5675,9 @@ qemu-kvm -net nic,model=? /dev/null
       Both <code>mode='server'</code> and <code>mode='client'</code>
       are supported.
       vhost-user requires the virtio model type, thus the
-      <code><model></code> element is mandatory.
+      <code><model></code> element is mandatory. <code>reconnect</code>
+      is an optional element,which configures reconnect timeout if the
+      connection is lost.
     </p>
 
     <h5><a id="elementNwfilter">Traffic filtering with NWFilter</a></h5>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 06c5a91..82f30ae 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2383,6 +2383,11 @@
                     <value>client</value>
                   </choice>
                 </attribute>
+                <optional>
+                  <attribute name="reconnect">
+                    <ref name='positiveInteger'/>
+                  </attribute>
+                </optional>
                 <empty/>
               </element>
             <ref name="interface-options"/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2fc1fc3..f9c3b35 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -10176,6 +10176,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     char *vhostuser_mode = NULL;
     char *vhostuser_path = NULL;
     char *vhostuser_type = NULL;
+    char *vhostuser_reconnect = NULL;
     char *trustGuestRxFilters = NULL;
     char *vhost_path = NULL;
     virNWFilterHashTablePtr filterparams = NULL;
@@ -10262,11 +10263,12 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
                     goto error;
                 }
             } else if (!vhostuser_path && !vhostuser_mode && !vhostuser_type
-                       && def->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER &&
-                       virXMLNodeNameEqual(cur, "source")) {
+                       && !vhostuser_reconnect && def->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER
+                       && virXMLNodeNameEqual(cur, "source")) {
                 vhostuser_type = virXMLPropString(cur, "type");
                 vhostuser_path = virXMLPropString(cur, "path");
                 vhostuser_mode = virXMLPropString(cur, "mode");
+                vhostuser_reconnect = virXMLPropString(cur, "reconnect");
             } else if (!def->virtPortProfile
                        && virXMLNodeNameEqual(cur, "virtualport")) {
                 if (def->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
@@ -10478,6 +10480,11 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
                              "type='vhostuser'/>"));
             goto error;
         }
+        if (vhostuser_reconnect != NULL && STREQ(vhostuser_mode, "server")) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("'reconnect' attribute  unsupported "
+                                 "'server' mode for <interface type='vhostuser'>"));
+        }
 
         if (VIR_ALLOC(def->data.vhostuser) < 0)
             goto error;
@@ -10490,6 +10497,17 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
             def->data.vhostuser->data.nix.listen = true;
         } else if (STREQ(vhostuser_mode, "client")) {
             def->data.vhostuser->data.nix.listen = false;
+            if (vhostuser_reconnect != NULL) {
+                def->data.vhostuser->data.nix.reconnect.enabled = true;
+                if (virStrToLong_ui(vhostuser_reconnect, NULL, 0,
+                                   &def->data.vhostuser->data.nix.reconnect.timeout) < 0) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                 _("vhost-user reconnect attribute is invalid"));
+                    vhostuser_reconnect = NULL;
+                    def->data.vhostuser->data.nix.reconnect.enabled = false;
+                    goto error;
+                }
+            }
         } else {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("Wrong <source> 'mode' attribute "
@@ -10937,6 +10955,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     VIR_FREE(vhostuser_type);
     VIR_FREE(vhostuser_path);
     VIR_FREE(vhostuser_mode);
+    VIR_FREE(vhostuser_reconnect);
     VIR_FREE(ifname);
     VIR_FREE(ifname_guest);
     VIR_FREE(ifname_guest_actual);
@@ -22928,6 +22947,11 @@ virDomainNetDefFormat(virBufferPtr buf,
                 virBufferAsprintf(buf, " mode='%s'",
                                   def->data.vhostuser->data.nix.listen ?
                                   "server"  : "client");
+                if (def->data.vhostuser->data.nix.reconnect.enabled == true) {
+                    virBufferAsprintf(buf, " reconnect='%u'",
+                                      def->data.vhostuser->data.nix.reconnect.timeout);
+                }
+
                 sourceLines++;
             }
             break;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
index b69ebd8..996828f 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
@@ -32,7 +32,7 @@ addr=0x4 \
 -netdev socket,listen=:2015,id=hostnet2 \
 -device rtl8139,netdev=hostnet2,id=net2,mac=52:54:00:95:db:c0,bus=pci.0,\
 addr=0x5 \
--chardev socket,id=charnet3,path=/tmp/vhost2.sock \
+-chardev socket,id=charnet3,path=/tmp/vhost2.sock,reconnect=10 \
 -netdev vhost-user,chardev=charnet3,queues=4,id=hostnet3 \
 -device virtio-net-pci,mq=on,vectors=10,netdev=hostnet3,id=net3,\
 mac=52:54:00:ee:96:6d,bus=pci.0,addr=0x6
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
index d5c42fe..7eb6fa0 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
@@ -40,7 +40,7 @@
     </interface>
     <interface type='vhostuser'>
       <mac address='52:54:00:ee:96:6d'/>
-      <source type='unix' path='/tmp/vhost2.sock' mode='client'/>
+      <source type='unix' path='/tmp/vhost2.sock' mode='client' reconnect='10'/>
       <model type='virtio'/>
       <driver queues='4'/>
     </interface>
-- 
1.8.3.1




More information about the libvir-list mailing list