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

ZhiPeng Lu posted 1 patch 6 years, 7 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/1504861929-7975-1-git-send-email-lu.zhipeng@zte.com.cn
There is a newer version of this series
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(-)
[libvirt] [PATCH] vhost-user: add support reconnect for vhost-user ports
Posted by ZhiPeng Lu 6 years, 7 months ago
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@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
   &lt;/interface&gt;
   &lt;interface type='vhostuser'&gt;
     &lt;mac address='52:54:00:3b:83:1b'/&gt;
-    &lt;source type='unix' path='/tmp/vhost2.sock' mode='client'/&gt;
+    &lt;source type='unix' path='/tmp/vhost2.sock' mode='client' reconnect='10'/&gt;
     &lt;model type='virtio'/&gt;
     &lt;driver queues='5'/&gt;
   &lt;/interface&gt;
@@ -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>&lt;model&gt;</code> element is mandatory.
+      <code>&lt;model&gt;</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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] vhost-user: add support reconnect for vhost-user ports
Posted by Michal Privoznik 6 years, 7 months ago
On 09/08/2017 11:12 AM, ZhiPeng Lu wrote:
> 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@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
>    &lt;/interface&gt;
>    &lt;interface type='vhostuser'&gt;
>      &lt;mac address='52:54:00:3b:83:1b'/&gt;
> -    &lt;source type='unix' path='/tmp/vhost2.sock' mode='client'/&gt;
> +    &lt;source type='unix' path='/tmp/vhost2.sock' mode='client' reconnect='10'/&gt;
>      &lt;model type='virtio'/&gt;
>      &lt;driver queues='5'/&gt;
>    &lt;/interface&gt;
> @@ -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>&lt;model&gt;</code> element is mandatory.
> +      <code>&lt;model&gt;</code> element is mandatory. <code>reconnect</code>
> +      is an optional element,which configures reconnect timeout if the
> +      connection is lost.

This is missing "Since 3.7.0".

>      </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'>"));
> +        }

This can be checked later, when we validate vhostuser_mode.

>  
>          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;

There are two problems with this. Setting vhostuser_reconnect to NULL
leaks it when the control jumps to the error label. Secondly, there's no
need to set reconnect.enabled to false. Oh, yes and we know what base
the reconnect number is in. Therefore s/0/10/. I guess we don't want to
allow:

  reconnect="0x50"

I've fixed all these problems, ACKed and pushed.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] vhost-user: add support reconnect for vhost-user ports
Posted by Pavel Hrdina 6 years, 7 months ago
On Wed, Sep 20, 2017 at 03:15:23PM +0200, Michal Privoznik wrote:
> On 09/08/2017 11:12 AM, ZhiPeng Lu wrote:
> > 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@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
> >    &lt;/interface&gt;
> >    &lt;interface type='vhostuser'&gt;
> >      &lt;mac address='52:54:00:3b:83:1b'/&gt;
> > -    &lt;source type='unix' path='/tmp/vhost2.sock' mode='client'/&gt;
> > +    &lt;source type='unix' path='/tmp/vhost2.sock' mode='client' reconnect='10'/&gt;
> >      &lt;model type='virtio'/&gt;
> >      &lt;driver queues='5'/&gt;
> >    &lt;/interface&gt;
> > @@ -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>&lt;model&gt;</code> element is mandatory.
> > +      <code>&lt;model&gt;</code> element is mandatory. <code>reconnect</code>
> > +      is an optional element,which configures reconnect timeout if the
> > +      connection is lost.
> 
> This is missing "Since 3.7.0".
> 
> >      </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'>"));
> > +        }
> 
> This can be checked later, when we validate vhostuser_mode.
> 
> >  
> >          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;
> 
> There are two problems with this. Setting vhostuser_reconnect to NULL
> leaks it when the control jumps to the error label. Secondly, there's no
> need to set reconnect.enabled to false. Oh, yes and we know what base
> the reconnect number is in. Therefore s/0/10/. I guess we don't want to
> allow:
> 
>   reconnect="0x50"
> 
> I've fixed all these problems, ACKed and pushed.

Sigh, I was planning to reply to this patch that we should model the XML
the same way as the reconnect element for chardev devices [1].  Now I
see that the documentation misses an example.  Anyway this should be the
correct XML:

<source type='unix' path='/tmp/vhost2.sock' mode='client'>
  <reconnect enabled='yes' timeout='10'/>
</source>

We should revert this commit and implement it the same way as for
chardev devices.

