Enable building for ppc64le

This commit is contained in:
Eduard Abdullin 2025-02-18 02:15:08 +00:00 committed by AlmaLinux Autopatch
commit c1840953f1
21 changed files with 70285 additions and 2 deletions

View File

@ -0,0 +1,158 @@
From 5083667a7f861364e293904a18bce550d9880536 Mon Sep 17 00:00:00 2001
Message-ID: <5083667a7f861364e293904a18bce550d9880536.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Tue, 11 Feb 2025 16:44:49 -0500
Subject: [PATCH] conf: change virDomainHostdevInsert() to return void
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We haven't checked for memalloc failure in many years, and that was
the only reason this function would have ever failed.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 956c6684113b46b2350db698dc75604f4c3a4b76)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
src/conf/domain_conf.c | 15 +++++----------
src/conf/domain_conf.h | 2 +-
src/libxl/libxl_domain.c | 5 +----
src/libxl/libxl_driver.c | 3 +--
src/lxc/lxc_driver.c | 3 +--
src/qemu/qemu_driver.c | 3 +--
src/qemu/qemu_process.c | 3 +--
7 files changed, 11 insertions(+), 23 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d83f1ba240..cba0b162f4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14456,12 +14456,10 @@ virDomainChrTargetTypeToString(int deviceType,
return type;
}
-int
+void
virDomainHostdevInsert(virDomainDef *def, virDomainHostdevDef *hostdev)
{
VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev);
-
- return 0;
}
virDomainHostdevDef *
@@ -14877,9 +14875,8 @@ virDomainDiskRemoveByName(virDomainDef *def, const char *name)
int virDomainNetInsert(virDomainDef *def, virDomainNetDef *net)
{
/* hostdev net devices must also exist in the hostdevs array */
- if (net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
- virDomainHostdevInsert(def, &net->data.hostdev.def) < 0)
- return -1;
+ if (net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV)
+ virDomainHostdevInsert(def, &net->data.hostdev.def);
VIR_APPEND_ELEMENT(def->nets, def->nnets, net);
return 0;
@@ -19257,10 +19254,8 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt,
* where the actual network type is already known to be
* hostdev) must also be in the hostdevs array.
*/
- if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
- virDomainHostdevInsert(def, virDomainNetGetActualHostdev(net)) < 0) {
- return NULL;
- }
+ if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV)
+ virDomainHostdevInsert(def, virDomainNetGetActualHostdev(net));
}
VIR_FREE(nodes);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5237046196..2d38e8fa51 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3982,7 +3982,7 @@ virDomainNetDef *virDomainNetRemove(virDomainDef *def, size_t i);
virDomainNetDef *virDomainNetRemoveByObj(virDomainDef *def, virDomainNetDef *net);
void virDomainNetRemoveHostdev(virDomainDef *def, virDomainNetDef *net);
-int virDomainHostdevInsert(virDomainDef *def, virDomainHostdevDef *hostdev);
+void virDomainHostdevInsert(virDomainDef *def, virDomainHostdevDef *hostdev);
virDomainHostdevDef *
virDomainHostdevRemove(virDomainDef *def, size_t i);
int virDomainHostdevFind(virDomainDef *def, virDomainHostdevDef *match,
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index cad6c9ce42..711e22b8df 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -1015,10 +1015,7 @@ libxlNetworkPrepareDevices(virDomainDef *def)
/* Each type='hostdev' network device must also have a
* corresponding entry in the hostdevs array.
*/
- virDomainHostdevDef *hostdev = virDomainNetGetActualHostdev(net);
-
- if (virDomainHostdevInsert(def, hostdev) < 0)
- return -1;
+ virDomainHostdevInsert(def, virDomainNetGetActualHostdev(net));
}
}
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 29dcee3cfc..b670e697c6 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3585,8 +3585,7 @@ libxlDomainAttachDeviceConfig(virDomainDef *vmdef, virDomainDeviceDef *dev)
return -1;
}
- if (virDomainHostdevInsert(vmdef, hostdev) < 0)
- return -1;
+ virDomainHostdevInsert(vmdef, hostdev);
dev->data.hostdev = NULL;
break;
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index d682e7168a..9609d7d10c 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -3025,8 +3025,7 @@ lxcDomainAttachDeviceConfig(virDomainDef *vmdef,
_("device is already in the domain configuration"));
return -1;
}
- if (virDomainHostdevInsert(vmdef, hostdev) < 0)
- return -1;
+ virDomainHostdevInsert(vmdef, hostdev);
dev->data.hostdev = NULL;
ret = 0;
break;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9a69574f31..379f9fb74f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6734,8 +6734,7 @@ qemuDomainAttachDeviceConfig(virDomainDef *vmdef,
_("device is already in the domain configuration"));
return -1;
}
- if (virDomainHostdevInsert(vmdef, hostdev))
- return -1;
+ virDomainHostdevInsert(vmdef, hostdev);
dev->data.hostdev = NULL;
break;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 1866c8f4e1..a45f1b5b7d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5929,8 +5929,7 @@ qemuProcessPrepareDomainNetwork(virDomainObj *vm)
if (qemuDomainPrepareHostdev(hostdev, priv) < 0)
return -1;
- if (virDomainHostdevInsert(def, hostdev) < 0)
- return -1;
+ virDomainHostdevInsert(def, hostdev);
}
}
return 0;
--
2.48.1

View File

@ -0,0 +1,170 @@
From 6cecf1cbd813f6b197920001a422e87d0999442a Mon Sep 17 00:00:00 2001
Message-ID: <6cecf1cbd813f6b197920001a422e87d0999442a.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Sun, 9 Feb 2025 22:52:54 -0500
Subject: [PATCH] conf/qemu: make <source> element *almost* optional for
type=vhostuser
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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>
(cherry picked from commit fb4bfa78589f7f556b6b0a176f109c94516d3cdd)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
src/conf/domain_conf.c | 56 ++++++++++++-------------------
src/conf/schemas/domaincommon.rng | 4 ++-
src/qemu/qemu_validate.c | 20 +++++++----
3 files changed, 39 insertions(+), 41 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cba0b162f4..b1e9dda80e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9767,50 +9767,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;
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 7121519ca3..cbc093ca7b 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -3485,7 +3485,9 @@
<value>vhostuser</value>
</attribute>
<interleave>
- <ref name="unixSocketSource"/>
+ <optional>
+ <ref name="unixSocketSource"/>
+ </optional>
<ref name="interface-options"/>
</interleave>
</group>
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index b7b2e3d0af..eb8c5366f6 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1810,12 +1810,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)) {
--
2.48.1

View File

@ -0,0 +1,139 @@
From 1be247ee9a7df932a3f2ff2126714755433fc94b Mon Sep 17 00:00:00 2001
Message-ID: <1be247ee9a7df932a3f2ff2126714755433fc94b.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Fri, 14 Feb 2025 23:35:56 -0500
Subject: [PATCH] docs: document using passt backend with <interface
type='vhostuser'>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Almost everything is already there (in the section for using passt
with type='user'), so we just need to point to that from the
type='vhostuser' section (and vice versa), and add a bit of glue.
Also updated a few related details that have changed (e.g. default
model type for vhostuser is now 'virtio', and source type/mode are now
optional), and changed "vhost-user interface" to "vhost-user
connection" because the interface is a virtio interface, and
vhost-user is being used to connect that interface to the outside.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 96fd17a99b514e585a94d43d40ab9a74907c7a5b)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
docs/formatdomain.rst | 73 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 62 insertions(+), 11 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 577366b934..c077c09a39 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -5131,6 +5131,15 @@ destined for the host toward the guest instead), and a socket between
passt and QEMU forwards that traffic on to the guest (and back out,
of course).
+*(:since:`Since 11.1.0 (QEMU and KVM only)` you may prefer to use the
+passt backend with the more efficient and performant type='vhostuser'
+rather than type='user'. All the options related to passt in the
+paragraphs below here also apply when using the passt backend with
+type='vhostuser'; any other details specific to vhostuser are
+described* `here
+<formatdomain.html#vhost-user-connection-with-passt-backend>`__.)
+
+
Similar to SLIRP, passt has an internal DHCP server that provides a
requesting guest with one ipv4 and one ipv6 address. There are default
values for both of these, or you can use the ``<ip>`` element
@@ -5823,7 +5832,7 @@ following attributes are available for the ``virtio`` NIC driver:
The optional ``queues`` attribute controls the number of queues to be used
for either `Multiqueue
virtio-net <https://www.linux-kvm.org/page/Multiqueue>`__ or vhost-user (See
- `vhost-user interface`_) network interfaces. Use of multiple packet
+ `vhost-user connection`_) network interfaces. Use of multiple packet
processing queues requires the interface having the
``<model type='virtio'/>`` element. Each queue will potentially be handled by
a different processor, resulting in much higher throughput.
@@ -6267,8 +6276,8 @@ similarly named elements used to configure the guest side of the interface
(described above).
-vhost-user interface
-^^^^^^^^^^^^^^^^^^^^
+vhost-user connection
+^^^^^^^^^^^^^^^^^^^^^
:since:`Since 1.2.7` the vhost-user enables the communication between a QEMU
virtual machine and other userspace process using the Virtio transport protocol.
@@ -6295,16 +6304,58 @@ plane is based on shared memory.
</devices>
...
-The ``<source>`` element has to be specified along with the type of char device.
-Currently, only type='unix' is supported, where the path (the directory path of
-the socket) and mode attributes are required. Both ``mode='server'`` and
-``mode='client'`` are supported. vhost-user requires the virtio model type, thus
-the ``<model>`` element is mandatory. :since:`Since 4.1.0` the element has an
-optional child element ``reconnect`` which configures reconnect timeout if the
-connection is lost. It has two attributes ``enabled`` (which accepts ``yes`` and
-``no``) and ``timeout`` which specifies the amount of seconds after which
+The ``<source>`` element has to be specified along with the type of
+char device. Currently, only type='unix' is supported, where the path
+(the directory path of the socket) and mode attributes are
+required. Both ``mode='server'`` and ``mode='client'`` are
+supported. (:since:`Since 11.1.0` the default source type for
+vhostuser interfaces is 'unix' and default mode is 'client', so those
+two attributes are now optional).
+
+The vhost-user protocol only works with the virtio guest driver, so
+the ``<model>`` element ``type`` attribute is mandatory (:since:`Since
+11.1.0` the default model type for vhostuser interfaces is now
+'virtio' so ``<model>`` is no longer mandatory). :since:`Since 4.1.0`
+the ``<source>`` element has an optional child element ``reconnect``
+which configures reconnect timeout if the connection is lost. It has
+two attributes ``enabled`` (which accepts ``yes`` and ``no``) and
+``timeout`` which specifies the amount of seconds after which
hypervisor tries to reconnect.
+
+vhost-user connection with passt backend
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:since:`Since 11.1.0 (QEMU and KVM only)` passt can be used as the
+other end of the vhost-user connection. This is a compelling
+alternative, because passt provides all of its network connectivity
+without requiring any elevated privileges or capabilities, and
+vhost-user uses shared memory to make this unprivileged connection
+very high performance as well. You can set a type='vhostuser'
+interface to use passt as the backend by adding ``<backend
+type='passt'/>``. When passt is the backend, only a single driver
+queue is supported, and the ``<source>`` path/type/mode are all
+implied to be "matching the passt process" so **must not** be
+specified. All of the passt options `described here
+<formatdomain.html#userspace-connection-using-passt>`__, are also
+supported for ``type='vhostuser'`` with the passt backend, e.g.
+setting guest-side IP addresses with ``<ip>`` and port forwarding with
+``<portForward``.
+
+::
+
+ ...
+ <devices>
+ <interface type='vhostuser'>
+ <backend type='passt'/>
+ <mac address='52:54:00:3b:83:1a'/>
+ <source dev='enp1s0'/>
+ <ip address='10.30.0.5 prefix='24'/>
+ </interface>
+ </devices>
+ ...
+
+
Traffic filtering with NWFilter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--
2.48.1

