Changeset
docs/schemas/domaincommon.rng                      | 26 ++++++++------
src/conf/domain_conf.c                             | 40 ++++++++++++++++++----
src/conf/domain_conf.h                             | 10 +++---
src/qemu/qemu_command.c                            |  2 +-
src/qemu/qemu_domain.c                             |  2 +-
src/qemu/qemu_monitor_json.c                       |  2 +-
.../qemuxml2argv-net-vhostuser-multiq.args         |  4 +--
.../qemuxml2argv-net-vhostuser-multiq.xml          |  8 +++--
8 files changed, 65 insertions(+), 29 deletions(-)
Git apply log
Switched to a new branch '1507508371-11188-1-git-send-email-lu.zhipeng@zte.com.cn'
Applying: vhost-user: add support reconnect for vhost-user ports
To https://github.com/patchew-project/libvirt
 * [new tag]             patchew/1507508371-11188-1-git-send-email-lu.zhipeng@zte.com.cn -> patchew/1507508371-11188-1-git-send-email-lu.zhipeng@zte.com.cn
[libvirt] [PATCH v3 RESEND] vhost-user: add support reconnect for vhost-user ports
Posted by ZhiPeng Lu, 1 week ago
For vhost-user ports, Open vSwitch acts as the server and QEMU the client.
When OVS crashes or restarts, the QEMU process should be reconnected to
OVS.

Signed-off-by: ZhiPeng Lu <lu.zhipeng@zte.com.cn>
---
 docs/schemas/domaincommon.rng                      | 26 ++++++++------
 src/conf/domain_conf.c                             | 40 ++++++++++++++++++----
 src/conf/domain_conf.h                             | 10 +++---
 src/qemu/qemu_command.c                            |  2 +-
 src/qemu/qemu_domain.c                             |  2 +-
 src/qemu/qemu_monitor_json.c                       |  2 +-
 .../qemuxml2argv-net-vhostuser-multiq.args         |  4 +--
 .../qemuxml2argv-net-vhostuser-multiq.xml          |  8 +++--
 8 files changed, 65 insertions(+), 29 deletions(-)

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 76852ab..3f4ed82 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2327,6 +2327,18 @@
       </attribute>
     </optional>
   </define>
+  <define name="reconnect">
+    <element name="reconnect">
+      <attribute name="enabled">
+        <ref name="virYesNo"/>
+      </attribute>
+      <optional>
+        <attribute name="timeout">
+          <ref name="unsignedInt"/>
+        </attribute>
+      </optional>
+    </element>
+  </define>
 
   <!--
       An interface description can either be of type bridge in which case
@@ -2388,6 +2400,9 @@
                   <value>client</value>
                 </choice>
               </attribute>
+              <optional>
+                 <ref name="reconnect"/>
+              </optional>
               <empty/>
             </element>
             <ref name="interface-options"/>
@@ -3636,16 +3651,7 @@
           </attribute>
         </optional>
         <optional>
-          <element name="reconnect">
-            <attribute name="enabled">
-              <ref name="virYesNo"/>
-            </attribute>
-            <optional>
-              <attribute name="timeout">
-                <ref name="unsignedInt"/>
-              </attribute>
-            </optional>
-          </element>
+          <ref name="reconnect"/>
         </optional>
         <zeroOrMore>
           <ref name='devSeclabel'/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cc5e79b..b7fc3a5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -83,6 +83,13 @@ struct _virDomainXMLOption {
     /* Private data for save image stored in snapshot XML */
     virSaveCookieCallbacks saveCookie;
 };