Using the existing structure should have been a hint that some device
already uses it.

[1] <http://libvirt.org/formatdomain.html#elementsConsole>

Pavel
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] vhost-user: add support reconnect for vhost-user ports
Posted by Michal Privoznik 6 years, 7 months ago
On 09/20/2017 03:59 PM, Pavel Hrdina wrote:
> On Wed, Sep 20, 2017 at 03:15:23PM +0200, Michal Privoznik wrote:
>> On 09/08/2017 11:12 AM, ZhiPeng Lu wrote:
>>> 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@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
>>>    &lt;/interface&gt;
>>>    &lt;interface type='vhostuser'&gt;
>>>      &lt;mac address='52:54:00:3b:83:1b'/&gt;
>>> -    &lt;source type='unix' path='/tmp/vhost2.sock' mode='client'/&gt;
>>> +    &lt;source type='unix' path='/tmp/vhost2.sock' mode='client' reconnect='10'/&gt;
>>>      &lt;model type='virtio'/&gt;
>>>      &lt;driver queues='5'/&gt;
>>>    &lt;/interface&gt;
>>> @@ -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>&lt;model&gt;</code> element is mandatory.
>>> +      <code>&lt;model&gt;</code> element is mandatory. <code>reconnect</code>
>>> +      is an optional element,which configures reconnect timeout if the
>>> +      connection is lost.
>>
>> This is missing "Since 3.7.0".
>>
>>>      </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'>"));
>>> +        }
>>
>> This can be checked later, when we validate vhostuser_mode.
>>
>>>  
>>>          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;
>>
>> There are two problems with this. Setting vhostuser_reconnect to NULL
>> leaks it when the control jumps to the error label. Secondly, there's no
>> need to set reconnect.enabled to false. Oh, yes and we know what base
>> the reconnect number is in. Therefore s/0/10/. I guess we don't want to
>> allow:
>>
>>   reconnect="0x50"
>>
>> I've fixed all these problems, ACKed and pushed.
> 
> Sigh, I was planning to reply to this patch that we should model the XML
> the same way as the reconnect element for chardev devices [1].  Now I
> see that the documentation misses an example.  Anyway this should be the
> correct XML:
> 
> <source type='unix' path='/tmp/vhost2.sock' mode='client'>
>   <reconnect enabled='yes' timeout='10'/>
> </source>

I was thinking about this too. Problem with this is that <source/> for
<interface> has slightly different meaning than for <channel/>. For
instance, we allow:

    <interface type='ethernet'>
      <mac address='00:16:3e:0f:ef:8a'/>
      <source>
        <ip address='192.168.122.12' family='ipv4' prefix='24' peer='192.168.122.1'/>
        <ip address='192.168.122.13' family='ipv4' prefix='24'/>
        <route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/>
        <route family='ipv4' address='192.168.124.0' prefix='24' gateway='192.168.124.1'/>
      </source>
      <ip address='192.168.122.1' family='ipv4' prefix='32' peer='192.168.122.12'/>
      <guest dev='eth2'/>
    </interface>

But now that I think about it, sure. If you think that having it as a
separate element instead of an attribute is better do provide patches.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] vhost-user: add support reconnect for vhost-user ports
Posted by Pavel Hrdina 6 years, 7 months ago
On Fri, Sep 08, 2017 at 05:12:09PM +0800, ZhiPeng Lu wrote:
> 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@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(-)

I sent a revert for this patch since it's not completely correct.

This is the XML format that I'm proposing and it will be the same as for
chardev devices:

  <interface type='vhostuser'>
    <mac address='52:54:00:3b:83:1b'/>
    <source type='unix' path='/tmp/vhost2.sock' mode='client'>
      <reconnect enabled='yes' timeout='10'/>
    </source>
    <model type='virtio'/>
    <driver queues='5'/>
  </interface>

The reason for that format is that it's generic and will work with other
hypervisors if they decide to introduce the same feature.  Another thing
is that adding "reconnect=0" on QEMU command line disables the reconnect
feature and it's better to expose it as <reconnect enabled='no'/>.

The <reconnect> element should be parsed only if the interface type is
"vhostuser" and only if the source type is "unix" since that's the only
type currently supported for "vhostuser" interface.

Check out this commit 9aa72a6dd5b3bd7a7139427dfa315cd36f7b4f0b, there
are virDomainChrSourceReconnectDefParseXML() and
virDomainChrSourceReconnectDefFormat() functions that should be used
for the "vhostuser" interface.

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