View File

@ -0,0 +1,177 @@
From 2e71e35f0d78191d5ea36297877933e58e624a3a Mon Sep 17 00:00:00 2001
Message-ID: <2e71e35f0d78191d5ea36297877933e58e624a3a.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Fri, 14 Feb 2025 22:43:03 -0500
Subject: [PATCH] docs: improve type='user' docs to higlight differences
between SLIRP and passt
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reorganizes the section about <interface type='user'> and
describes the differences in behavior between SLIRP and passt.
Resolves: https://issues.redhat.com/browse/RHEL-46601
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit a47a89a9d335c111a9c2fbb3f4e1c3a13001e74b)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
docs/formatdomain.rst | 116 ++++++++++++++++++++++++++++--------------
1 file changed, 78 insertions(+), 38 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 8d787ef59a..577366b934 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -5072,25 +5072,34 @@ to the interface.
</devices>
...
-Userspace (SLIRP or passt) connection
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Userspace connection using SLIRP
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The ``user`` type connects the guest interface to the outside via a
+The ``user`` interface type connects the guest interface to the outside via a
transparent userspace proxy that doesn't require any special system
privileges, making it usable in cases when libvirt itself is running
with no privileges (e.g. libvirt's "session mode" daemon, or when
libvirt is run inside an unprivileged container).
-By default, this user proxy is done with QEMU's internal SLIRP driver
-which has DHCP & DNS services that give the guest IP addresses
-starting from ``10.0.2.15``, a default route of ``10.0.2.2`` and DNS
-server of ``10.0.2.3``. :since:`Since 3.8.0` it is possible to override
-the default network address by including an ``ip`` element specifying
-an IPv4 address in its one mandatory attribute,
-``address``. Optionally, a second ``ip`` element with a ``family``
-attribute set to "ipv6" can be specified to add an IPv6 address to the
-interface. ``address``. Optionally, address ``prefix`` can be
-specified.
+By default, this user proxy is done with QEMU's SLIRP driver, a
+userspace proxy built into QEMU that has DHCP & DNS services that give
+the guest an IP address of ``10.0.2.15``, a default route of
+``10.0.2.2`` and DNS server at ``10.0.2.3``.
+
+:since:`Since 3.8.0` it is possible to override the guest's default
+network address by including an ``ip`` element specifying an IPv4
+address in its one mandatory attribute, ``address``. Optionally, a
+second ``ip`` element with a ``family`` attribute set to "ipv6" can be
+specified to add an IPv6 address to the interface. ``address``.
+Optionally, an address ``prefix`` can be specified. These settings are
+surprisingly **not** used by SLIRP to set the exact IP address;
+instead they are used to determine what network/subnet the guest's IP
+address should be on, and the guest will be given an address in that
+subnet, but the host portion of the address will still be "2.15". In
+the example below, for example, the guest will be given the IP address
+172.17.2.15 (**note that the '1.1' in the host portion of the address
+has been ignored**), default route of 172.17.2.2, and DNS server
+172.17.2.3.
::
@@ -5100,34 +5109,65 @@ specified.
...
<interface type='user'>
<mac address="00:11:22:33:44:55"/>
- <ip family='ipv4' address='172.17.2.0' prefix='24'/>
- <ip family='ipv6' address='2001:db8:ac10:fd01::' prefix='64'/>
+ <ip family='ipv4' address='172.17.1.1' prefix='16'/>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'/>
</interface>
</devices>
...
-:since:`Since 9.0.0` an alternate backend implementation of the
-``user`` interface type can be selected by setting the interface's
-``<backend>`` subelement ``type`` attribute to ``passt``. In this
-case, the passt transport (https://passt.top) is used. Similar to
-SLIRP, passt has an internal DHCP server that provides a requesting
-guest with one ipv4 and one ipv6 address; it then uses userspace
-proxies and a separate network namespace to provide outgoing
-UDP/TCP/ICMP sessions, and optionally redirect incoming traffic
-destined for the host toward the guest instead.
-
-When the passt backend is used, the ``<backend>`` attribute
-``logFile`` can be used to tell the passt process for this interface
-where to write its message log, and the ``<source>`` attribute ``dev``
-can tell it to use a particular host interface to derive the routes
-given to the guest for forwarding traffic upstream. Due to the design
-decisions of passt, if using SELinux, the log file is recommended to
-reside in the runtime directory of a user under which the passt
-process will run, most probably ``/run/user/$UID`` where ``$UID`` is
-the UID of the user, e.g. ``qemu``. Beware that libvirt does not
-create this directory if it does not already exist to avoid possible,
-however unlikely, issues, especially since this logfile attribute is
-meant mostly for debugging.
+Userspace connection using passt
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:since:`Since 9.0.0 (QEMU and KVM only)` an alternate backend
+implementation of the ``user`` interface type can be selected by
+setting the interface's ``<backend>`` subelement ``type`` attribute to
+``passt``. In this case, the passt transport `(details here)
+<https://passt.top>`__ is used. passt is run as a separate process
+from QEMU - the passt process handles the details of forwarding
+network traffic back and forth to the physical network (using
+userspace proxies and a separate network namespace to provide outgoing
+UDP/TCP/ICMP sessions, and optionally redirecting incoming traffic
+destined for the host toward the guest instead), and a socket between
+passt and QEMU forwards that traffic on to the guest (and back out,
+of course).
+
+Similar to SLIRP, passt has an internal DHCP server that provides a
+requesting guest with one ipv4 and one ipv6 address. There are default
+values for both of these, or you can use the ``<ip>`` element
+(described above, with behavioral differences as outlined below) to
+configure one IPv4 and one IPv6 address that passt's DHCP server can
+provide to the guest.
+
+Unlike SLIRP, when no `<ip>`` address is specified, passt will by
+default provide the guest with an IP address, DNS server, etc. that
+are identical to those settings on the host itself (through the magic
+of the proxies and a separate network namespace, this doesn't create
+any conflict).
+
+Also different from SLIRP's behavior: if you do specify IP
+address(es), the exact address and netmask/prefix you specify will be
+provided to the guest (i.e. passt doesn't interpret the <ip> settings
+as a network address like SLIRP does, but as a host address). In
+example given above, the guest IP would be set to exactly 172.17.1.1.
+
+Just as with SLIRP, though, once traffic from the guest leaves the
+host towards the rest of the network, it will always appear as if it
+came from the host's IP.
+
+There are a few other options that are configurable only for the passt
+backend. For example, the ``<backend>`` attribute ``logFile`` can be
+used to tell the passt process for this interface where to write its
+message log, and the ``<source>`` attribute ``dev`` can tell it a
+particular host interface to use when deriving the routes given to the
+guest for forwarding traffic upstream. Due to the design decisions of
+passt, when using SELinux on the host, it is recommended that the log
+file reside in the runtime directory of the user under which the passt
+process will run, most probably ``/run/user/$UID`` (where ``$UID`` is
+the UID of that user), e.g. ``/run/user/1000``. Be aware that libvirt
+does not create this directory if it does not already exist to avoid
+possible, however unlikely, issues with orphaned directories or
+permissions, etc. The logfile attribute is meant mostly for debugging,
+so it shouldn't be set under normal circumstances.
Additionally, when passt is used, multiple ``<portForward>`` elements
can be added to forward incoming network traffic for the host to this
@@ -5164,7 +5204,7 @@ ports **with the exception of some subset**.
<backend type='passt' logFile='/run/user/$UID/passt-domain.log'/>
<mac address="00:11:22:33:44:55"/>
<source dev='eth0'/>
- <ip family='ipv4' address='172.17.2.4' prefix='24'/>
+ <ip family='ipv4' address='172.17.5.4' prefix='24'/>
<ip family='ipv6' address='2001:db8:ac10:fd01::20'/>
<portForward proto='tcp'>
<range start='2022' to='22'/>
--
2.48.1

View File

@ -0,0 +1,41 @@
From e1e0d3f8b4b6d6694a57425e6a3f85015cee9225 Mon Sep 17 00:00:00 2001
Message-ID: <e1e0d3f8b4b6d6694a57425e6a3f85015cee9225.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Sun, 9 Feb 2025 18:23:03 -0500
Subject: [PATCH] qemu: automatically set model type='virtio' for interface
type='vhostuser'
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Both vdpa and vhostuser require that the guest device be virtio, and
for interface type='vdpa', we already set <model type='virtio'/> if it
is unspecified in the input XML, so let's be just as courteous for
interface type='vhostuser'.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c4746418d7e952888c0989db3a5c723d888fc32d)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
src/qemu/qemu_postparse.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c
index 049a6ef2dc..892330646a 100644
--- a/src/qemu/qemu_postparse.c
+++ b/src/qemu/qemu_postparse.c
@@ -100,7 +100,8 @@ qemuDomainDeviceNetDefPostParse(virDomainNetDef *net,
const virDomainDef *def,
virQEMUCaps *qemuCaps)
{
- if (net->type == VIR_DOMAIN_NET_TYPE_VDPA &&
+ if ((net->type == VIR_DOMAIN_NET_TYPE_VDPA ||
+ net->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER) &&
!virDomainNetGetModelString(net)) {
net->model = VIR_DOMAIN_NET_MODEL_VIRTIO;
} else if (net->type != VIR_DOMAIN_NET_TYPE_HOSTDEV &&
--
2.48.1

View File

@ -0,0 +1,76 @@
From a26297c129ec05c129fda6da57ef8b8330d626be Mon Sep 17 00:00:00 2001
Message-ID: <a26297c129ec05c129fda6da57ef8b8330d626be.1739815540.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 10 Feb 2025 17:57:01 +0100
Subject: [PATCH] qemu: capabilies: Introduce QEMU_CAPS_BLOCKDEV_SET_ACTIVE
The flag signals presence of the 'blockdev-set-active' QMP command.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit b402e167b640bcd242ba518cfd7cbc469dba52e9)
Conflicts:
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
Some capabilities were not backported:
- QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS
- QEMU_CAPS_MIGRATE_INCOMING_EXIT_ON_ERROR
- QEMU_CAPS_MACHINE_VIRT_AIA
- QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW
https://issues.redhat.com/browse/RHEL-78398
---
src/qemu/qemu_capabilities.c | 2 ++
src/qemu/qemu_capabilities.h | 1 +
tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml | 1 +
3 files changed, 4 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index dec3199fce..65e19965dd 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -721,6 +721,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
"chardev-reconnect-miliseconds", /* QEMU_CAPS_CHARDEV_RECONNECT_MILISECONDS */
"virtio-ccw.loadparm", /* QEMU_CAPS_VIRTIO_CCW_DEVICE_LOADPARM */
"netdev-stream-reconnect-miliseconds", /* QEMU_CAPS_NETDEV_STREAM_RECONNECT_MILISECONDS */
+ "blockdev-set-active", /* QEMU_CAPS_BLOCKDEV_SET_ACTIVE */
);
@@ -1242,6 +1243,7 @@ struct virQEMUCapsStringFlags virQEMUCapsCommands[] = {
{ "query-stats-schemas", QEMU_CAPS_QUERY_STATS_SCHEMAS },
{ "display-reload", QEMU_CAPS_DISPLAY_RELOAD },
{ "snapshot-save", QEMU_CAPS_SNAPSHOT_INTERNAL_QMP },
+ { "blockdev-set-active", QEMU_CAPS_BLOCKDEV_SET_ACTIVE },
};
struct virQEMUCapsStringFlags virQEMUCapsMigration[] = {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 48e4530c95..e93e6a01cc 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -700,6 +700,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_CHARDEV_RECONNECT_MILISECONDS, /* 'reconnect-ms' option for chardevs supported */
QEMU_CAPS_VIRTIO_CCW_DEVICE_LOADPARM, /* loadparm available on CCW device for multi device boot */
QEMU_CAPS_NETDEV_STREAM_RECONNECT_MILISECONDS, /* 'reconnect-ms' option for netdev stream supported */
+ QEMU_CAPS_BLOCKDEV_SET_ACTIVE, /* blockdev-set-active QMP command supported */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
index aed0a58fa7..e09b6e6e1a 100644
--- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
@@ -210,6 +210,7 @@
<flag name='snapshot-internal-qmp'/>
<flag name='chardev-reconnect-miliseconds'/>
<flag name='netdev-stream-reconnect-miliseconds'/>
+ <flag name='blockdev-set-active'/>
<version>9002050</version>
<microcodeVersion>43100285</microcodeVersion>
<package>v9.2.0-1636-gffaf7f0376</package>
--
2.48.1

View File

@ -0,0 +1,663 @@
From cdc86b7722beaf209df71b57f76dfbb30c6c7305 Mon Sep 17 00:00:00 2001
Message-ID: <cdc86b7722beaf209df71b57f76dfbb30c6c7305.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Wed, 12 Feb 2025 16:16:44 -0500
Subject: [PATCH] qemu: complete vhostuser + passt support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
<interface type='vhostuser'><backend type='passt'/> needs to run the
passt command just as is done for interface type='user', but then add
vhostuser bits to the qemu commandline/monitor command.
There are some changes to the parsing/validation along with changes to
the vhostuser codepath do do the extra stuff for passt. I tried
keeping them separated into different patches, but then the unit test
failed in a strange way deep down in the bowels of the commandline
generation, so this patch both 1) makes the final changes to
parsing/formatting and 2) adds passt stuff at appropriate places for
vhostuser (as well as making a couple of things *not* happen when the
passt backend is chosen). The result is that you can now have:
<interface type='vhostuser'>
<backend type='passt'/>
...
</interface>
Then as long as you also have the following as a subelement of
<domain>:
<memoryBacking>
<access mode='shared'/>
</memoryBacking>
your passt interfaces will benefit from the greatly improved
efficiency of a vhost-user data path, and all without requiring
special privileges or capabilities *anywhere* (i.e. it works for
unprivileged libvirt (qemu:///session) as well as privileged libvirt).
Resolves: https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 1e9054b9c79d721a55f413c2983c5370044f8f60)
https://issues.redhat.com/browse/RHEL-69455
Signed-off-by: Laine Stump <laine@redhat.com>
---
src/conf/domain_conf.c | 36 ++++++---
src/conf/domain_validate.c | 77 +++++++------------
src/conf/schemas/domaincommon.rng | 32 +++++++-
src/qemu/qemu_command.c | 7 +-
src/qemu/qemu_extdevice.c | 6 +-
src/qemu/qemu_hotplug.c | 21 ++++-
src/qemu/qemu_passt.c | 3 +
src/qemu/qemu_process.c | 15 +++-
src/qemu/qemu_validate.c | 7 +-
...t-user-slirp-portforward.x86_64-latest.err | 2 +-
.../net-vhostuser-passt.x86_64-latest.args | 42 ++++++++++
.../net-vhostuser-passt.x86_64-latest.xml | 72 +++++++++++++++++
tests/qemuxmlconfdata/net-vhostuser-passt.xml | 70 +++++++++++++++++
tests/qemuxmlconftest.c | 1 +
14 files changed, 317 insertions(+), 74 deletions(-)
create mode 100644 tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/net-vhostuser-passt.xml
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b1e9dda80e..095b9bbaa2 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9448,9 +9448,25 @@ virDomainNetBackendParseXML(xmlNodePtr node,
g_autofree char *tap = virXMLPropString(node, "tap");
g_autofree char *vhost = virXMLPropString(node, "vhost");
- /* The VIR_DOMAIN_NET_BACKEND_DEFAULT really means 'use hypervisor's
- * builtin SLIRP'. It's reported in domain caps and thus we need to accept
- * it. Hence VIR_XML_PROP_NONE instead of VIR_XML_PROP_NONZERO. */
+ /* In the case of NET_TYPE_USER, backend type can be unspecified
+ * (i.e. VIR_DOMAIN_NET_BACKEND_DEFAULT) and that means 'use
+ * hypervisor's builtin SLIRP (or if that isn't available, use
+ * passt)'. Similarly, it can also be left unspecified in the case
+ * of NET_TYPE_VHOSTUSER, and then it means "use the traditional
+ * vhost-user backend (which auto-detects between connecting to a
+ * socket created by OVS, or connecting to a standalone socket
+ * used (mostly in testing) to connect the vhost-user interface of
+ * one guest directly to the vhost-user interface of another
+ * guest.
+ *
+ * If backend type is set to 'passt', then in both cases a passt
+ * process will be started, and libvirt will connect that to the
+ * guest interface (either communicating everything over the
+ * socket created by passt using a specific-to-passt protocol
+ * (interface type='user'>), or by using the socket for control
+ * plane messages and shared memory for data using the vhost-user
+ * protocol (<interface type='vhostuser'>)).
+ */
if (virXMLPropEnum(node, "type", virDomainNetBackendTypeFromString,
VIR_XML_PROP_NONE, &def->backend.type) < 0) {
return -1;
@@ -24581,7 +24597,11 @@ virDomainNetDefFormat(virBuffer *buf,
break;
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
- if (def->data.vhostuser->type == VIR_DOMAIN_CHR_TYPE_UNIX) {
+ if (def->data.vhostuser->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
+ def->backend.type != VIR_DOMAIN_NET_BACKEND_PASST) {
+ /* in the case of BACKEND_PASST, the values of all of these are either
+ * fixed (type, mode, reconnect), or derived from elsewhere (path)
+ */
virBufferAddLit(&sourceAttrBuf, " type='unix'");
virBufferEscapeString(&sourceAttrBuf, " path='%s'",
def->data.vhostuser->data.nix.path);
@@ -24592,7 +24612,6 @@ virDomainNetDefFormat(virBuffer *buf,
virDomainChrSourceReconnectDefFormat(&sourceChildBuf,
&def->data.vhostuser->data.nix.reconnect);
}
-
}
break;
@@ -24654,15 +24673,14 @@ virDomainNetDefFormat(virBuffer *buf,
}
case VIR_DOMAIN_NET_TYPE_USER:
- if (def->backend.type == VIR_DOMAIN_NET_BACKEND_PASST)
- virBufferEscapeString(&sourceAttrBuf, " dev='%s'", def->sourceDev);
- break;
-
case VIR_DOMAIN_NET_TYPE_NULL:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
}
+ if (def->backend.type == VIR_DOMAIN_NET_BACKEND_PASST)
+ virBufferEscapeString(&sourceAttrBuf, " dev='%s'", def->sourceDev);
+
if (def->hostIP.nips || def->hostIP.nroutes) {
if (virDomainNetIPInfoFormat(&sourceChildBuf, &def->hostIP) < 0)
return -1;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index dacde1f780..597ae3d938 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2157,67 +2157,46 @@ virDomainNetDefValidate(const virDomainNetDef *net)
return -1;
}
- if (net->type != VIR_DOMAIN_NET_TYPE_USER) {
+ if (net->type != VIR_DOMAIN_NET_TYPE_USER &&
+ net->type != VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("The 'passt' backend can only be used with interface type='user'"));
+ _("The 'passt' backend can only be used with interface type='user' or type='vhostuser'"));
return -1;
}
}
- if (net->nPortForwards > 0 &&
- (net->type != VIR_DOMAIN_NET_TYPE_USER ||
- (net->type == VIR_DOMAIN_NET_TYPE_USER &&
- net->backend.type != VIR_DOMAIN_NET_BACKEND_PASST))) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("The <portForward> element can only be used with <interface type='user'> and its 'passt' backend"));
- return -1;
- }
+ if (net->nPortForwards > 0) {
+ size_t p;
- if (!virNetDevBandwidthValidate(net->bandwidth)) {
- return -1;
- }
+ if ((net->type != VIR_DOMAIN_NET_TYPE_USER &&
+ net->type != VIR_DOMAIN_NET_TYPE_VHOSTUSER) ||
+ net->backend.type != VIR_DOMAIN_NET_BACKEND_PASST) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("The <portForward> element can only be used with the 'passt' backend of interface type='user' or type='vhostuser'"));
+ return -1;
+ }
- switch (net->type) {
- case VIR_DOMAIN_NET_TYPE_USER:
- if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) {
- size_t p;
-
- for (p = 0; p < net->nPortForwards; p++) {
- size_t r;
- virDomainNetPortForward *pf = net->portForwards[p];
-
- for (r = 0; r < pf->nRanges; r++) {
- virDomainNetPortForwardRange *range = pf->ranges[r];
-
- if (!range->start
- && (range->end || range->to
- || range->exclude != VIR_TRISTATE_BOOL_ABSENT)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("The 'range' of a 'portForward' requires 'start' attribute if 'end', 'to', or 'exclude' is specified"));
- return -1;
- }
+ for (p = 0; p < net->nPortForwards; p++) {
+ size_t r;
+ virDomainNetPortForward *pf = net->portForwards[p];
+
+ for (r = 0; r < pf->nRanges; r++) {
+ virDomainNetPortForwardRange *range = pf->ranges[r];
+
+ if (!range->start
+ && (range->end || range->to
+ || range->exclude != VIR_TRISTATE_BOOL_ABSENT)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("The 'range' of a 'portForward' requires 'start' attribute if 'end', 'to', or 'exclude' is specified"));
+ return -1;
}
}
}
- break;
+ }
- case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
- case VIR_DOMAIN_NET_TYPE_NETWORK:
- case VIR_DOMAIN_NET_TYPE_VDPA:
- case VIR_DOMAIN_NET_TYPE_BRIDGE:
- case VIR_DOMAIN_NET_TYPE_CLIENT:
- case VIR_DOMAIN_NET_TYPE_SERVER:
- case VIR_DOMAIN_NET_TYPE_MCAST:
- case VIR_DOMAIN_NET_TYPE_UDP:
- case VIR_DOMAIN_NET_TYPE_INTERNAL:
- case VIR_DOMAIN_NET_TYPE_DIRECT:
- case VIR_DOMAIN_NET_TYPE_HOSTDEV:
- case VIR_DOMAIN_NET_TYPE_VDS:
- case VIR_DOMAIN_NET_TYPE_ETHERNET:
- case VIR_DOMAIN_NET_TYPE_NULL:
- case VIR_DOMAIN_NET_TYPE_LAST:
- break;
+ if (!virNetDevBandwidthValidate(net->bandwidth)) {
+ return -1;
}
return 0;
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index cbc093ca7b..d433e95d8b 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -3486,8 +3486,36 @@
</attribute>
<interleave>
<optional>
- <ref name="unixSocketSource"/>
- </optional>
+ <element name="source">
+ <optional>
+ <attribute name="type">
+ <value>unix</value>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="path">
+ <ref name="absFilePath"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="mode">
+ <choice>
+ <value>server</value>
+ <value>client</value>
+ </choice>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="dev">
+ <ref name="deviceName"/>
+ </attribute>
+ </optional>
+ <optional>
+ <ref name="reconnect"/>
+ </optional>
+ <empty/>
+ </element>
+ </optional>
<ref name="interface-options"/>
</interleave>
</group>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1f28de6194..24dac0ce0f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8617,11 +8617,12 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver,
if (qemuInterfaceVhostuserConnect(cmd, net, qemuCaps) < 0)
goto cleanup;
- if (virNetDevOpenvswitchGetVhostuserIfname(net->data.vhostuser->data.nix.path,
+ if (net->backend.type != VIR_DOMAIN_NET_BACKEND_PASST &&
+ virNetDevOpenvswitchGetVhostuserIfname(net->data.vhostuser->data.nix.path,
net->data.vhostuser->data.nix.listen,
- &net->ifname) < 0)
+ &net->ifname) < 0) {
goto cleanup;
-
+ }
break;
case VIR_DOMAIN_NET_TYPE_VDPA:
diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
index 954cb323a4..2384bab7a6 100644
--- a/src/qemu/qemu_extdevice.c
+++ b/src/qemu/qemu_extdevice.c
@@ -212,13 +212,15 @@ qemuExtDevicesStart(virQEMUDriver *driver,
for (i = 0; i < def->nnets; i++) {
virDomainNetDef *net = def->nets[i];
- if (net->type != VIR_DOMAIN_NET_TYPE_USER)
+ if (net->type != VIR_DOMAIN_NET_TYPE_USER &&
+ net->type != VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
continue;
+ }
if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) {
if (qemuPasstStart(vm, net) < 0)
return -1;
- } else {
+ } else if (net->type == VIR_DOMAIN_NET_TYPE_USER) {
if (qemuSlirpStart(vm, net, incomingMigration) < 0)
return -1;
}
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index de0777d330..c8746f5e22 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1262,10 +1262,23 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
if (!(charDevAlias = qemuAliasChardevFromDevAlias(net->info.alias)))
goto cleanup;
- if (virNetDevOpenvswitchGetVhostuserIfname(net->data.vhostuser->data.nix.path,
- net->data.vhostuser->data.nix.listen,
- &net->ifname) < 0)
- goto cleanup;
+ if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) {
+
+ /* vhostuser needs socket path in this location, and when
+ * backend is passt, the path is derived from other info,
+ * not taken from config.
+ */
+ g_free(net->data.vhostuser->data.nix.path);
+ net->data.vhostuser->data.nix.path = qemuPasstCreateSocketPath(vm, net);
+
+ if (qemuPasstStart(vm, net) < 0)
+ goto cleanup;
+ } else {
+ if (virNetDevOpenvswitchGetVhostuserIfname(net->data.vhostuser->data.nix.path,
+ net->data.vhostuser->data.nix.listen,
+ &net->ifname) < 0)
+ goto cleanup;
+ }
if (qemuSecuritySetNetdevLabel(driver, vm, net) < 0)
goto cleanup;
diff --git a/src/qemu/qemu_passt.c b/src/qemu/qemu_passt.c
index 8a3ac4e988..b9616d1c63 100644
--- a/src/qemu/qemu_passt.c
+++ b/src/qemu/qemu_passt.c
@@ -180,6 +180,9 @@ qemuPasstStart(virDomainObj *vm,
virCommandClearCaps(cmd);
+ if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_VHOSTUSER)
+ virCommandAddArg(cmd, "--vhost-user");
+
virCommandAddArgList(cmd,
"--one-off",
"--socket", passtSocketName,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 26ca943dfc..7285fd5ce9 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -64,6 +64,7 @@
#include "qemu_backup.h"
#include "qemu_dbus.h"
#include "qemu_snapshot.h"
+#include "qemu_passt.h"
#include "cpu/cpu.h"
#include "cpu/cpu_x86.h"
@@ -5932,12 +5933,23 @@ qemuProcessPrepareDomainNetwork(virDomainObj *vm)
}
break;
+ case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
+ if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) {
+ /* when using the passt backend, the path of the
+ * unix socket is always derived from other info
+ * *not* manually given in the config, but all the
+ * vhostuser code looks for it there.
+ */
+ g_free(net->data.vhostuser->data.nix.path);
+ net->data.vhostuser->data.nix.path = qemuPasstCreateSocketPath(vm, net);
+ }
+ break;
+
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_ETHERNET:
case VIR_DOMAIN_NET_TYPE_USER:
- case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
@@ -5949,7 +5961,6 @@ qemuProcessPrepareDomainNetwork(virDomainObj *vm)
case VIR_DOMAIN_NET_TYPE_LAST:
break;
}
-
}
return 0;
}
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index eb8c5366f6..f33c0c07b4 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1736,7 +1736,9 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
return -1;
}
- if (net->type == VIR_DOMAIN_NET_TYPE_USER) {
+ if (net->type == VIR_DOMAIN_NET_TYPE_USER ||
+ (net->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER &&
+ net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST)) {
virDomainCapsDeviceNet netCaps = { };
virQEMUCapsFillDomainDeviceNetCaps(qemuCaps, &netCaps);
@@ -1811,7 +1813,8 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
}
if (net->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
- if (!net->data.vhostuser->data.nix.path) {
+ if (!net->data.vhostuser->data.nix.path &&
+ net->backend.type != VIR_DOMAIN_NET_BACKEND_PASST) {
virReportError(VIR_ERR_XML_ERROR,
_("Missing required attribute '%1$s' in element '%2$s'"),
"path", "source");
diff --git a/tests/qemuxmlconfdata/net-user-slirp-portforward.x86_64-latest.err b/tests/qemuxmlconfdata/net-user-slirp-portforward.x86_64-latest.err
index eaa934742e..e231677e57 100644
--- a/tests/qemuxmlconfdata/net-user-slirp-portforward.x86_64-latest.err
+++ b/tests/qemuxmlconfdata/net-user-slirp-portforward.x86_64-latest.err
@@ -1 +1 @@
-unsupported configuration: The <portForward> element can only be used with <interface type='user'> and its 'passt' backend
+unsupported configuration: The <portForward> element can only be used with the 'passt' backend of interface type='user' or type='vhostuser'
diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args
new file mode 100644
index 0000000000..21d78d6072
--- /dev/null
+++ b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args
@@ -0,0 +1,42 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=219136k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","read-only":false}' \
+-device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-storage","id":"ide0-0-0","bootindex":1}' \
+-chardev socket,id=charnet0,path=/var/run/libvirt/qemu/passt/-1-QEMUGuest1-net0.socket \
+-netdev '{"type":"vhost-user","chardev":"charnet0","id":"hostnet0"}' \
+-device '{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"00:11:22:33:44:55","bus":"pci.0","addr":"0x2"}' \
+-chardev socket,id=charnet1,path=/var/run/libvirt/qemu/passt/-1-QEMUGuest1-net1.socket \
+-netdev '{"type":"vhost-user","chardev":"charnet1","id":"hostnet1"}' \
+-device '{"driver":"virtio-net-pci","netdev":"hostnet1","id":"net1","mac":"00:11:22:33:44:11","bus":"pci.0","addr":"0x3"}' \
+-chardev socket,id=charnet2,path=/var/run/libvirt/qemu/passt/-1-QEMUGuest1-net2.socket \
+-netdev '{"type":"vhost-user","chardev":"charnet2","id":"hostnet2"}' \
+-device '{"driver":"virtio-net-pci","netdev":"hostnet2","id":"net2","mac":"00:11:22:33:44:11","bus":"pci.0","addr":"0x4"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml
new file mode 100644
index 0000000000..26aa4c8d05
--- /dev/null
+++ b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml
@@ -0,0 +1,72 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0' model='none'/>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <interface type='vhostuser'>
+ <mac address='00:11:22:33:44:55'/>
+ <ip address='172.17.2.0' family='ipv4' prefix='24'/>
+ <ip address='2001:db8:ac10:fd01::feed' family='ipv6'/>
+ <portForward proto='tcp' address='2001:db8:ac10:fd01::1:10'>
+ <range start='22' to='2022'/>
+ <range start='1000' end='1050'/>
+ <range start='1020' exclude='yes'/>
+ <range start='1030' end='1040' exclude='yes'/>
+ </portForward>
+ <portForward proto='udp' address='1.2.3.4' dev='eth0'>
+ <range start='5000' end='5020' to='6000'/>
+ <range start='5010' end='5015' exclude='yes'/>
+ </portForward>
+ <portForward proto='tcp'>
+ <range start='80'/>
+ </portForward>
+ <portForward proto='tcp'>
+ <range start='443' to='344'/>
+ </portForward>
+ <model type='virtio'/>
+ <backend type='passt' logFile='/var/log/loglaw.blog'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </interface>
+ <interface type='vhostuser'>
+ <mac address='00:11:22:33:44:11'/>
+ <model type='virtio'/>
+ <backend type='passt'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ <interface type='vhostuser'>
+ <mac address='00:11:22:33:44:11'/>
+ <model type='virtio'/>
+ <backend type='passt'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </interface>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.xml b/tests/qemuxmlconfdata/net-vhostuser-passt.xml
new file mode 100644
index 0000000000..e44c91e541
--- /dev/null
+++ b/tests/qemuxmlconfdata/net-vhostuser-passt.xml
@@ -0,0 +1,70 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0' model='none'/>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <interface type='vhostuser'>
+ <mac address='00:11:22:33:44:55'/>
+ <ip address='172.17.2.0' family='ipv4' prefix='24'/>
+ <ip address='2001:db8:ac10:fd01::feed' family='ipv6'/>
+ <source dev='eth42'/>
+ <portForward proto='tcp' address='2001:db8:ac10:fd01::1:10'>
+ <range start='22' to='2022'/>
+ <range start='1000' end='1050'/>
+ <range start='1020' exclude='yes'/>
+ <range start='1030' end='1040' exclude='yes'/>
+ </portForward>
+ <portForward proto='udp' address='1.2.3.4' dev='eth0'>
+ <range start='5000' end='5020' to='6000'/>
+ <range start='5010' end='5015' exclude='yes'/>
+ </portForward>
+ <portForward proto='tcp'>
+ <range start='80'/>
+ </portForward>
+ <portForward proto='tcp'>
+ <range start='443' to='344'/>
+ </portForward>
+ <model type='virtio'/>
+ <backend type='passt' logFile='/var/log/loglaw.blog'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </interface>
+ <interface type='vhostuser'>
+ <mac address='00:11:22:33:44:11'/>
+ <backend type='passt'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ <interface type='vhostuser'>
+ <mac address='00:11:22:33:44:11'/>
+ <source dev='eth43'/>
+ <model type='virtio'/>
+ <backend type='passt'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </interface>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 821d9b1048..9603984b60 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -1791,6 +1791,7 @@ mymain(void)
DO_TEST_CAPS_LATEST("net-user-passt");
DO_TEST_CAPS_VER("net-user-passt", "7.2.0");
DO_TEST_CAPS_LATEST_PARSE_ERROR("net-user-slirp-portforward");
+ DO_TEST_CAPS_LATEST("net-vhostuser-passt");
DO_TEST_CAPS_LATEST("net-virtio");
DO_TEST_CAPS_LATEST("net-virtio-device");
DO_TEST_CAPS_LATEST("net-virtio-disable-offloads");
--
2.48.1

View File

@ -0,0 +1,75 @@
From 83cb107badafc54fcd29eb000121d784cde92d84 Mon Sep 17 00:00:00 2001
Message-ID: <83cb107badafc54fcd29eb000121d784cde92d84.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Sun, 9 Feb 2025 19:01:32 -0500
Subject: [PATCH] qemu: do all vhostuser attribute validation in qemu driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since vhostuser is only used/supported by the QEMU driver, and all the
rest of the vhostuser-specific validation is done in QEMU's
validation, lets move the final check (to see if they've tried to
enable auto-reconnect when this interface is on the server side of the
vhostuser socket) to the QEMU validate.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 56f4cc167a6c93ec420c82f15a265ec08469279d)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
src/conf/domain_validate.c | 10 +---------
src/qemu/qemu_validate.c | 8 ++++++++
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index f56ff5b7bb..dacde1f780 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2179,15 +2179,6 @@ virDomainNetDefValidate(const virDomainNetDef *net)
}
switch (net->type) {
- case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
- 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 unsupported 'server' mode for <interface type='vhostuser'>"));
- return -1;
- }
- break;
-
case VIR_DOMAIN_NET_TYPE_USER:
if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) {
size_t p;
@@ -2211,6 +2202,7 @@ virDomainNetDefValidate(const virDomainNetDef *net)
}
break;
+ case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_VDPA:
case VIR_DOMAIN_NET_TYPE_BRIDGE:
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 841d320541..b7b2e3d0af 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1810,6 +1810,14 @@ 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 (!virDomainNetIsVirtioModel(net)) {
if (net->type == VIR_DOMAIN_NET_TYPE_VDPA ||
net->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
--
2.48.1

View File

@ -0,0 +1,203 @@
From bd90132d08a4222f4103873b8532fb8b5d999018 Mon Sep 17 00:00:00 2001
Message-ID: <bd90132d08a4222f4103873b8532fb8b5d999018.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Fri, 14 Feb 2025 13:10:19 -0500
Subject: [PATCH] qemu: fail validation if a domain def has vhostuser/passt but
no shared mem
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This can/should also be done for a traditional vhost-user interface
(ie not backend type='passt') but that will be a separate change.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 70bce2e6ee7a6b738d08fa79d14342969f51668b)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
src/qemu/qemu_validate.c | 9 ++-
...vhostuser-passt-no-shmem.x86_64-latest.err | 1 +
.../net-vhostuser-passt-no-shmem.xml | 70 +++++++++++++++++++
.../net-vhostuser-passt.x86_64-latest.args | 2 +-
.../net-vhostuser-passt.x86_64-latest.xml | 3 +
tests/qemuxmlconfdata/net-vhostuser-passt.xml | 3 +
tests/qemuxmlconftest.c | 1 +
7 files changed, 87 insertions(+), 2 deletions(-)
create mode 100644 tests/qemuxmlconfdata/net-vhostuser-passt-no-shmem.x86_64-latest.err
create mode 100644 tests/qemuxmlconfdata/net-vhostuser-passt-no-shmem.xml
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index f33c0c07b4..289a3f94cc 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1724,6 +1724,7 @@ qemuValidateDomainDefVhostUserRequireSharedMemory(const virDomainDef *def,
static int
qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
+ const virDomainDef *def,
virQEMUCaps *qemuCaps)
{
bool hasIPv4 = false;
@@ -1804,6 +1805,12 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
return -1;
}
+ if (net->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER &&
+ net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) {
+ if (qemuValidateDomainDefVhostUserRequireSharedMemory(def, "interface type=\"vhostuser\" backend type=\"passt\"") < 0)
+ return -1;
+ }
+
if (net->type == VIR_DOMAIN_NET_TYPE_VDPA) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV_VHOST_VDPA)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -5400,7 +5407,7 @@ qemuValidateDomainDeviceDef(const virDomainDeviceDef *dev,
switch (dev->type) {
case VIR_DOMAIN_DEVICE_NET:
- return qemuValidateDomainDeviceDefNetwork(dev->data.net, qemuCaps);
+ return qemuValidateDomainDeviceDefNetwork(dev->data.net, def, qemuCaps);
case VIR_DOMAIN_DEVICE_CHR:
return qemuValidateDomainChrDef(dev->data.chr, def, qemuCaps);
diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt-no-shmem.x86_64-latest.err b/tests/qemuxmlconfdata/net-vhostuser-passt-no-shmem.x86_64-latest.err
new file mode 100644
index 0000000000..274af5c722
--- /dev/null
+++ b/tests/qemuxmlconfdata/net-vhostuser-passt-no-shmem.x86_64-latest.err
@@ -0,0 +1 @@
+unsupported configuration: 'interface type="vhostuser" backend type="passt"' requires shared memory
diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt-no-shmem.xml b/tests/qemuxmlconfdata/net-vhostuser-passt-no-shmem.xml
new file mode 100644
index 0000000000..e44c91e541
--- /dev/null
+++ b/tests/qemuxmlconfdata/net-vhostuser-passt-no-shmem.xml
@@ -0,0 +1,70 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0' model='none'/>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <interface type='vhostuser'>
+ <mac address='00:11:22:33:44:55'/>
+ <ip address='172.17.2.0' family='ipv4' prefix='24'/>
+ <ip address='2001:db8:ac10:fd01::feed' family='ipv6'/>
+ <source dev='eth42'/>
+ <portForward proto='tcp' address='2001:db8:ac10:fd01::1:10'>
+ <range start='22' to='2022'/>
+ <range start='1000' end='1050'/>
+ <range start='1020' exclude='yes'/>
+ <range start='1030' end='1040' exclude='yes'/>
+ </portForward>
+ <portForward proto='udp' address='1.2.3.4' dev='eth0'>
+ <range start='5000' end='5020' to='6000'/>
+ <range start='5010' end='5015' exclude='yes'/>
+ </portForward>
+ <portForward proto='tcp'>
+ <range start='80'/>
+ </portForward>
+ <portForward proto='tcp'>
+ <range start='443' to='344'/>
+ </portForward>
+ <model type='virtio'/>
+ <backend type='passt' logFile='/var/log/loglaw.blog'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </interface>
+ <interface type='vhostuser'>
+ <mac address='00:11:22:33:44:11'/>
+ <backend type='passt'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ <interface type='vhostuser'>
+ <mac address='00:11:22:33:44:11'/>
+ <source dev='eth43'/>
+ <model type='virtio'/>
+ <backend type='passt'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </interface>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args
index 21d78d6072..7c030d7067 100644
--- a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args
@@ -14,7 +14,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-accel tcg \
-cpu qemu64 \
-m size=219136k \
--object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
+-object '{"qom-type":"memory-backend-file","id":"pc.ram","mem-path":"/var/lib/libvirt/qemu/ram/-1-QEMUGuest1/pc.ram","share":true,"x-use-canonical-path-for-ramblock-id":false,"size":224395264}' \
-overcommit mem-lock=off \
-smp 1,sockets=1,cores=1,threads=1 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml
index 26aa4c8d05..a1f9366722 100644
--- a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml
@@ -3,6 +3,9 @@
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
+ <memoryBacking>
+ <access mode='shared'/>
+ </memoryBacking>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64' machine='pc'>hvm</type>
diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.xml b/tests/qemuxmlconfdata/net-vhostuser-passt.xml
index e44c91e541..71b845329b 100644
--- a/tests/qemuxmlconfdata/net-vhostuser-passt.xml
+++ b/tests/qemuxmlconfdata/net-vhostuser-passt.xml
@@ -3,6 +3,9 @@
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
+ <memoryBacking>
+ <access mode='shared'/>
+ </memoryBacking>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64' machine='pc'>hvm</type>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 9603984b60..3947f508a2 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -1792,6 +1792,7 @@ mymain(void)
DO_TEST_CAPS_VER("net-user-passt", "7.2.0");
DO_TEST_CAPS_LATEST_PARSE_ERROR("net-user-slirp-portforward");
DO_TEST_CAPS_LATEST("net-vhostuser-passt");
+ DO_TEST_CAPS_LATEST_PARSE_ERROR("net-vhostuser-passt-no-shmem");
DO_TEST_CAPS_LATEST("net-virtio");
DO_TEST_CAPS_LATEST("net-virtio-device");
DO_TEST_CAPS_LATEST("net-virtio-disable-offloads");
--
2.48.1

View File

@ -0,0 +1,94 @@
From eb843b8d21a68b245d53c0e54ec064918eb1e775 Mon Sep 17 00:00:00 2001
Message-ID: <eb843b8d21a68b245d53c0e54ec064918eb1e775.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Tue, 4 Feb 2025 16:06:18 -0500
Subject: [PATCH] qemu: fix qemu validation to forbid guest-side IP address for
type='vdpa'
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Because all the checks for VIR_DOMAIN_NET_TYPE_VDPA were inside an
else-if clause that was immediately followed by another else-if clause
that forbid setting guestIP.ips or guestIP.routes, we've been allowing
users to set guestIP.* for vdpa interfaces (but then not doing
validation of the attributes that should have been done if we *did*
support setting IPs for vdpa (but we don't anyway, so :shrug:.)
This can be fixed by turning the vdpa else-if clause into a top-level
if - this way vdpa interfaces will hit the "else if
(net->guestIP.nips)" clause and reject guest-side IP address setting.
Also, since there are currently *no* interface types for QEMU that
support adding guest-side routes, we put that check by itself (I think
it may be possible to set some guest routes for passt interfaces, but
we don't do that)
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 6345ee60d87a6490a51a58527dc9b47e4d0264f9)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
src/qemu/qemu_validate.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index aaa056379e..9310457cb1 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1730,6 +1730,12 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
bool hasIPv6 = false;
size_t i;
+ if (net->guestIP.nroutes) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Invalid attempt to set network interface guest-side IP route, not supported by QEMU"));
+ return -1;
+ }
+
if (net->type == VIR_DOMAIN_NET_TYPE_USER) {
virDomainCapsDeviceNet netCaps = { };
@@ -1743,12 +1749,6 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
return -1;
}
- if (net->guestIP.nroutes) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Invalid attempt to set network interface guest-side IP route, not supported by QEMU"));
- return -1;
- }
-
for (i = 0; i < net->guestIP.nips; i++) {
const virNetDevIPAddr *ip = net->guestIP.ips[i];
@@ -1796,7 +1796,13 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
}
}
}
- } else if (net->type == VIR_DOMAIN_NET_TYPE_VDPA) {
+ } else if (net->guestIP.nips) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Invalid attempt to set network interface guest-side IP address info, not supported by QEMU"));
+ return -1;
+ }
+
+ if (net->type == VIR_DOMAIN_NET_TYPE_VDPA) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV_VHOST_VDPA)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("vDPA devices are not supported with this QEMU binary"));
@@ -1810,10 +1816,6 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
virDomainNetModelTypeToString(net->model));
return -1;
}
- } else if (net->guestIP.nroutes || net->guestIP.nips) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Invalid attempt to set network interface guest-side IP route and/or address info, not supported by QEMU"));
- return -1;
}
if (virDomainNetIsVirtioModel(net)) {
--
2.48.1

View File

@ -0,0 +1,51 @@
From 7128909f7a0227a2977345e56ccc0516cc07ea05 Mon Sep 17 00:00:00 2001
Message-ID: <7128909f7a0227a2977345e56ccc0516cc07ea05.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Wed, 12 Feb 2025 12:12:04 -0500
Subject: [PATCH] qemu: make qemuPasstCreateSocketPath() public
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When passt is used with vhostuser, the vhostuser code that builds the
qemu commandline will need to have the same socket path that is given
to the passt command, so this patch makes it visible outside of
qemu_passt.c.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 7b7c56c3b81c0f525c6b2f1c89e0ef070bb4fb19)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
src/qemu/qemu_passt.c | 2 +-
src/qemu/qemu_passt.h | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_passt.c b/src/qemu/qemu_passt.c
index dd4a8bb997..8a3ac4e988 100644
--- a/src/qemu/qemu_passt.c
+++ b/src/qemu/qemu_passt.c
@@ -54,7 +54,7 @@ qemuPasstCreatePidFilename(virDomainObj *vm,
}
-static char *
+char *
qemuPasstCreateSocketPath(virDomainObj *vm,
virDomainNetDef *net)
{
diff --git a/src/qemu/qemu_passt.h b/src/qemu/qemu_passt.h
index 623b494b7a..e0b9aaac8d 100644
--- a/src/qemu/qemu_passt.h
+++ b/src/qemu/qemu_passt.h
@@ -36,3 +36,6 @@ void qemuPasstStop(virDomainObj *vm,
int qemuPasstSetupCgroup(virDomainObj *vm,
virDomainNetDef *net,
virCgroup *cgroup);
+
+char *qemuPasstCreateSocketPath(virDomainObj *vm,
+ virDomainNetDef *net);
--
2.48.1

View File

@ -0,0 +1,137 @@
From 8012f23fe028ca0a4392094e2185d361ca568455 Mon Sep 17 00:00:00 2001
Message-ID: <8012f23fe028ca0a4392094e2185d361ca568455.1739815540.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 10 Feb 2025 19:49:10 +0100
Subject: [PATCH] qemu: migration: Reactivate block nodes after migration if VM
is left paused
On incoming migration qemu doesn't activate the block graph nodes right
away. This is to properly facilitate locking of the images.
The block nodes are normally re-activated when starting the CPUs after
migration, but in cases (e.g. when a paused VM was migrated) when the VM
is left paused the block nodes are not re-activated by qemu.
This means that blockjobs which would want to write to an existing
backing chain member would fail. Generally read-only jobs would succeed
with older qemu's but this was not intended.
Instead with new qemu you'll always get an error if attempting to access
a inactive node:
error: internal error: unable to execute QEMU command 'blockdev-mirror': Inactive 'libvirt-1-storage' can't be a backing child of active '#block052'
This is the case for explicit blockjobs (virsh blockcopy) but also for
non shared-storage migration (virsh migrate --copy-storage-all).
Since qemu now provides 'blockdev-set-active' QMP command which can
on-demand re-activate the nodes we can re-activate them in similar cases
as when we'd be starting vCPUs if the VM weren't left paused.
The only exception is on the source in case of a failed post-copy
migration as the VM already ran on destination so it won't ever run on
the source even when recovered.
Resolves: https://issues.redhat.com/browse/RHEL-78398
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 2626fa0569781c0f42db247f4b7116c33cd88b43)
---
src/qemu/qemu_migration.c | 55 ++++++++++++++++++++++++++++++++++++---
1 file changed, 52 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 4112e95a1e..62da892254 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -220,6 +220,43 @@ qemuMigrationSrcStoreDomainState(virDomainObj *vm)
}
+/**
+ * qemuMigrationBlockNodesReactivate:
+ *
+ * In case when we're keeping the VM paused qemu will not re-activate the block
+ * device backend tree so blockjobs would fail. In case when qemu supports the
+ * 'blockdev-set-active' command this function will re-activate the block nodes.
+ */
+static void
+qemuMigrationBlockNodesReactivate(virDomainObj *vm,
+ virDomainAsyncJob asyncJob)
+{
+ virErrorPtr orig_err;
+ qemuDomainObjPrivate *priv = vm->privateData;
+ int rc;
+
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_SET_ACTIVE))
+ return;
+
+ VIR_DEBUG("re-activating block nodes");
+
+ virErrorPreserveLast(&orig_err);
+
+ if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
+ goto cleanup;
+
+ rc = qemuMonitorBlockdevSetActive(priv->mon, NULL, true);
+
+ qemuDomainObjExitMonitor(vm);
+
+ if (rc < 0)
+ VIR_WARN("failed to re-activate block nodes after migration of VM '%s'", vm->def->name);
+
+ cleanup:
+ virErrorRestore(&orig_err);
+}
+
+
static void
qemuMigrationSrcRestoreDomainState(virQEMUDriver *driver, virDomainObj *vm)
{
@@ -236,14 +273,17 @@ qemuMigrationSrcRestoreDomainState(virQEMUDriver *driver, virDomainObj *vm)
virDomainStateTypeToString(state),
virDomainStateReasonToString(state, reason));
- if (preMigrationState != VIR_DOMAIN_RUNNING ||
- state != VIR_DOMAIN_PAUSED ||
+ if (state == VIR_DOMAIN_PAUSED &&
reason == VIR_DOMAIN_PAUSED_POSTCOPY_FAILED)
return;
+ if (preMigrationState != VIR_DOMAIN_RUNNING ||
+ state != VIR_DOMAIN_PAUSED)
+ goto reactivate;
+
if (reason == VIR_DOMAIN_PAUSED_IOERROR) {
VIR_DEBUG("Domain is paused due to I/O error, skipping resume");
- return;
+ goto reactivate;
}
VIR_DEBUG("Restoring pre-migration state due to migration error");
@@ -266,7 +306,14 @@ qemuMigrationSrcRestoreDomainState(virQEMUDriver *driver, virDomainObj *vm)
VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR);
virObjectEventStateQueue(driver->domainEventState, event);
}
+
+ goto reactivate;
}
+
+ return;
+
+ reactivate:
+ qemuMigrationBlockNodesReactivate(vm, VIR_ASYNC_JOB_MIGRATION_OUT);
}
@@ -6781,6 +6828,8 @@ qemuMigrationDstFinishFresh(virQEMUDriver *driver,
if (*inPostCopy)
*doKill = false;
+ } else {
+ qemuMigrationBlockNodesReactivate(vm, VIR_ASYNC_JOB_MIGRATION_IN);
}
if (mig->jobData) {
--
2.48.1

View File

@ -0,0 +1,160 @@
From 2eede6a92213c7f72fda218616635cd71efdab34 Mon Sep 17 00:00:00 2001
Message-ID: <2eede6a92213c7f72fda218616635cd71efdab34.1739815540.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 10 Feb 2025 17:51:31 +0100
Subject: [PATCH] qemu: monitor: Add monitor backend for 'blockdev-set-active'
The command will be used to re-activate block nodes after migration when
we're leaving the VM paused so that blockjobs can be used.
As the 'node-name' field is optional the 'qemumonitorjsontest' case
tests both variants.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit d8f9cfb5e45111da0bd39f334f0643c0ab22ef49)
https://issues.redhat.com/browse/RHEL-78398
---
src/qemu/qemu_monitor.c | 21 +++++++++++++++++++++
src/qemu/qemu_monitor.h | 5 +++++
src/qemu/qemu_monitor_json.c | 21 +++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 5 +++++
tests/qemumonitorjsontest.c | 31 +++++++++++++++++++++++++++++++
5 files changed, 83 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 79ff4e2e87..82aa1cbc5f 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4555,3 +4555,24 @@ qemuMonitorDisplayReload(qemuMonitor *mon,
return qemuMonitorJSONDisplayReload(mon, type, tlsCerts);
}
+
+
+/**
+ * qemuMonitorBlockdevSetActive:
+ * @mon: monitor object
+ * @nodename: optional nodename to (de)activate
+ * @active: requested state
+ *
+ * Activate or deactivate @nodename based on @active. If @nodename is NULL,
+ * qemu will act on all block nodes.
+ */
+int
+qemuMonitorBlockdevSetActive(qemuMonitor *mon,
+ const char *nodename,
+ bool active)
+{
+ QEMU_CHECK_MONITOR(mon);
+ VIR_DEBUG("nodename='%s', active='%d'", NULLSTR(nodename), active);
+
+ return qemuMonitorJSONBlockdevSetActive(mon, nodename, active);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index a4818a6aa1..672cd6487e 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1650,3 +1650,8 @@ qemuMonitorSnapshotDelete(qemuMonitor *mon,
const char *jobname,
const char *snapshotname,
const char **disks);
+
+int
+qemuMonitorBlockdevSetActive(qemuMonitor *mon,
+ const char *nodename,
+ bool active);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 53648dea8b..6f9f495888 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8831,3 +8831,24 @@ qemuMonitorJSONSnapshotDelete(qemuMonitor *mon,
return qemuMonitorJSONCheckError(cmd, reply);
}
+
+
+int
+qemuMonitorJSONBlockdevSetActive(qemuMonitor *mon,
+ const char *nodename,
+ bool active)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("blockdev-set-active",
+ "S:node-name", nodename,
+ "b:active", active,
+ NULL)))
+ return -1;
+
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ return -1;
+
+ return qemuMonitorJSONCheckError(cmd, reply);
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 0214e9e9ff..68f60aec61 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -816,3 +816,8 @@ qemuMonitorJSONSnapshotDelete(qemuMonitor *mon,
const char *jobname,
const char *snapshotname,
const char **disks);
+
+int
+qemuMonitorJSONBlockdevSetActive(qemuMonitor *mon,
+ const char *nodename,
+ bool active);
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index f7fe0fb6f4..f0f6a329c8 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -1249,6 +1249,36 @@ testQemuMonitorJSONqemuMonitorJSONSnapshot(const void *opaque)
}
+static int
+testQemuMonitorJSONqemuMonitorJSONBlockdevSetActive(const void *opaque)
+{
+ const testGenericData *data = opaque;
+ virDomainXMLOption *xmlopt = data->xmlopt;
+ g_autoptr(qemuMonitorTest) test = NULL;
+
+ if (!(test = qemuMonitorTestNewSchema(xmlopt, data->schema)))
+ return -1;
+
+ if (qemuMonitorTestAddItem(test, "blockdev-set-active",
+ "{\"return\":{}}") < 0)
+ return -1;
+
+ if (qemuMonitorTestAddItem(test, "blockdev-set-active",
+ "{\"return\":{}}") < 0)
+ return -1;
+
+ if (qemuMonitorJSONBlockdevSetActive(qemuMonitorTestGetMonitor(test),
+ NULL, true) < 0)
+ return -1;
+
+ if (qemuMonitorJSONBlockdevSetActive(qemuMonitorTestGetMonitor(test),
+ "testnode", false) < 0)
+ return -1;
+
+ return 0;
+}
+
+
static bool
testQemuMonitorJSONqemuMonitorJSONQueryCPUsEqual(struct qemuMonitorQueryCpusEntry *a,
struct qemuMonitorQueryCpusEntry *b)
@@ -2989,6 +3019,7 @@ mymain(void)
DO_TEST(qemuMonitorJSONSendKeyHoldtime);
DO_TEST(qemuMonitorJSONNBDServerStart);
DO_TEST(qemuMonitorJSONSnapshot);
+ DO_TEST(qemuMonitorJSONBlockdevSetActive);
DO_TEST_CPU_DATA("host");
DO_TEST_CPU_DATA("full");
--
2.48.1

View File

@ -0,0 +1,132 @@
From 0dc1ceab2611a06d5f108c8f74e1c876de05cd44 Mon Sep 17 00:00:00 2001
Message-ID: <0dc1ceab2611a06d5f108c8f74e1c876de05cd44.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Tue, 11 Feb 2025 16:30:11 -0500
Subject: [PATCH] qemu: use switch instead of if in
qemuProcessPrepareDomainNetwork()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
qemuProcessPrepareDomain()'s comments say that it should be the only
place to change the "live XML" of a domain (i.e. the public parts of
the virDomainDef object that is shown in the domain's status
XML), and that seems like a reasonable idea (although there aren't
many users of it to date).
qemuProcessPrepareDomainNetwork() is called by the aforementioned
qemuProcessPrepareDomain() - this patch changes the "if (type ==
HOSTDEV)" in that function to a "switch(type)" so it's simpler to add
DomainDef modifications for various other types of virDomainNetDef,
and also so that anyone who adds a new interface type is forced to
look at the code and decide if anything needs to be done here for the
new type.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 6fe3d765e506b2954931e228ecd233f1200dce1a)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
src/qemu/qemu_process.c | 75 ++++++++++++++++++++++++++---------------
1 file changed, 47 insertions(+), 28 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a45f1b5b7d..26ca943dfc 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5888,7 +5888,6 @@ qemuProcessPrepareDomainNetwork(virDomainObj *vm)
for (i = 0; i < def->nnets; i++) {
virDomainNetDef *net = def->nets[i];
- virDomainNetType actualType;
/* If appropriate, grab a physical device from the configured
* network's pool of devices, or resolve bridge device name
@@ -5901,36 +5900,56 @@ qemuProcessPrepareDomainNetwork(virDomainObj *vm)
return -1;
}
- actualType = virDomainNetGetActualType(net);
- if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
- net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
- /* Each type='hostdev' network device must also have a
- * corresponding entry in the hostdevs array. For netdevs
- * that are hardcoded as type='hostdev', this is already
- * done by the parser, but for those allocated from a
- * network / determined at runtime, we need to do it
- * separately.
- */
- virDomainHostdevDef *hostdev = virDomainNetGetActualHostdev(net);
- virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci;
-
- if (virDomainHostdevFind(def, hostdev, NULL) >= 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("PCI device %1$04x:%2$02x:%3$02x.%4$x allocated from network %5$s is already in use by domain %6$s"),
- pcisrc->addr.domain, pcisrc->addr.bus,
- pcisrc->addr.slot, pcisrc->addr.function,
- net->data.network.name, def->name);
- return -1;
- }
+ switch (virDomainNetGetActualType(net)) {
+ case VIR_DOMAIN_NET_TYPE_HOSTDEV:
+ if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+ /* Each type='hostdev' network device must also have a
+ * corresponding entry in the hostdevs array. For netdevs
+ * that are hardcoded as type='hostdev', this is already
+ * done by the parser, but for those allocated from a
+ * network / determined at runtime, we need to do it
+ * separately.
+ */
+ virDomainHostdevDef *hostdev = virDomainNetGetActualHostdev(net);
+ virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci;
+
+ if (virDomainHostdevFind(def, hostdev, NULL) >= 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("PCI device %1$04x:%2$02x:%3$02x.%4$x allocated from network %5$s is already in use by domain %6$s"),
+ pcisrc->addr.domain, pcisrc->addr.bus,
+ pcisrc->addr.slot, pcisrc->addr.function,
+ net->data.network.name, def->name);
+ return -1;
+ }
- /* For hostdev present in qemuProcessPrepareDomain() phase this was
- * done already, but this code runs after that, so we have to call
- * it ourselves. */
- if (qemuDomainPrepareHostdev(hostdev, priv) < 0)
- return -1;
+ /* For hostdev present in qemuProcessPrepareDomain() phase this was
+ * done already, but this code runs after that, so we have to call
+ * it ourselves. */
+ if (qemuDomainPrepareHostdev(hostdev, priv) < 0)
+ return -1;
- virDomainHostdevInsert(def, hostdev);
+ virDomainHostdevInsert(def, hostdev);
+ }
+ break;
+
+ case VIR_DOMAIN_NET_TYPE_DIRECT:
+ case VIR_DOMAIN_NET_TYPE_BRIDGE:
+ case VIR_DOMAIN_NET_TYPE_NETWORK:
+ case VIR_DOMAIN_NET_TYPE_ETHERNET:
+ case VIR_DOMAIN_NET_TYPE_USER:
+ case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
+ case VIR_DOMAIN_NET_TYPE_SERVER:
+ case VIR_DOMAIN_NET_TYPE_CLIENT:
+ case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_INTERNAL:
+ case VIR_DOMAIN_NET_TYPE_UDP:
+ case VIR_DOMAIN_NET_TYPE_VDPA:
+ case VIR_DOMAIN_NET_TYPE_NULL:
+ case VIR_DOMAIN_NET_TYPE_VDS:
+ case VIR_DOMAIN_NET_TYPE_LAST:
+ break;
}
+
}
return 0;
}
--
2.48.1

View File

@ -0,0 +1,82 @@
From 5d7fa1e2def7a48f23dc908c504288d23f0bdafa Mon Sep 17 00:00:00 2001
Message-ID: <5d7fa1e2def7a48f23dc908c504288d23f0bdafa.1739815540.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Sun, 9 Feb 2025 18:46:00 -0500
Subject: [PATCH] qemu: validate that model is virtio for vhostuser and vdpa
interfaces in the same place
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Both vhostuser and vdpa interface types must use the virtio model in
the guest (because part of the functionality is implemented in the
guest virtio driver). Due to ["because that's the way it happened"]
this has been validated for vhostuser in the hypervisor-agnostic
validate function, but for vdpa it has been done in the QEMU-specific
validate. Since these interface models are only supported by QEMU
anyway, validate for both of them in the QEMU validation function.
Take advantage of this change to switch to using
virDomainNetIsVirtioModel(net) instead of "net->model ==
VIR_DOMAIN_NET_MODEL_VIRTIO" (the former also matches
...VIRTIO_TRANSITIONAL and ...VIRTIO_NON_TRANSITIONAL, so is more
correct).
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 154d44a585c40d0b6cf3bae674da2a8ca11ddb95)
https://issues.redhat.com/browse/RHEL-77086
Signed-off-by: Laine Stump <laine@redhat.com>
---
src/conf/domain_validate.c | 6 ------
src/qemu/qemu_validate.c | 11 ++++++-----
2 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 1034bb57f5..f56ff5b7bb 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2180,12 +2180,6 @@ virDomainNetDefValidate(const virDomainNetDef *net)
switch (net->type) {
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
- if (!virDomainNetIsVirtioModel(net)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Wrong or no <model> 'type' attribute specified with <interface type='vhostuser'/>. vhostuser requires the virtio-net* frontend"));
- 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",
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 9310457cb1..841d320541 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1808,17 +1808,18 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
_("vDPA devices are not supported with this QEMU binary"));
return -1;
}
+ }
- if (net->model != VIR_DOMAIN_NET_MODEL_VIRTIO) {
+ if (!virDomainNetIsVirtioModel(net)) {
+ if (net->type == VIR_DOMAIN_NET_TYPE_VDPA ||
+ net->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("invalid model for interface of type '%1$s': '%2$s'"),
+ _("invalid model for interface of type '%1$s': '%2$s' - must be 'virtio'"),
virDomainNetTypeToString(net->type),
virDomainNetModelTypeToString(net->model));
return -1;
}
- }
-
- if (virDomainNetIsVirtioModel(net)) {
+ } else {
if (net->driver.virtio.rx_queue_size) {
if (!VIR_IS_POW2(net->driver.virtio.rx_queue_size)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
--
2.48.1

View File

@ -0,0 +1,38 @@
From 33c6c5a2061321e75fa1455a5ad9fa192b1a7825 Mon Sep 17 00:00:00 2001
Message-ID: <33c6c5a2061321e75fa1455a5ad9fa192b1a7825.1739815540.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 15 Jan 2025 16:02:00 +0100
Subject: [PATCH] qemu_migration: Do not automatically resume domain after I/O
error
When an I/O error happens (causing a domain to be paused) during live
migration which is later cancelled by a user, trying to resume the
domain doesn't make sense.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 3766891c5954c53370d7eb9c7a0a8e6ba3854ca4)
https://issues.redhat.com/browse/RHEL-1071
---
src/qemu/qemu_migration.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index fe0b9fc672..4112e95a1e 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -241,6 +241,11 @@ qemuMigrationSrcRestoreDomainState(virQEMUDriver *driver, virDomainObj *vm)
reason == VIR_DOMAIN_PAUSED_POSTCOPY_FAILED)
return;
+ if (reason == VIR_DOMAIN_PAUSED_IOERROR) {
+ VIR_DEBUG("Domain is paused due to I/O error, skipping resume");
+ return;
+ }
+
VIR_DEBUG("Restoring pre-migration state due to migration error");
/* we got here through some sort of failure; start the domain again */
--
2.48.1

View File

@ -0,0 +1,110 @@
From f9698e648654cf75af7ef2366c4ad7c2b8c19f6d Mon Sep 17 00:00:00 2001
Message-ID: <f9698e648654cf75af7ef2366c4ad7c2b8c19f6d.1739815540.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 15 Jan 2025 15:59:22 +0100
Subject: [PATCH] qemu_migration: Refactor qemuMigrationSrcRestoreDomainState
None of the callers really care about the return value so we can drop it
and simplify the code a bit.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit e46e64be501cd670a3f224fabd97705fb01c6f85)
https://issues.redhat.com/browse/RHEL-1071
---
src/qemu/qemu_migration.c | 64 +++++++++++++++++----------------------
1 file changed, 28 insertions(+), 36 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index b2b172a26c..fe0b9fc672 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -219,57 +219,49 @@ qemuMigrationSrcStoreDomainState(virDomainObj *vm)
priv->preMigrationState, vm);
}
-/* Returns true if the domain was resumed, false otherwise */
-static bool
+
+static void
qemuMigrationSrcRestoreDomainState(virQEMUDriver *driver, virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
+ virDomainState preMigrationState = priv->preMigrationState;
int reason;
virDomainState state = virDomainObjGetState(vm, &reason);
- bool ret = false;
+
+ priv->preMigrationState = VIR_DOMAIN_NOSTATE;
VIR_DEBUG("driver=%p, vm=%p, pre-mig-state=%s, state=%s, reason=%s",
driver, vm,
- virDomainStateTypeToString(priv->preMigrationState),
+ virDomainStateTypeToString(preMigrationState),
virDomainStateTypeToString(state),
virDomainStateReasonToString(state, reason));
- if (state != VIR_DOMAIN_PAUSED ||
+ if (preMigrationState != VIR_DOMAIN_RUNNING ||
+ state != VIR_DOMAIN_PAUSED ||
reason == VIR_DOMAIN_PAUSED_POSTCOPY_FAILED)
- goto cleanup;
+ return;
- if (priv->preMigrationState == VIR_DOMAIN_RUNNING) {
- /* This is basically the only restore possibility that's safe
- * and we should attempt to do */
-
- VIR_DEBUG("Restoring pre-migration state due to migration error");
-
- /* we got here through some sort of failure; start the domain again */
- if (qemuProcessStartCPUs(driver, vm,
- VIR_DOMAIN_RUNNING_MIGRATION_CANCELED,
- VIR_ASYNC_JOB_MIGRATION_OUT) < 0) {
- /* Hm, we already know we are in error here. We don't want to
- * overwrite the previous error, though, so we just throw something
- * to the logs and hope for the best */
- VIR_ERROR(_("Failed to resume guest %1$s after failure"), vm->def->name);
- if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
- virObjectEvent *event;
-
- virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
- VIR_DOMAIN_PAUSED_API_ERROR);
- event = virDomainEventLifecycleNewFromObj(vm,
- VIR_DOMAIN_EVENT_SUSPENDED,
- VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR);
- virObjectEventStateQueue(driver->domainEventState, event);
- }
- goto cleanup;
+ VIR_DEBUG("Restoring pre-migration state due to migration error");
+
+ /* we got here through some sort of failure; start the domain again */
+ if (qemuProcessStartCPUs(driver, vm,
+ VIR_DOMAIN_RUNNING_MIGRATION_CANCELED,
+ VIR_ASYNC_JOB_MIGRATION_OUT) < 0) {
+ /* Hm, we already know we are in error here. We don't want to
+ * overwrite the previous error, though, so we just throw something
+ * to the logs and hope for the best */
+ VIR_ERROR(_("Failed to resume guest %1$s after failure"), vm->def->name);
+ if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
+ virObjectEvent *event;
+
+ virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
+ VIR_DOMAIN_PAUSED_API_ERROR);
+ event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_SUSPENDED,
+ VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR);
+ virObjectEventStateQueue(driver->domainEventState, event);
}
- ret = true;
}
-
- cleanup:
- priv->preMigrationState = VIR_DOMAIN_NOSTATE;
- return ret;
}
--
2.48.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
From d4bff9bd1d108937b70ce1c9931bcc13e3ad1437 Mon Sep 17 00:00:00 2001
Message-ID: <d4bff9bd1d108937b70ce1c9931bcc13e3ad1437.1739815540.git.jdenemar@redhat.com>
From: Andrea Bolognani <abologna@redhat.com>
Date: Thu, 13 Feb 2025 09:54:05 +0100
Subject: [PATCH] utils: Canonicalize paths before comparing them
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In virFileIsSharedFSOverride() we compare a path against a list
of overrides looking for a match.
All overrides are canonicalized ahead of time though, so e.g.
/var/run/foo will be turned into /run/foo due to /var/run being
a symlink on modern Linux systems. But the path we're trying to
match with the overrides doesn't get the same treatment, so in
this scenario the comparison will always fail.
Canonicalizing the path as well solves the issue.
Resolves: https://issues.redhat.com/browse/RHEL-79165
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit f2023e8018fe18550ad6aec66fe72bd1376f8522)
https://issues.redhat.com/browse/RHEL-79165
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
src/util/virfile.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 6ac0f4efb3..7cab3d0cd6 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -3823,10 +3823,13 @@ virFileIsSharedFSOverride(const char *path,
if (!path || path[0] != '/' || !overrides)
return false;
- if (g_strv_contains((const char *const *) overrides, path))
- return true;
+ /* Overrides have been canonicalized ahead of time, so we need to
+ * do the same for the provided path or we'll never be able to
+ * find a match if symlinks are involved */
+ dirpath = virFileCanonicalizePath(path);
- dirpath = g_strdup(path);
+ if (g_strv_contains((const char *const *) overrides, dirpath))
+ return true;
/* Continue until we've scanned the entire path */
while (p != dirpath) {
--
2.48.1

View File

@ -293,7 +293,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 10.10.0
Release: 6%{?dist}%{?extra_release}.alma.1
Release: 7%{?dist}%{?extra_release}.alma.1
License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1
URL: https://libvirt.org/
@ -367,6 +367,26 @@ Patch63: libvirt-qemu-snapshot-Ensure-that-NVRAM-image-exists-when-taking-inacti
Patch64: libvirt-qemuxmlconftest-Allow-testing-of-the-writable-flag-for-passed-FDs-for-disks.patch
Patch65: libvirt-qemuxmlconftest-Add-testing-of-FDs-with-writable-flag-in-disk-source-fd.patch
Patch66: libvirt-qemu-domain-Initialize-FD-passthrough-for-a-virStorageSource-before-using-it.patch
Patch67: libvirt-qemu_migration-Refactor-qemuMigrationSrcRestoreDomainState.patch
Patch68: libvirt-qemu_migration-Do-not-automatically-resume-domain-after-I-O-error.patch
Patch69: libvirt-qemucapabilitiestest-Add-data-for-the-qemu-10.0-dev-cycle-on-x86_64.patch
Patch70: libvirt-qemucapabilitiestest-Update-caps_10.0.0_x86_64-to-v9.2.0-1636-gffaf7f0376.patch
Patch71: libvirt-qemu-capabilies-Introduce-QEMU_CAPS_BLOCKDEV_SET_ACTIVE.patch
Patch72: libvirt-qemu-monitor-Add-monitor-backend-for-blockdev-set-active.patch
Patch73: libvirt-qemu-migration-Reactivate-block-nodes-after-migration-if-VM-is-left-paused.patch
Patch74: libvirt-conf-change-virDomainHostdevInsert-to-return-void.patch
Patch75: libvirt-qemu-fix-qemu-validation-to-forbid-guest-side-IP-address-for-type-vdpa.patch
Patch76: libvirt-qemu-validate-that-model-is-virtio-for-vhostuser-and-vdpa-interfaces-in-the-same-place.patch
Patch77: libvirt-qemu-automatically-set-model-type-virtio-for-interface-type-vhostuser.patch
Patch78: libvirt-qemu-do-all-vhostuser-attribute-validation-in-qemu-driver.patch
Patch79: libvirt-conf-qemu-make-source-element-almost-optional-for-type-vhostuser.patch
Patch80: libvirt-qemu-use-switch-instead-of-if-in-qemuProcessPrepareDomainNetwork.patch
Patch81: libvirt-qemu-make-qemuPasstCreateSocketPath-public.patch
Patch82: libvirt-qemu-complete-vhostuser-passt-support.patch
Patch83: libvirt-qemu-fail-validation-if-a-domain-def-has-vhostuser-passt-but-no-shared-mem.patch
Patch84: libvirt-docs-improve-type-user-docs-to-higlight-differences-between-SLIRP-and-passt.patch
Patch85: libvirt-docs-document-using-passt-backend-with-interface-type-vhostuser.patch
Patch86: libvirt-utils-Canonicalize-paths-before-comparing-them.patch
Requires: libvirt-daemon = %{version}-%{release}
@ -2691,9 +2711,31 @@ exit 0
%endif
%changelog
* Wed Feb 12 2025 Eduard Abdullin <eabdullin@almalinux.org> - 10.10.0-6.alma.1
* Tue Feb 18 2025 Eduard Abdullin <eabdullin@almalinux.org> - 10.10.0-7.alma.1
- Enable building for ppc64le
* Mon Feb 17 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-7
- qemu_migration: Refactor qemuMigrationSrcRestoreDomainState (RHEL-1071)
- qemu_migration: Do not automatically resume domain after I/O error (RHEL-1071)
- qemucapabilitiestest: Add data for the qemu-10.0 dev cycle on x86_64 (RHEL-78398)
- qemucapabilitiestest: Update 'caps_10.0.0_x86_64' to 'v9.2.0-1636-gffaf7f0376' (RHEL-78398)
- qemu: capabilies: Introduce QEMU_CAPS_BLOCKDEV_SET_ACTIVE (RHEL-78398)
- qemu: monitor: Add monitor backend for 'blockdev-set-active' (RHEL-78398)
- qemu: migration: Reactivate block nodes after migration if VM is left paused (RHEL-78398)
- conf: change virDomainHostdevInsert() to return void (RHEL-77086)
- qemu: fix qemu validation to forbid guest-side IP address for type='vdpa' (RHEL-77086)
- qemu: validate that model is virtio for vhostuser and vdpa interfaces in the same place (RHEL-77086)
- qemu: automatically set model type='virtio' for interface type='vhostuser' (RHEL-77086)
- qemu: do all vhostuser attribute validation in qemu driver (RHEL-77086)
- conf/qemu: make <source> element *almost* optional for type=vhostuser (RHEL-77086)
- qemu: use switch instead of if in qemuProcessPrepareDomainNetwork() (RHEL-77086)
- qemu: make qemuPasstCreateSocketPath() public (RHEL-77086)
- qemu: complete vhostuser + passt support (RHEL-77086)
- qemu: fail validation if a domain def has vhostuser/passt but no shared mem (RHEL-77086)
- docs: improve type='user' docs to higlight differences between SLIRP and passt (RHEL-77086)
- docs: document using passt backend with <interface type='vhostuser'> (RHEL-77086)
- utils: Canonicalize paths before comparing them (RHEL-79165)
* Fri Feb 7 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-6
- build: Bump minimum glib2 version to 2.66.0 (RHEL-76802)
- qemuProcessHandleIOError: Refactor to extract 'priv' instead of 'driver' (RHEL-76802)