]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf/qemu: make <source> element *almost* optional for type=vhostuser
authorLaine Stump <laine@redhat.com>
Mon, 10 Feb 2025 03:52:54 +0000 (22:52 -0500)
committerLaine Stump <laine@redhat.com>
Mon, 17 Feb 2025 04:58:35 +0000 (23:58 -0500)
For some reason, when vhostuser interface support was added in 2014,
the parser required that the XML for the <interface> have a <source>
element with type, mode, and path, all 3 also required. This in spite
of the fact that 'unix' is the only possible valid setting for type,
and 95% of the time the mode is set to 'client' (as I understand from
comments in the code, normally a guest will use mode='client' to
connect to an existing socket that is precreated (by OVS?), and the
only use for mode='server' is for test setups where one guest is setup
with a listening vhostuser socket (i.e. 'server') and another guest
connects to that socket (i.e. 'client')). (or maybe one guest connects
to OVS in server mode, and all the others connect in client mode, not
sure - I don't claim to be an expert on vhost-user.)

So from the point of view of existing vhost-user functionality, it
seems reasonable to make 'type' and 'mode' optional, and by default
fill in the vhostuser part of the NetDef as if they were 'unix' and
'client'.

In theory, the <source> element itself is also not *directly* required
after this patch, however, the path attribute of <source> *is*
required (for now), so effectively the <source> element is still
required.

Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/conf/domain_conf.c
src/conf/schemas/domaincommon.rng
src/qemu/qemu_validate.c

index 50dc4a33a637a15f812fc416113091588fb92979..6b382eb63f629735756def580fec6c004d17029e 100644 (file)
@@ -9776,50 +9776,38 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt,
         g_autofree char *vhostuser_type = NULL;
         virDomainNetVhostuserMode vhostuser_mode;
 
-        if (virDomainNetDefParseXMLRequireSource(def, source_node) < 0)
-            return NULL;
-
-        if (!(vhostuser_type = virXMLPropStringRequired(source_node, "type")))
-            return NULL;
-
-        if (STRNEQ_NULLABLE(vhostuser_type, "unix")) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("Type='%1$s' unsupported for <interface type='vhostuser'>"),
-                           vhostuser_type);
-            return NULL;
-        }
-
         if (!(def->data.vhostuser = virDomainChrSourceDefNew(xmlopt)))
             return NULL;
 
+        /* Default (and only valid) value of type is "unix".
+         * Everything else's default value is 0/NULL.
+         */
         def->data.vhostuser->type = VIR_DOMAIN_CHR_TYPE_UNIX;
 
-        if (!(def->data.vhostuser->data.nix.path = virXMLPropStringRequired(source_node, "path")))
-            return NULL;
+        if (source_node) {
+            if ((vhostuser_type = virXMLPropString(source_node, "type"))) {
+                if (STRNEQ(vhostuser_type, "unix")) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("Type='%1$s' unsupported for <interface type='vhostuser'>"),
+                                   vhostuser_type);
+                    return NULL;
+                }
+            }
 
-        if (virXMLPropEnum(source_node, "mode",
-                           virDomainNetVhostuserModeTypeFromString,
-                           VIR_XML_PROP_REQUIRED | VIR_XML_PROP_NONZERO,
-                           &vhostuser_mode) < 0)
-            return NULL;
+            def->data.vhostuser->data.nix.path = virXMLPropString(source_node, "path");
 
-        switch (vhostuser_mode) {
-        case VIR_DOMAIN_NET_VHOSTUSER_MODE_CLIENT:
-            def->data.vhostuser->data.nix.listen = false;
-            break;
+            if (virXMLPropEnum(source_node, "mode", virDomainNetVhostuserModeTypeFromString,
+                               VIR_XML_PROP_NONZERO, &vhostuser_mode) < 0) {
+                return NULL;
+            }
 
-        case VIR_DOMAIN_NET_VHOSTUSER_MODE_SERVER:
-            def->data.vhostuser->data.nix.listen = true;
-            break;
+            if (vhostuser_mode == VIR_DOMAIN_NET_VHOSTUSER_MODE_SERVER)
+                def->data.vhostuser->data.nix.listen = true;
 
-        case VIR_DOMAIN_NET_VHOSTUSER_MODE_NONE:
-        case VIR_DOMAIN_NET_VHOSTUSER_MODE_LAST:
-            break;
+            if (virDomainChrSourceReconnectDefParseXML(&def->data.vhostuser->data.nix.reconnect,
+                                                       source_node, ctxt) < 0)
+                return NULL;
         }
-
-        if (virDomainChrSourceReconnectDefParseXML(&def->data.vhostuser->data.nix.reconnect,
-                                                   source_node, ctxt) < 0)
-            return NULL;
     }
         break;
 
index 96cedb85e867c4758483ca10a94b33dcf943ebec..e5da550e458598ab82f753520de28f056aacc250 100644 (file)
             <value>vhostuser</value>
           </attribute>
           <interleave>
-            <ref name="unixSocketSource"/>
+            <optional>
+              <ref name="unixSocketSource"/>
+            </optional>
             <ref name="interface-options"/>
           </interleave>
         </group>
index 351fe388309572003f7a838910406fa34f4d4419..b0cf5e866ce92bf8d5a6c27d493b5a21831d6b5a 100644 (file)
@@ -1825,12 +1825,20 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
         }
     }
 
-    if (net->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER &&
-        net->data.vhostuser->data.nix.listen &&
-        net->data.vhostuser->data.nix.reconnect.enabled == VIR_TRISTATE_BOOL_YES) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("'reconnect' attribute is not supported when source mode='server' for <interface type='vhostuser'>"));
-        return -1;
+    if (net->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
+        if (!net->data.vhostuser->data.nix.path) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("Missing required attribute '%1$s' in element '%2$s'"),
+                           "path", "source");
+            return -1;
+        }
+
+        if (net->data.vhostuser->data.nix.listen &&
+            net->data.vhostuser->data.nix.reconnect.enabled == VIR_TRISTATE_BOOL_YES) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("'reconnect' attribute is not supported when source mode='server' for <interface type='vhostuser'>"));
+            return -1;
+        }
     }
 
     if (!virDomainNetIsVirtioModel(net)) {