+static int
+virDomainDeviceSourceReconnectDefParseXML(virDomainDeviceSourceReconnectDefPtr def,
+                                       xmlNodePtr node,
+                                       xmlXPathContextPtr ctxt);
+static void
+virDomainDeviceSourceReconnectDefFormat(virBufferPtr buf,
+                                     virDomainDeviceSourceReconnectDefPtr def);
 
 #define VIR_DOMAIN_DEF_FORMAT_COMMON_FLAGS             \
     (VIR_DOMAIN_DEF_FORMAT_SECURE |                    \
@@ -10245,6 +10252,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     virNWFilterHashTablePtr filterparams = NULL;
     virDomainActualNetDefPtr actual = NULL;
     xmlNodePtr oldnode = ctxt->node;
+    virDomainDeviceSourceReconnectDef reconnect = {0};
     int rv, val;
 
     if (VIR_ALLOC(def) < 0)
@@ -10331,6 +10339,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
                 vhostuser_type = virXMLPropString(cur, "type");
                 vhostuser_path = virXMLPropString(cur, "path");
                 vhostuser_mode = virXMLPropString(cur, "mode");
+                if (virDomainDeviceSourceReconnectDefParseXML(&reconnect, cur, ctxt) < 0)
+                    goto error;
             } else if (!def->virtPortProfile
                        && virXMLNodeNameEqual(cur, "virtualport")) {
                 if (def->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
@@ -10552,8 +10562,17 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
 
         if (STREQ(vhostuser_mode, "server")) {
             def->data.vhostuser->data.nix.listen = true;
+            if (reconnect.enabled != VIR_TRISTATE_BOOL_ABSENT) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("'reconnect' attribute  unsupported "
+                                 "'server' mode for <interface type='vhostuser'>"));
+                goto error;
+           }
         } else if (STREQ(vhostuser_mode, "client")) {
             def->data.vhostuser->data.nix.listen = false;
+            def->data.vhostuser->data.nix.reconnect.enabled = reconnect.enabled;
+            def->data.vhostuser->data.nix.reconnect.timeout = reconnect.timeout;
+            reconnect.enabled = VIR_TRISTATE_BOOL_ABSENT;
         } else {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("Wrong <source> 'mode' attribute "
@@ -11216,7 +11235,7 @@ virDomainChrDefParseTargetXML(virDomainChrDefPtr def,
 }
 
 static int
-virDomainChrSourceReconnectDefParseXML(virDomainChrSourceReconnectDefPtr def,
+virDomainDeviceSourceReconnectDefParseXML(virDomainDeviceSourceReconnectDefPtr def,
                                        xmlNodePtr node,
                                        xmlXPathContextPtr ctxt)
 {
@@ -11338,7 +11357,7 @@ virDomainChrSourceDefParseTCP(virDomainChrSourceDefPtr def,
         VIR_FREE(tmp);
     }
 
-    if (virDomainChrSourceReconnectDefParseXML(&def->data.tcp.reconnect,
+    if (virDomainDeviceSourceReconnectDefParseXML(&def->data.tcp.reconnect,
                                                source,
                                                ctxt) < 0) {
         goto error;
@@ -11389,7 +11408,7 @@ 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,
+    if (virDomainDeviceSourceReconnectDefParseXML(&def->data.nix.reconnect,
                                                source,
                                                ctxt) < 0) {
         return -1;
@@ -22984,6 +23003,13 @@ virDomainNetDefFormat(virBufferPtr buf,
                                   def->data.vhostuser->data.nix.listen ?
                                   "server"  : "client");
                 sourceLines++;
+                if (def->data.vhostuser->data.nix.reconnect.enabled != VIR_TRISTATE_BOOL_ABSENT) {
+                    virBufferAddLit(buf, ">\n");
+                    sourceLines++;
+                    virBufferAdjustIndent(buf, 2);
+                    virDomainDeviceSourceReconnectDefFormat(buf, &def->data.vhostuser->data.nix.reconnect);
+                    virBufferAdjustIndent(buf, -2);
+                }
             }
             break;
 
@@ -23218,8 +23244,8 @@ virDomainChrAttrsDefFormat(virBufferPtr buf,
 
 
 static void
-virDomainChrSourceReconnectDefFormat(virBufferPtr buf,
-                                     virDomainChrSourceReconnectDefPtr def)
+virDomainDeviceSourceReconnectDefFormat(virBufferPtr buf,
+                                     virDomainDeviceSourceReconnectDefPtr def)
 {
     if (def->enabled == VIR_TRISTATE_BOOL_ABSENT)
         return;
@@ -23314,7 +23340,7 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
             virBufferAsprintf(&attrBuf, " tlsFromConfig='%d'",
                               def->data.tcp.tlsFromConfig);
 
-        virDomainChrSourceReconnectDefFormat(&childBuf,
+        virDomainDeviceSourceReconnectDefFormat(&childBuf,
                                              &def->data.tcp.reconnect);
 
         if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
@@ -23333,7 +23359,7 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
             virDomainSourceDefFormatSeclabel(&childBuf, def->nseclabels,
                                              def->seclabels, flags);
 
-            virDomainChrSourceReconnectDefFormat(&childBuf,
+            virDomainDeviceSourceReconnectDefFormat(&childBuf,
                                                  &def->data.nix.reconnect);
 
             if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bb3b6f0..909f60d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1138,12 +1138,12 @@ typedef enum {
 } virDomainChrSpicevmcName;
 
 
-struct _virDomainChrSourceReconnectDef {
+struct _virDomainDeviceSourceReconnectDef {
     virTristateBool enabled;
     unsigned int timeout;
 };
-typedef struct _virDomainChrSourceReconnectDef virDomainChrSourceReconnectDef;
-typedef virDomainChrSourceReconnectDef *virDomainChrSourceReconnectDefPtr;
+typedef struct _virDomainDeviceSourceReconnectDef virDomainDeviceSourceReconnectDef;
+typedef virDomainDeviceSourceReconnectDef *virDomainDeviceSourceReconnectDefPtr;
 
 
 /* The host side information for a character device.  */
@@ -1168,7 +1168,7 @@ struct _virDomainChrSourceDef {
             bool tlscreds;
             int haveTLS; /* enum virTristateBool */
             bool tlsFromConfig;
-            virDomainChrSourceReconnectDef reconnect;
+            virDomainDeviceSourceReconnectDef reconnect;
         } tcp;
         struct {
             char *bindHost;
@@ -1179,7 +1179,7 @@ struct _virDomainChrSourceDef {
         struct {
             char *path;
             bool listen;
-            virDomainChrSourceReconnectDef reconnect;
+            virDomainDeviceSourceReconnectDef reconnect;
         } nix;
         int spicevmc;
         struct {
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9b3e3fc..4640ce8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5094,7 +5094,7 @@ qemuBuildChrChardevFileStr(virLogManagerPtr logManager,
 
 static void
 qemuBuildChrChardevReconnectStr(virBufferPtr buf,
-                                const virDomainChrSourceReconnectDef *def)
+                                const virDomainDeviceSourceReconnectDef *def)
 {
     if (def->enabled == VIR_TRISTATE_BOOL_YES) {
         virBufferAsprintf(buf, ",reconnect=%u", def->timeout);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 50b536e..4ea0727 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3244,7 +3244,7 @@ qemuDomainNetSupportsCoalesce(virDomainNetType type)
 
 
 static int
-qemuDomainChrSourceReconnectDefValidate(const virDomainChrSourceReconnectDef *def)
+qemuDomainChrSourceReconnectDefValidate(const virDomainDeviceSourceReconnectDef *def)
 {
     if (def->enabled == VIR_TRISTATE_BOOL_YES &&
         def->timeout == 0) {
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 63b8559..b3d572e 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6443,7 +6443,7 @@ int qemuMonitorJSONGetTPMTypes(qemuMonitorPtr mon,
 
 static int
 qemuMonitorJSONBuildChrChardevReconnect(virJSONValuePtr object,
-                                        const virDomainChrSourceReconnectDef *def)
+                                        const virDomainDeviceSourceReconnectDef *def)
 {
     if (def->enabled != VIR_TRISTATE_BOOL_YES)
         return 0;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
index b69ebd8..0b08f44 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
@@ -25,14 +25,14 @@ server,nowait \
 -netdev vhost-user,chardev=charnet0,id=hostnet0 \
 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:ee:96:6b,bus=pci.0,\
 addr=0x3 \
--chardev socket,id=charnet1,path=/tmp/vhost1.sock \
+-chardev socket,id=charnet1,path=/tmp/vhost1.sock,reconnect=10 \
 -netdev vhost-user,chardev=charnet1,id=hostnet1 \
 -device virtio-net-pci,netdev=hostnet1,id=net1,mac=52:54:00:ee:96:6c,bus=pci.0,\
 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=0 \
 -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..2fadb1c 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
@@ -30,7 +30,9 @@
     </interface>
     <interface type='vhostuser'>
       <mac address='52:54:00:ee:96:6c'/>
-      <source type='unix' path='/tmp/vhost1.sock' mode='client'/>
+      <source type='unix' path='/tmp/vhost1.sock' mode='client'>
+        <reconnect enabled='yes' timeout='10'/>
+      </source>
       <model type='virtio'/>
     </interface>
     <interface type='server'>
@@ -40,7 +42,9 @@
     </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 enabled='no'/>
+      </source>
       <model type='virtio'/>
       <driver queues='4'/>
     </interface>
-- 
1.8.3.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list