Compare commits
8 Commits
01e1b91449
...
d7c309784a
| Author | SHA1 | Date |
|---|---|---|
|
|
d7c309784a | 2 months ago |
|
|
52aad0ee14 | 2 months ago |
|
|
7eee526e3e | 2 months ago |
|
|
940a8a1af9 | 2 months ago |
|
|
5fb979149b | 2 months ago |
|
|
d825e80265 | 2 months ago |
|
|
e7905a965f | 2 months ago |
|
|
526c7b13d0 | 2 months ago |
119 changed files with 56457 additions and 3606 deletions
@ -0,0 +1,45 @@ |
|||
name: Backport Packages for Fedora Rawhide (Daily) |
|||
|
|||
# Every day at 02:00 UTC |
|||
on: |
|||
schedule: |
|||
- cron: '0 2 * * *' |
|||
# Enables manual triggering of the workflow |
|||
workflow_dispatch: |
|||
|
|||
jobs: |
|||
update-packages-rawhide: |
|||
runs-on: ubuntu-latest |
|||
|
|||
# Defines the Fedora container for this job |
|||
container: |
|||
image: fedora:latest |
|||
|
|||
steps: |
|||
# 1. Install pre-requisites |
|||
- name: Install pre-requisites |
|||
run: dnf install -y patch git git-lfs jq |
|||
|
|||
# 2. Checkout the repository |
|||
- name: Checkout repository |
|||
uses: actions/checkout@v4 |
|||
with: |
|||
ref: main |
|||
lfs: true |
|||
# We cannot use the default GITHUB_TOKEN as it is restricted and cannot |
|||
# trigger another workflow run, which is needed here to trigger the COPR build |
|||
token: ${{ secrets.COMMIT_TOKEN }} |
|||
|
|||
# 2.5. Configure Git safe directory |
|||
- name: Configure Git safe directory |
|||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE" |
|||
|
|||
# 3. Run the update script for Fedora Rawhide only. |
|||
- name: Run update script for Fedora Rawhide (best effort) |
|||
run: ./update.sh fedora-rawhide |
|||
|
|||
# 4. Push changes (if any) |
|||
- uses: stefanzweifel/git-auto-commit-action@v7 |
|||
with: |
|||
commit_message: Backport packages from Fedora Rawhide |
|||
commit_author: Nicolas Massé <nicolas.masse@itix.fr> |
|||
@ -0,0 +1,38 @@ |
|||
name: Trigger COPR Build for Fedora Rawhide |
|||
|
|||
on: |
|||
# Trigger on push, but only for fedora-rawhide SPECS and SOURCES changes |
|||
push: |
|||
paths: |
|||
- fedora-rawhide/SPECS/*.spec |
|||
- fedora-rawhide/SOURCES/** |
|||
|
|||
# Enables manual triggering of the workflow |
|||
workflow_dispatch: |
|||
|
|||
jobs: |
|||
build-copr-rawhide: |
|||
runs-on: ubuntu-latest |
|||
|
|||
# Defines the Fedora container for this job |
|||
container: |
|||
image: fedora:latest |
|||
|
|||
steps: |
|||
# 1. Install copr-cli |
|||
- name: Install copr-cli |
|||
run: dnf install -y copr-cli git git-lfs jq |
|||
|
|||
# 2. Checkout the repository |
|||
- name: Checkout repository |
|||
uses: actions/checkout@v4 |
|||
with: |
|||
ref: ${{ github.head_ref }} |
|||
lfs: true |
|||
|
|||
# 3. Run the build script for Fedora Rawhide only. |
|||
- name: Run COPR build script for Fedora Rawhide (best effort) |
|||
run: ./build.sh fedora-rawhide |
|||
# Inject secrets into the container as environment variables |
|||
env: |
|||
COPR_CONFIG: ${{ secrets.COPR_CONFIG }} |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:f7882fe65302bbcf804b573e0128c4fc6bfc52c9c3f44852a04de2391d858e34 |
|||
size 10093332 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:104f70ee591e72989d4f8c6caa79ed9dacd5dc84efdb0125b848afe544ad0c2d |
|||
size 10145112 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:06bb2efe406454b398621db73dee9bac80e31b80ab0df662c4d57f5fca974b41 |
|||
size 33883409 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:ef669f8ba31b6998a97002d29eb079c8680e59fd2a9202fcb9ca7a9d9522459d |
|||
size 33857690 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:a2a2b8ba8dcb1b73f82d416f2399315d7e2cb129711e945922e4688d46f32d9f |
|||
size 33879322 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:f7882fe65302bbcf804b573e0128c4fc6bfc52c9c3f44852a04de2391d858e34 |
|||
size 10093332 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:104f70ee591e72989d4f8c6caa79ed9dacd5dc84efdb0125b848afe544ad0c2d |
|||
size 10145112 |
|||
@ -0,0 +1,73 @@ |
|||
From 7a8f13f443843e8903ab18d5917f6f8bc4192dd6 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <7a8f13f443843e8903ab18d5917f6f8bc4192dd6.1780571167.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Tue, 26 May 2026 15:38:59 +0200 |
|||
Subject: [PATCH] Fix documentation of |
|||
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES |
|||
|
|||
The flag is designed for expanding the CPU model used by host-model. But |
|||
the documentation was sometimes describing it as showing all CPU |
|||
features supported on the host, which is wrong as the host may support |
|||
features that would not be enabled in host-model. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 090183a7dc4a64cca83937eff9a4e93a45b4d712) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
docs/manpages/virsh.rst | 5 +++-- |
|||
src/libvirt-domain.c | 6 +++--- |
|||
tools/virsh-host.c | 2 +- |
|||
3 files changed, 7 insertions(+), 6 deletions(-) |
|||
|
|||
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
|
|||
index 85fa6ab011..7169b6bc05 100644
|
|||
--- a/docs/manpages/virsh.rst
|
|||
+++ b/docs/manpages/virsh.rst
|
|||
@@ -640,8 +640,9 @@ flagged as deprecated for the CPU model by the hypervisor. These
|
|||
features will be paired with the "disable" policy. |
|||
|
|||
The **--expand-cpu-features** option will cause the host-model CPU definition |
|||
-to contain all CPU features supported on the host including those implicitly
|
|||
-enabled by the selected CPU model.
|
|||
+to contain all required CPU features including those implicitly enabled by the
|
|||
+selected CPU model. Without this flag features that are part of the CPU model
|
|||
+itself will not be listed.
|
|||
|
|||
|
|||
pool-capabilities |
|||
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
|
|||
index 034f126dd5..e146fa7e82 100644
|
|||
--- a/src/libvirt-domain.c
|
|||
+++ b/src/libvirt-domain.c
|
|||
@@ -12331,9 +12331,9 @@ virDomainSetUserPassword(virDomainPtr dom,
|
|||
* passthrough and so on. |
|||
* |
|||
* If @flags includes VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES, |
|||
- * libvirt will explicitly list all CPU features (in host-model CPU definition)
|
|||
- * that are supported on the host. Without this flag features that are part of
|
|||
- * the CPU model itself will not be listed.
|
|||
+ * libvirt will explicitly list all CPU features that will be enabled for
|
|||
+ * host-model CPU mode. Without this flag features that are part of the CPU
|
|||
+ * model itself will not be listed.
|
|||
* |
|||
* Returns NULL in case of error or an XML string |
|||
* defining the capabilities. |
|||
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
|
|||
index dd98917fa8..5dbeb54ae5 100644
|
|||
--- a/tools/virsh-host.c
|
|||
+++ b/tools/virsh-host.c
|
|||
@@ -120,7 +120,7 @@ static const vshCmdOptDef opts_domcapabilities[] = {
|
|||
}, |
|||
{.name = "expand-cpu-features", |
|||
.type = VSH_OT_BOOL, |
|||
- .help = N_("show all features in host CPU model"),
|
|||
+ .help = N_("expand 'host-model' CPU to also show features enabled by the CPU model"),
|
|||
}, |
|||
{.name = NULL} |
|||
}; |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,54 @@ |
|||
From 9644e7aceda1ca2b88d9eb699a274c5b4eafbda1 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <9644e7aceda1ca2b88d9eb699a274c5b4eafbda1.1780571166.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Wed, 11 Mar 2026 11:31:06 +0100 |
|||
Subject: [PATCH] Introduce EXPAND_CPU_FEATURES flag for domain capabilities |
|||
|
|||
The new VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES flag for |
|||
virConnectGetDomainCapabilities can be used to request the host-model |
|||
CPU definition to include all supported features (normally only extra |
|||
features relative to the selected CPU model are listed). |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 8aa13d1b16b08feea37ecacc85540671e7995bb8) |
|||
|
|||
https://issues.redhat.com/browse/RHEL-153653 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
include/libvirt/libvirt-domain.h | 2 ++ |
|||
src/libvirt-domain.c | 5 +++++ |
|||
2 files changed, 7 insertions(+) |
|||
|
|||
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
|
|||
index 8e62bd23d4..1c5dbdc26e 100644
|
|||
--- a/include/libvirt/libvirt-domain.h
|
|||
+++ b/include/libvirt/libvirt-domain.h
|
|||
@@ -1517,6 +1517,8 @@ int virDomainMigrateStartPostCopy(virDomainPtr domain,
|
|||
typedef enum { |
|||
/* Report host model with deprecated features disabled. (Since: 11.0.0) */ |
|||
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES = (1 << 0), |
|||
+ /* Report all host model CPU features. (Since: 12.2.0) */
|
|||
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES = (1 << 1),
|
|||
} virConnectGetDomainCapabilitiesFlags; |
|||
|
|||
char * virConnectGetDomainCapabilities(virConnectPtr conn, |
|||
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
|
|||
index c7451fee05..034f126dd5 100644
|
|||
--- a/src/libvirt-domain.c
|
|||
+++ b/src/libvirt-domain.c
|
|||
@@ -12330,6 +12330,11 @@ virDomainSetUserPassword(virDomainPtr dom,
|
|||
* instance, if host, libvirt and qemu is capable of VFIO |
|||
* passthrough and so on. |
|||
* |
|||
+ * If @flags includes VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
|
|||
+ * libvirt will explicitly list all CPU features (in host-model CPU definition)
|
|||
+ * that are supported on the host. Without this flag features that are part of
|
|||
+ * the CPU model itself will not be listed.
|
|||
+ *
|
|||
* Returns NULL in case of error or an XML string |
|||
* defining the capabilities. |
|||
* |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,59 @@ |
|||
From f4588f45d48037050c88624e37f7b13e15138b0e Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <f4588f45d48037050c88624e37f7b13e15138b0e.1780571167.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Fri, 29 May 2026 12:52:39 +0200 |
|||
Subject: [PATCH] Introduce |
|||
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag |
|||
|
|||
Some CPU features may be enabled explicitly, but should not |
|||
automatically become part of a host-model CPU. Users can now request |
|||
such features to be shown in the host-model CPU in domain capabilities |
|||
by VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit e1efd79e837456d209115c536fc7e5f14abcbc63) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
include/libvirt/libvirt-domain.h | 3 +++ |
|||
src/libvirt-domain.c | 8 ++++++++ |
|||
2 files changed, 11 insertions(+) |
|||
|
|||
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
|
|||
index 1c5dbdc26e..4d7c0099ef 100644
|
|||
--- a/include/libvirt/libvirt-domain.h
|
|||
+++ b/include/libvirt/libvirt-domain.h
|
|||
@@ -1519,6 +1519,9 @@ typedef enum {
|
|||
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES = (1 << 0), |
|||
/* Report all host model CPU features. (Since: 12.2.0) */ |
|||
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES = (1 << 1), |
|||
+ /* Report all CPU features supported on the host, even those that will not
|
|||
+ * be enabled by host-model CPU mode. (Since: 12.5.0) */
|
|||
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES = (1 << 2),
|
|||
} virConnectGetDomainCapabilitiesFlags; |
|||
|
|||
char * virConnectGetDomainCapabilities(virConnectPtr conn, |
|||
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
|
|||
index e146fa7e82..0ae48654df 100644
|
|||
--- a/src/libvirt-domain.c
|
|||
+++ b/src/libvirt-domain.c
|
|||
@@ -12335,6 +12335,14 @@ virDomainSetUserPassword(virDomainPtr dom,
|
|||
* host-model CPU mode. Without this flag features that are part of the CPU |
|||
* model itself will not be listed. |
|||
* |
|||
+ * Adding VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES to @flags
|
|||
+ * tells libvirt to update the host-model CPU definition with features that are
|
|||
+ * supported on the host, but will not be enabled by default when starting a
|
|||
+ * domain with host-model CPU. Use both
|
|||
+ * VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES and
|
|||
+ * VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES flags to get a
|
|||
+ * complete list of features that can be enabled on the host.
|
|||
+ *
|
|||
* Returns NULL in case of error or an XML string |
|||
* defining the capabilities. |
|||
* |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,160 @@ |
|||
From 99ca73f9c43c7a266cf65f0012a5350197d0f229 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <99ca73f9c43c7a266cf65f0012a5350197d0f229.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Fri, 13 Mar 2026 15:28:17 +0100 |
|||
Subject: [PATCH] conf: Add iommufd fdgroup support |
|||
|
|||
This will allow management applications running libvirt without |
|||
necessary permissions to pass FD for /dev/iommu with per-process |
|||
locked memory accounting enabled. |
|||
|
|||
Kernel uses per-user locked memory accounting by default which may |
|||
cause error while starting multiple VMs with host devices using IOMMUFD. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 58875a6df679c5272f61028d33bf1380c51b0d5b) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
docs/formatdomain.rst | 8 +++++++- |
|||
src/conf/domain_conf.c | 6 ++++++ |
|||
src/conf/domain_conf.h | 1 + |
|||
src/conf/domain_validate.c | 16 ++++++++++++++++ |
|||
src/conf/schemas/domaincommon.rng | 3 +++ |
|||
tests/genericxml2xmlindata/iommufd.xml | 2 +- |
|||
6 files changed, 34 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
|
|||
index 86b3bad903..225152e0f2 100644
|
|||
--- a/docs/formatdomain.rst
|
|||
+++ b/docs/formatdomain.rst
|
|||
@@ -1368,7 +1368,7 @@ Host Device IOMMUFD
|
|||
|
|||
<domain> |
|||
... |
|||
- <iommufd enabled='yes'/>
|
|||
+ <iommufd enabled='yes' fdgroup='iommu'/>
|
|||
... |
|||
</domain> |
|||
|
|||
@@ -1382,6 +1382,12 @@ Host Device IOMMUFD
|
|||
This controls IOMMUFD usage for all host devices, each device can change this |
|||
global default by setting ``iommufd`` attribute for ``driver`` element. |
|||
|
|||
+ Optional ``fdgroup`` attribute can be used together with
|
|||
+ `virDomainFDAssociate <html/libvirt-libvirt-domain.html#virDomainFDAssociate>`__
|
|||
+ to pass /dev/iommu FD instead of letting libvirt to open it. Caller is
|
|||
+ responsible for setting per-process locked memory accounting otherwise
|
|||
+ starting multiple VMs with host devices using IOMMUFD may fail.
|
|||
+
|
|||
Resource partitioning |
|||
--------------------- |
|||
|
|||
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|||
index 1e91561fea..cec0f88f0f 100644
|
|||
--- a/src/conf/domain_conf.c
|
|||
+++ b/src/conf/domain_conf.c
|
|||
@@ -4192,6 +4192,8 @@ void virDomainDefFree(virDomainDef *def)
|
|||
g_free(def->kvm_features); |
|||
g_free(def->tcg_features); |
|||
|
|||
+ g_free(def->iommufd_fdgroup);
|
|||
+
|
|||
virBlkioDeviceArrayClear(def->blkio.devices, |
|||
def->blkio.ndevices); |
|||
g_free(def->blkio.devices); |
|||
@@ -19765,6 +19767,8 @@ virDomainDefIommufdParse(virDomainDef *def,
|
|||
if (virXMLPropTristateBool(nodes[0], "enabled", VIR_XML_PROP_REQUIRED, &def->iommufd) < 0) |
|||
return -1; |
|||
|
|||
+ def->iommufd_fdgroup = virXMLPropString(nodes[0], "fdgroup");
|
|||
+
|
|||
return 0; |
|||
} |
|||
|
|||
@@ -27998,6 +28002,8 @@ virDomainDefIommufdFormat(virBuffer *buf,
|
|||
virBufferAsprintf(&attrBuf, " enabled='%s'", |
|||
virTristateBoolTypeToString(def->iommufd)); |
|||
|
|||
+ virBufferEscapeString(&attrBuf, " fdgroup='%s'", def->iommufd_fdgroup);
|
|||
+
|
|||
virXMLFormatElement(buf, "iommufd", &attrBuf, NULL); |
|||
} |
|||
|
|||
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
|||
index e12064a3ab..8c8c11c0cf 100644
|
|||
--- a/src/conf/domain_conf.h
|
|||
+++ b/src/conf/domain_conf.h
|
|||
@@ -3232,6 +3232,7 @@ struct _virDomainDef {
|
|||
virDomainFeatureTCG *tcg_features; |
|||
|
|||
virTristateBool iommufd; |
|||
+ char *iommufd_fdgroup;
|
|||
|
|||
bool tseg_specified; |
|||
unsigned long long tseg_size; |
|||
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
|
|||
index 4558e7b210..3e6ba5e609 100644
|
|||
--- a/src/conf/domain_validate.c
|
|||
+++ b/src/conf/domain_validate.c
|
|||
@@ -1995,6 +1995,19 @@ virDomainDefValidateThrottleGroups(const virDomainDef *def)
|
|||
} |
|||
|
|||
|
|||
+static int
|
|||
+virDomainDefValidateIommufd(const virDomainDef *def)
|
|||
+{
|
|||
+ if (def->iommufd == VIR_TRISTATE_BOOL_NO && def->iommufd_fdgroup) {
|
|||
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|||
+ _("Setting 'fdgroup' when 'iommufd' is disabled is not supported."));
|
|||
+ return -1;
|
|||
+ }
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+
|
|||
static int |
|||
virDomainDefValidateInternal(const virDomainDef *def, |
|||
virDomainXMLOption *xmlopt) |
|||
@@ -2056,6 +2069,9 @@ virDomainDefValidateInternal(const virDomainDef *def,
|
|||
if (virDomainDefValidateThrottleGroups(def) < 0) |
|||
return -1; |
|||
|
|||
+ if (virDomainDefValidateIommufd(def) < 0)
|
|||
+ return -1;
|
|||
+
|
|||
return 0; |
|||
} |
|||
|
|||
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
|
|||
index 81b57a937a..9fde565d94 100644
|
|||
--- a/src/conf/schemas/domaincommon.rng
|
|||
+++ b/src/conf/schemas/domaincommon.rng
|
|||
@@ -1353,6 +1353,9 @@
|
|||
<attribute name="enabled"> |
|||
<ref name="virYesNo"/> |
|||
</attribute> |
|||
+ <optional>
|
|||
+ <attribute name="fdgroup"/>
|
|||
+ </optional>
|
|||
</element> |
|||
</define> |
|||
|
|||
diff --git a/tests/genericxml2xmlindata/iommufd.xml b/tests/genericxml2xmlindata/iommufd.xml
|
|||
index 63ea839383..10d59ca548 100644
|
|||
--- a/tests/genericxml2xmlindata/iommufd.xml
|
|||
+++ b/tests/genericxml2xmlindata/iommufd.xml
|
|||
@@ -4,7 +4,7 @@
|
|||
<memory unit='KiB'>219136</memory> |
|||
<currentMemory unit='KiB'>219136</currentMemory> |
|||
<vcpu placement='static'>1</vcpu> |
|||
- <iommufd enabled='yes'/>
|
|||
+ <iommufd enabled='yes' fdgroup='iommu'/>
|
|||
<os> |
|||
<type arch='i686' machine='pc'>hvm</type> |
|||
<boot dev='hd'/> |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,218 @@ |
|||
From 28b77cb65fd0eedbd017d97d803256265ce3cbf4 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <28b77cb65fd0eedbd017d97d803256265ce3cbf4.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Fri, 13 Mar 2026 11:57:57 +0100 |
|||
Subject: [PATCH] conf: Introduce domain iommufd element |
|||
|
|||
In addition to configuring IOMMUFD for each host device add |
|||
configuration for the whole VM. This will be extended to add support for |
|||
passing FD to libvirt from management applications. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit c03b8f0804f648a2bbc2eb7e957f2f8821b8e167) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
docs/formatdomain.rst | 21 ++++++++++++ |
|||
src/conf/domain_conf.c | 46 ++++++++++++++++++++++++++ |
|||
src/conf/domain_conf.h | 2 ++ |
|||
src/conf/schemas/domaincommon.rng | 12 +++++++ |
|||
tests/genericxml2xmlindata/iommufd.xml | 18 ++++++++++ |
|||
tests/genericxml2xmltest.c | 2 ++ |
|||
6 files changed, 101 insertions(+) |
|||
create mode 100644 tests/genericxml2xmlindata/iommufd.xml |
|||
|
|||
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
|
|||
index 5ec9a41aac..86b3bad903 100644
|
|||
--- a/docs/formatdomain.rst
|
|||
+++ b/docs/formatdomain.rst
|
|||
@@ -1361,6 +1361,27 @@ Block I/O Tuning
|
|||
``write_iops_sec`` |
|||
Write I/O operations per second limit. :since:`Since 1.2.2` |
|||
|
|||
+Host Device IOMMUFD
|
|||
+-------------------
|
|||
+
|
|||
+::
|
|||
+
|
|||
+ <domain>
|
|||
+ ...
|
|||
+ <iommufd enabled='yes'/>
|
|||
+ ...
|
|||
+ </domain>
|
|||
+
|
|||
+``iommufd``
|
|||
+ :since:`Since 12.2.0 (QEMU/KVM only)` The optional ``iommufd`` element with
|
|||
+ mandatory ``enabled`` attribute can be used to enable IOMMUFD backend for
|
|||
+ VFIO host devices. This provides an interface to propagate DMA mappings to
|
|||
+ kernel for assigned devices. Libvirt will open the /dev/iommu and VFIO device
|
|||
+ cdev and pass associated file descriptors to QEMU.
|
|||
+
|
|||
+ This controls IOMMUFD usage for all host devices, each device can change this
|
|||
+ global default by setting ``iommufd`` attribute for ``driver`` element.
|
|||
+
|
|||
Resource partitioning |
|||
--------------------- |
|||
|
|||
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|||
index 576a1bd79b..1e91561fea 100644
|
|||
--- a/src/conf/domain_conf.c
|
|||
+++ b/src/conf/domain_conf.c
|
|||
@@ -19743,6 +19743,31 @@ virDomainDefControllersParse(virDomainDef *def,
|
|||
return 0; |
|||
} |
|||
|
|||
+static int
|
|||
+virDomainDefIommufdParse(virDomainDef *def,
|
|||
+ xmlXPathContextPtr ctxt)
|
|||
+{
|
|||
+ int n;
|
|||
+ g_autofree xmlNodePtr *nodes = NULL;
|
|||
+
|
|||
+ if ((n = virXPathNodeSet("./iommufd", ctxt, &nodes)) < 0)
|
|||
+ return -1;
|
|||
+
|
|||
+ if (n > 1) {
|
|||
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|||
+ _("only one 'iommufd' element is supported"));
|
|||
+ return -1;
|
|||
+ }
|
|||
+
|
|||
+ if (n == 0)
|
|||
+ return 0;
|
|||
+
|
|||
+ if (virXMLPropTristateBool(nodes[0], "enabled", VIR_XML_PROP_REQUIRED, &def->iommufd) < 0)
|
|||
+ return -1;
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
static virDomainDef * |
|||
virDomainDefParseXML(xmlXPathContextPtr ctxt, |
|||
virDomainXMLOption *xmlopt, |
|||
@@ -19821,6 +19846,9 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt,
|
|||
!virDomainIOThreadIDArrayHasPin(def)) |
|||
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO; |
|||
|
|||
+ if (virDomainDefIommufdParse(def, ctxt) < 0)
|
|||
+ return NULL;
|
|||
+
|
|||
if ((n = virXPathNodeSet("./resource", ctxt, &nodes)) < 0) |
|||
return NULL; |
|||
|
|||
@@ -27958,6 +27986,22 @@ virDomainHubDefFormat(virBuffer *buf,
|
|||
} |
|||
|
|||
|
|||
+static void
|
|||
+virDomainDefIommufdFormat(virBuffer *buf,
|
|||
+ virDomainDef *def)
|
|||
+{
|
|||
+ g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
|
|||
+
|
|||
+ if (def->iommufd == VIR_TRISTATE_BOOL_ABSENT)
|
|||
+ return;
|
|||
+
|
|||
+ virBufferAsprintf(&attrBuf, " enabled='%s'",
|
|||
+ virTristateBoolTypeToString(def->iommufd));
|
|||
+
|
|||
+ virXMLFormatElement(buf, "iommufd", &attrBuf, NULL);
|
|||
+}
|
|||
+
|
|||
+
|
|||
static void |
|||
virDomainResourceDefFormat(virBuffer *buf, |
|||
virDomainResourceDef *def) |
|||
@@ -29482,6 +29526,8 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
|
|||
if (virDomainNumatuneFormatXML(buf, def->numa) < 0) |
|||
return -1; |
|||
|
|||
+ virDomainDefIommufdFormat(buf, def);
|
|||
+
|
|||
virDomainResourceDefFormat(buf, def->resource); |
|||
|
|||
for (i = 0; i < def->nsysinfo; i++) { |
|||
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
|||
index f1c8478208..e12064a3ab 100644
|
|||
--- a/src/conf/domain_conf.h
|
|||
+++ b/src/conf/domain_conf.h
|
|||
@@ -3231,6 +3231,8 @@ struct _virDomainDef {
|
|||
virTristateSwitch apic_eoi; |
|||
virDomainFeatureTCG *tcg_features; |
|||
|
|||
+ virTristateBool iommufd;
|
|||
+
|
|||
bool tseg_specified; |
|||
unsigned long long tseg_size; |
|||
|
|||
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
|
|||
index afdf7bfc1a..81b57a937a 100644
|
|||
--- a/src/conf/schemas/domaincommon.rng
|
|||
+++ b/src/conf/schemas/domaincommon.rng
|
|||
@@ -1001,6 +1001,10 @@
|
|||
<ref name="numatune"/> |
|||
</optional> |
|||
|
|||
+ <optional>
|
|||
+ <ref name="iommufd"/>
|
|||
+ </optional>
|
|||
+
|
|||
<optional> |
|||
<ref name="respartition"/> |
|||
</optional> |
|||
@@ -1344,6 +1348,14 @@
|
|||
</element> |
|||
</define> |
|||
|
|||
+ <define name="iommufd">
|
|||
+ <element name="iommufd">
|
|||
+ <attribute name="enabled">
|
|||
+ <ref name="virYesNo"/>
|
|||
+ </attribute>
|
|||
+ </element>
|
|||
+ </define>
|
|||
+
|
|||
<define name="respartition"> |
|||
<element name="resource"> |
|||
<optional> |
|||
diff --git a/tests/genericxml2xmlindata/iommufd.xml b/tests/genericxml2xmlindata/iommufd.xml
|
|||
new file mode 100644 |
|||
index 0000000000..63ea839383
|
|||
--- /dev/null
|
|||
+++ b/tests/genericxml2xmlindata/iommufd.xml
|
|||
@@ -0,0 +1,18 @@
|
|||
+<domain type='kvm'>
|
|||
+ <name>foo</name>
|
|||
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
|||
+ <memory unit='KiB'>219136</memory>
|
|||
+ <currentMemory unit='KiB'>219136</currentMemory>
|
|||
+ <vcpu placement='static'>1</vcpu>
|
|||
+ <iommufd enabled='yes'/>
|
|||
+ <os>
|
|||
+ <type arch='i686' 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>
|
|||
+ </devices>
|
|||
+</domain>
|
|||
diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c
|
|||
index 6757fc44de..6be694cac5 100644
|
|||
--- a/tests/genericxml2xmltest.c
|
|||
+++ b/tests/genericxml2xmltest.c
|
|||
@@ -263,6 +263,8 @@ mymain(void)
|
|||
|
|||
DO_TEST("iothreadids"); |
|||
|
|||
+ DO_TEST("iommufd");
|
|||
+
|
|||
virObjectUnref(caps); |
|||
virObjectUnref(xmlopt); |
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,330 @@ |
|||
From 15b1edcb2dca52b4d2276359c1eeaa97d66ac400 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <15b1edcb2dca52b4d2276359c1eeaa97d66ac400.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Fri, 13 Mar 2026 16:59:01 +0100 |
|||
Subject: [PATCH] conf: Move and rename virStorageSourceFDTuple object |
|||
|
|||
Associating FD can be used by other parts of VM so rename it to generic |
|||
virDomainFDTuple. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit f89e3dbce809f64246a8fe5ef0d05a63a28a05c0) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/conf/meson.build | 1 + |
|||
src/conf/storage_source_conf.c | 42 --------------------------- |
|||
src/conf/storage_source_conf.h | 24 ++-------------- |
|||
src/conf/virdomainfd.c | 52 ++++++++++++++++++++++++++++++++++ |
|||
src/conf/virdomainfd.h | 27 ++++++++++++++++++ |
|||
src/libvirt_private.syms | 5 +++- |
|||
src/qemu/qemu_backup.c | 2 +- |
|||
src/qemu/qemu_domain.c | 2 +- |
|||
src/qemu/qemu_driver.c | 6 ++-- |
|||
tests/testutilsqemu.c | 2 +- |
|||
10 files changed, 92 insertions(+), 71 deletions(-) |
|||
create mode 100644 src/conf/virdomainfd.c |
|||
create mode 100644 src/conf/virdomainfd.h |
|||
|
|||
diff --git a/src/conf/meson.build b/src/conf/meson.build
|
|||
index 5116c23fe3..6f95b23cce 100644
|
|||
--- a/src/conf/meson.build
|
|||
+++ b/src/conf/meson.build
|
|||
@@ -20,6 +20,7 @@ domain_conf_sources = [
|
|||
'numa_conf.c', |
|||
'snapshot_conf.c', |
|||
'virdomaincheckpointobjlist.c', |
|||
+ 'virdomainfd.c',
|
|||
'virdomainjob.c', |
|||
'virdomainmomentobjlist.c', |
|||
'virdomainobjlist.c', |
|||
diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c
|
|||
index 24d4b0de6a..493b1411b3 100644
|
|||
--- a/src/conf/storage_source_conf.c
|
|||
+++ b/src/conf/storage_source_conf.c
|
|||
@@ -1413,48 +1413,6 @@ virStorageSourceInitiatorClear(virStorageSourceInitiatorDef *initiator)
|
|||
VIR_FREE(initiator->iqn); |
|||
} |
|||
|
|||
-G_DEFINE_TYPE(virStorageSourceFDTuple, vir_storage_source_fd_tuple, G_TYPE_OBJECT);
|
|||
-
|
|||
-static void
|
|||
-vir_storage_source_fd_tuple_init(virStorageSourceFDTuple *fdt G_GNUC_UNUSED)
|
|||
-{
|
|||
-}
|
|||
-
|
|||
-
|
|||
-static void
|
|||
-virStorageSourceFDTupleFinalize(GObject *object)
|
|||
-{
|
|||
- virStorageSourceFDTuple *fdt = VIR_STORAGE_SOURCE_FD_TUPLE(object);
|
|||
- size_t i;
|
|||
-
|
|||
- if (!fdt)
|
|||
- return;
|
|||
-
|
|||
- for (i = 0; i < fdt->nfds; i++)
|
|||
- VIR_FORCE_CLOSE(fdt->fds[i]);
|
|||
-
|
|||
- g_free(fdt->fds);
|
|||
- g_free(fdt->testfds);
|
|||
- g_free(fdt->selinuxLabel);
|
|||
- G_OBJECT_CLASS(vir_storage_source_fd_tuple_parent_class)->finalize(object);
|
|||
-}
|
|||
-
|
|||
-
|
|||
-static void
|
|||
-vir_storage_source_fd_tuple_class_init(virStorageSourceFDTupleClass *klass)
|
|||
-{
|
|||
- GObjectClass *obj = G_OBJECT_CLASS(klass);
|
|||
-
|
|||
- obj->finalize = virStorageSourceFDTupleFinalize;
|
|||
-}
|
|||
-
|
|||
-
|
|||
-virStorageSourceFDTuple *
|
|||
-virStorageSourceFDTupleNew(void)
|
|||
-{
|
|||
- return g_object_new(vir_storage_source_fd_tuple_get_type(), NULL);
|
|||
-}
|
|||
-
|
|||
|
|||
/** |
|||
* virStorageSourceNetworkProtocolPathSplit: |
|||
diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h
|
|||
index 5a4b088eeb..b47313bae5 100644
|
|||
--- a/src/conf/storage_source_conf.h
|
|||
+++ b/src/conf/storage_source_conf.h
|
|||
@@ -24,6 +24,7 @@
|
|||
#include "storage_encryption_conf.h" |
|||
#include "virbitmap.h" |
|||
#include "virconftypes.h" |
|||
+#include "virdomainfd.h"
|
|||
#include "virenum.h" |
|||
#include "virobject.h" |
|||
#include "virpci.h" |
|||
@@ -268,27 +269,6 @@ struct _virStorageSourceSlice {
|
|||
void |
|||
virStorageSourceSliceFree(virStorageSourceSlice *slice); |
|||
|
|||
-struct _virStorageSourceFDTuple {
|
|||
- GObject parent;
|
|||
- int *fds;
|
|||
- size_t nfds;
|
|||
- int *testfds; /* populated by tests to ensure stable FDs */
|
|||
-
|
|||
- bool writable;
|
|||
- bool tryRestoreLabel;
|
|||
-
|
|||
- /* connection this FD tuple is associated with for auto-closing */
|
|||
- virConnect *conn;
|
|||
-
|
|||
- /* original selinux label when we relabel the image */
|
|||
- char *selinuxLabel;
|
|||
-};
|
|||
-G_DECLARE_FINAL_TYPE(virStorageSourceFDTuple, vir_storage_source_fd_tuple, VIR, STORAGE_SOURCE_FD_TUPLE, GObject);
|
|||
-
|
|||
-virStorageSourceFDTuple *
|
|||
-virStorageSourceFDTupleNew(void);
|
|||
-
|
|||
-
|
|||
typedef struct _virStorageSource virStorageSource; |
|||
|
|||
/* Stores information related to a host resource. In the case of backing |
|||
@@ -441,7 +421,7 @@ struct _virStorageSource {
|
|||
* one event for it */ |
|||
bool thresholdEventWithIndex; |
|||
|
|||
- virStorageSourceFDTuple *fdtuple;
|
|||
+ virDomainFDTuple *fdtuple;
|
|||
|
|||
/* Setting 'seclabelSkipRemember' to true will cause the security driver to |
|||
* not remember the security label even if it otherwise were to be |
|||
diff --git a/src/conf/virdomainfd.c b/src/conf/virdomainfd.c
|
|||
new file mode 100644 |
|||
index 0000000000..13c3161e6a
|
|||
--- /dev/null
|
|||
+++ b/src/conf/virdomainfd.c
|
|||
@@ -0,0 +1,52 @@
|
|||
+/*
|
|||
+ * SPDX-License-Identifier: LGPL-2.1-or-later
|
|||
+ */
|
|||
+
|
|||
+#include <config.h>
|
|||
+
|
|||
+#include "virdomainfd.h"
|
|||
+
|
|||
+#include "virfile.h"
|
|||
+
|
|||
+G_DEFINE_TYPE(virDomainFDTuple, vir_domain_fd_tuple, G_TYPE_OBJECT);
|
|||
+
|
|||
+
|
|||
+static void
|
|||
+vir_domain_fd_tuple_init(virDomainFDTuple *fdt G_GNUC_UNUSED)
|
|||
+{
|
|||
+}
|
|||
+
|
|||
+
|
|||
+static void
|
|||
+virDomainFDTupleFinalize(GObject *object)
|
|||
+{
|
|||
+ virDomainFDTuple *fdt = VIR_DOMAIN_FD_TUPLE(object);
|
|||
+ size_t i;
|
|||
+
|
|||
+ if (!fdt)
|
|||
+ return;
|
|||
+
|
|||
+ for (i = 0; i < fdt->nfds; i++)
|
|||
+ VIR_FORCE_CLOSE(fdt->fds[i]);
|
|||
+
|
|||
+ g_free(fdt->fds);
|
|||
+ g_free(fdt->testfds);
|
|||
+ g_free(fdt->selinuxLabel);
|
|||
+ G_OBJECT_CLASS(vir_domain_fd_tuple_parent_class)->finalize(object);
|
|||
+}
|
|||
+
|
|||
+
|
|||
+static void
|
|||
+vir_domain_fd_tuple_class_init(virDomainFDTupleClass *klass)
|
|||
+{
|
|||
+ GObjectClass *obj = G_OBJECT_CLASS(klass);
|
|||
+
|
|||
+ obj->finalize = virDomainFDTupleFinalize;
|
|||
+}
|
|||
+
|
|||
+
|
|||
+virDomainFDTuple *
|
|||
+virDomainFDTupleNew(void)
|
|||
+{
|
|||
+ return g_object_new(vir_domain_fd_tuple_get_type(), NULL);
|
|||
+}
|
|||
diff --git a/src/conf/virdomainfd.h b/src/conf/virdomainfd.h
|
|||
new file mode 100644 |
|||
index 0000000000..0c0d475ed6
|
|||
--- /dev/null
|
|||
+++ b/src/conf/virdomainfd.h
|
|||
@@ -0,0 +1,27 @@
|
|||
+/*
|
|||
+ * SPDX-License-Identifier: LGPL-2.1-or-later
|
|||
+ */
|
|||
+
|
|||
+#pragma once
|
|||
+
|
|||
+#include "internal.h"
|
|||
+
|
|||
+struct _virDomainFDTuple {
|
|||
+ GObject parent;
|
|||
+ int *fds;
|
|||
+ size_t nfds;
|
|||
+ int *testfds; /* populated by tests to ensure stable FDs */
|
|||
+
|
|||
+ bool writable;
|
|||
+ bool tryRestoreLabel;
|
|||
+
|
|||
+ /* connection this FD tuple is associated with for auto-closing */
|
|||
+ virConnect *conn;
|
|||
+
|
|||
+ /* original selinux label when we relabel the image */
|
|||
+ char *selinuxLabel;
|
|||
+};
|
|||
+G_DECLARE_FINAL_TYPE(virDomainFDTuple, vir_domain_fd_tuple, VIR, DOMAIN_FD_TUPLE, GObject);
|
|||
+
|
|||
+virDomainFDTuple *
|
|||
+virDomainFDTupleNew(void);
|
|||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|||
index effe44fe57..386e757d81 100644
|
|||
--- a/src/libvirt_private.syms
|
|||
+++ b/src/libvirt_private.syms
|
|||
@@ -1177,7 +1177,6 @@ virStorageSourceChainHasManagedPR;
|
|||
virStorageSourceChainHasNVMe; |
|||
virStorageSourceClear; |
|||
virStorageSourceCopy; |
|||
-virStorageSourceFDTupleNew;
|
|||
virStorageSourceGetActualType; |
|||
virStorageSourceGetSecurityLabelDef; |
|||
virStorageSourceHasBacking; |
|||
@@ -1230,6 +1229,10 @@ virDomainCheckpointUpdateRelations;
|
|||
virDomainListCheckpoints; |
|||
|
|||
|
|||
+# conf/virdomainfd.h
|
|||
+virDomainFDTupleNew;
|
|||
+
|
|||
+
|
|||
#conf/virdomainjob.h |
|||
virDomainAgentJobTypeToString; |
|||
virDomainAsyncJobTypeFromString; |
|||
diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
|
|||
index c3566bcd57..eebf6cdc06 100644
|
|||
--- a/src/qemu/qemu_backup.c
|
|||
+++ b/src/qemu/qemu_backup.c
|
|||
@@ -876,7 +876,7 @@ qemuBackupBegin(virDomainObj *vm,
|
|||
priv->backup = g_steal_pointer(&def); |
|||
|
|||
if (pull && priv->backup->server->fdgroup) { |
|||
- virStorageSourceFDTuple *fdt = NULL;
|
|||
+ virDomainFDTuple *fdt = NULL;
|
|||
VIR_AUTOCLOSE fdcopy = -1; |
|||
|
|||
if (!(fdt = virHashLookup(priv->fds, priv->backup->server->fdgroup))) { |
|||
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|||
index ccbfc8bac7..5c9f4831fd 100644
|
|||
--- a/src/qemu/qemu_domain.c
|
|||
+++ b/src/qemu/qemu_domain.c
|
|||
@@ -9835,7 +9835,7 @@ qemuDomainPrepareStorageSourceFDs(virStorageSource *src,
|
|||
{ |
|||
qemuDomainStorageSourcePrivate *srcpriv = NULL; |
|||
virStorageType actualType = virStorageSourceGetActualType(src); |
|||
- virStorageSourceFDTuple *fdt = NULL;
|
|||
+ virDomainFDTuple *fdt = NULL;
|
|||
size_t i; |
|||
|
|||
if (actualType != VIR_STORAGE_TYPE_FILE && |
|||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|||
index ecd19663ce..8db9cbb6a2 100644
|
|||
--- a/src/qemu/qemu_driver.c
|
|||
+++ b/src/qemu/qemu_driver.c
|
|||
@@ -20241,7 +20241,7 @@ qemuDomainFDHashCloseConnect(virDomainObj *vm,
|
|||
virConnectPtr conn) |
|||
{ |
|||
qemuDomainObjPrivate *priv = QEMU_DOMAIN_PRIVATE(vm); |
|||
- virStorageSourceFDTuple *data;
|
|||
+ virDomainFDTuple *data;
|
|||
GHashTableIter htitr; |
|||
|
|||
if (!priv->fds) |
|||
@@ -20265,7 +20265,7 @@ qemuDomainFDAssociate(virDomainPtr domain,
|
|||
{ |
|||
virDomainObj *vm = NULL; |
|||
qemuDomainObjPrivate *priv; |
|||
- g_autoptr(virStorageSourceFDTuple) new = NULL;
|
|||
+ g_autoptr(virDomainFDTuple) new = NULL;
|
|||
size_t i; |
|||
int ret = -1; |
|||
|
|||
@@ -20283,7 +20283,7 @@ qemuDomainFDAssociate(virDomainPtr domain,
|
|||
|
|||
priv = vm->privateData; |
|||
|
|||
- new = virStorageSourceFDTupleNew();
|
|||
+ new = virDomainFDTupleNew();
|
|||
new->nfds = nfds; |
|||
new->fds = g_new0(int, new->nfds); |
|||
for (i = 0; i < new->nfds; i++) { |
|||
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
|
|||
index 78ec521266..fc51e0e3df 100644
|
|||
--- a/tests/testutilsqemu.c
|
|||
+++ b/tests/testutilsqemu.c
|
|||
@@ -713,7 +713,7 @@ testQemuInfoSetArgs(testQemuInfo *info,
|
|||
break; |
|||
|
|||
case ARG_FD_GROUP: { |
|||
- virStorageSourceFDTuple *new = virStorageSourceFDTupleNew();
|
|||
+ virDomainFDTuple *new = virDomainFDTupleNew();
|
|||
const char *fdname = va_arg(argptr, char *); |
|||
VIR_AUTOCLOSE fakefd = open("/dev/zero", O_RDWR); |
|||
bool writable = va_arg(argptr, int); |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,113 @@ |
|||
From b60749c749a3312148c72471b99bd76469a6aff2 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <b60749c749a3312148c72471b99bd76469a6aff2.1780571166.git.jdenemar@redhat.com> |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Wed, 11 Feb 2026 10:16:28 +0100 |
|||
Subject: [PATCH] conf: Parse hyperv features even for host-model |
|||
|
|||
As it turns out, some users of the hyperv "host-model" mode might |
|||
want to override the hypervisor defaults. For instance disable a |
|||
feature that's on by default, or vice versa. Currently, this is |
|||
not possible because as soon as our XML parser sees the |
|||
"host-model" mode it exits early and skips parsing of individual |
|||
features (for "custom" mode). Well, do not return early and parse |
|||
the rest. |
|||
|
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 380fb8939009a420f598175e63994a5bf197fd56) |
|||
Resolves: https://issues.redhat.com/browse/RHEL-151688 |
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
---
|
|||
docs/formatdomain.rst | 3 +++ |
|||
src/conf/domain_conf.c | 3 +-- |
|||
src/conf/schemas/domaincommon.rng | 8 ++++---- |
|||
tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml | 6 +++++- |
|||
tests/qemuxmlconfdata/hyperv-host-model.xml | 6 +++++- |
|||
5 files changed, 18 insertions(+), 8 deletions(-) |
|||
|
|||
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
|
|||
index 31232deb3c..5ec9a41aac 100644
|
|||
--- a/docs/formatdomain.rst
|
|||
+++ b/docs/formatdomain.rst
|
|||
@@ -2197,6 +2197,9 @@ are:
|
|||
enlightenments are supported by hypervisor and expands them on domain |
|||
startup into the live XML. In a sense, this is similar to ``host-model`` |
|||
CPU mode (See `CPU model and topology`_). :since:`Since 11.9.0` |
|||
+ It is also possible to set features, like in ``custom`` mode. These are
|
|||
+ then left untouched and no expansion is done for them. :since:`Since
|
|||
+ 12.1.0`
|
|||
|
|||
The ``mode`` attribute can be omitted and will default to ``custom``. |
|||
|
|||
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|||
index df05d96f01..1f7b1ca340 100644
|
|||
--- a/src/conf/domain_conf.c
|
|||
+++ b/src/conf/domain_conf.c
|
|||
@@ -17269,8 +17269,7 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
|
|||
|
|||
def->features[VIR_DOMAIN_FEATURE_HYPERV] = mode; |
|||
|
|||
- if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH ||
|
|||
- mode == VIR_DOMAIN_HYPERV_MODE_HOST_MODEL)
|
|||
+ if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH)
|
|||
return 0; |
|||
|
|||
node = xmlFirstElementChild(node); |
|||
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
|
|||
index 441328a08e..afdf7bfc1a 100644
|
|||
--- a/src/conf/schemas/domaincommon.rng
|
|||
+++ b/src/conf/schemas/domaincommon.rng
|
|||
@@ -8063,13 +8063,13 @@
|
|||
<attribute name="mode"> |
|||
<value>passthrough</value> |
|||
</attribute> |
|||
- <attribute name="mode">
|
|||
- <value>host-model</value>
|
|||
- </attribute>
|
|||
<group> |
|||
<optional> |
|||
<attribute name="mode"> |
|||
- <value>custom</value>
|
|||
+ <choice>
|
|||
+ <value>custom</value>
|
|||
+ <value>host-model</value>
|
|||
+ </choice>
|
|||
</attribute> |
|||
</optional> |
|||
<interleave> |
|||
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
|
|||
index 453a43b3c9..9535cee02a 100644
|
|||
--- a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
|
|||
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
|
|||
@@ -10,7 +10,11 @@
|
|||
</os> |
|||
<features> |
|||
<acpi/> |
|||
- <hyperv mode='host-model'/>
|
|||
+ <hyperv mode='host-model'>
|
|||
+ <relaxed state='on'/>
|
|||
+ <spinlocks state='on' retries='8192'/>
|
|||
+ <xmm_input state='off'/>
|
|||
+ </hyperv>
|
|||
</features> |
|||
<cpu mode='custom' match='exact' check='none'> |
|||
<model fallback='forbid'>qemu64</model> |
|||
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.xml b/tests/qemuxmlconfdata/hyperv-host-model.xml
|
|||
index fae00d86dd..473a41892d 100644
|
|||
--- a/tests/qemuxmlconfdata/hyperv-host-model.xml
|
|||
+++ b/tests/qemuxmlconfdata/hyperv-host-model.xml
|
|||
@@ -10,7 +10,11 @@
|
|||
</os> |
|||
<features> |
|||
<acpi/> |
|||
- <hyperv mode='host-model'/>
|
|||
+ <hyperv mode='host-model'>
|
|||
+ <relaxed state='on'/>
|
|||
+ <spinlocks state='on' retries='8192'/>
|
|||
+ <xmm_input state='off'/>
|
|||
+ </hyperv>
|
|||
</features> |
|||
<clock offset='utc'/> |
|||
<on_poweroff>destroy</on_poweroff> |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,80 @@ |
|||
From 7af5a1f92b63d250922e04b56cae67bfb65fa4f4 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <7af5a1f92b63d250922e04b56cae67bfb65fa4f4.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Wed, 18 Mar 2026 11:47:21 +0100 |
|||
Subject: [PATCH] conf: Refactor virHostdevIsPCIDevice |
|||
|
|||
Future patches will need to check if the host device uses IOMMUFD or not |
|||
but we also need to keep a function that will check only if it is PCI device. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit d0afa0a842ce8a6dcb3f881d7dccdf5198f78fa7) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/conf/domain_conf.c | 34 +++++++++++++++++++++++++++++----- |
|||
1 file changed, 29 insertions(+), 5 deletions(-) |
|||
|
|||
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|||
index 35de8bab6b..59df028192 100644
|
|||
--- a/src/conf/domain_conf.c
|
|||
+++ b/src/conf/domain_conf.c
|
|||
@@ -32782,6 +32782,33 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev)
|
|||
} |
|||
|
|||
|
|||
+static bool
|
|||
+virHostdevPCIDevHasIOMMUFD(const virDomainHostdevDef *hostdev)
|
|||
+{
|
|||
+ return hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO &&
|
|||
+ hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES;
|
|||
+}
|
|||
+
|
|||
+
|
|||
+static bool
|
|||
+virHostdevIsPCIDeviceImpl(const virDomainHostdevDef *hostdev,
|
|||
+ virTristateBool iommufd)
|
|||
+{
|
|||
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
|||
+ return false;
|
|||
+
|
|||
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
|
|||
+ return false;
|
|||
+
|
|||
+ if (iommufd != VIR_TRISTATE_BOOL_ABSENT) {
|
|||
+ bool hasIOMMUFD = iommufd == VIR_TRISTATE_BOOL_YES;
|
|||
+ return hasIOMMUFD == virHostdevPCIDevHasIOMMUFD(hostdev);
|
|||
+ }
|
|||
+
|
|||
+ return true;
|
|||
+}
|
|||
+
|
|||
+
|
|||
/** |
|||
* virHostdevIsPCIDevice: |
|||
* @hostdev: host device to check |
|||
@@ -32791,8 +32818,7 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev)
|
|||
bool |
|||
virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev) |
|||
{ |
|||
- return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
|
|||
- hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
|
|||
+ return virHostdevIsPCIDeviceImpl(hostdev, VIR_TRISTATE_BOOL_ABSENT);
|
|||
} |
|||
|
|||
|
|||
@@ -32805,9 +32831,7 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
|
|||
bool |
|||
virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev) |
|||
{ |
|||
- return virHostdevIsPCIDevice(hostdev) &&
|
|||
- hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO &&
|
|||
- hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES;
|
|||
+ return virHostdevIsPCIDeviceImpl(hostdev, VIR_TRISTATE_BOOL_YES);
|
|||
} |
|||
|
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,158 @@ |
|||
From 353e7eb26cb922bd342c050273afbcc4ed4dd20e Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <353e7eb26cb922bd342c050273afbcc4ed4dd20e.1780571167.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Mon, 25 May 2026 14:22:58 +0200 |
|||
Subject: [PATCH] cpu: Introduce virCPUUpdateFeatures |
|||
|
|||
This new API can be used to update an existing CPU definition with |
|||
features described by CPU data. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 6be1be4938338477bff14ff24c7ed2a05bc1dadc) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/cpu/cpu.c | 34 ++++++++++++++++++++++++++++++++++ |
|||
src/cpu/cpu.h | 12 ++++++++++++ |
|||
src/cpu/cpu_x86.c | 23 +++++++++++++++++++++++ |
|||
src/libvirt_private.syms | 1 + |
|||
4 files changed, 70 insertions(+) |
|||
|
|||
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
|
|||
index d81e620a1d..3e9affa1cd 100644
|
|||
--- a/src/cpu/cpu.c
|
|||
+++ b/src/cpu/cpu.c
|
|||
@@ -1359,6 +1359,40 @@ virCPUGetCanonicalModel(virArch arch,
|
|||
} |
|||
|
|||
|
|||
+/** virCPUUpdateFeatures:
|
|||
+ *
|
|||
+ * @arch: CPU architecture
|
|||
+ * @cpu: CPU definition to update
|
|||
+ * @cpuData: CPU data describing features
|
|||
+ * @policy: to be used by the updated features
|
|||
+ *
|
|||
+ * Updates features described in @cpuData to use the specified @policy. Missing
|
|||
+ * features will be automatically added to the CPU definition.
|
|||
+ *
|
|||
+ * Returns 0 on success, -1 otherwise.
|
|||
+ */
|
|||
+int
|
|||
+virCPUUpdateFeatures(virArch arch,
|
|||
+ virCPUDef *cpu,
|
|||
+ virCPUData *cpuData,
|
|||
+ virCPUFeaturePolicy policy)
|
|||
+{
|
|||
+ struct cpuArchDriver *driver;
|
|||
+
|
|||
+ VIR_DEBUG("arch=%s, cpu=%p, model=%s, policy=%s",
|
|||
+ virArchToString(arch), cpu, NULLSTR(cpu->model),
|
|||
+ virCPUFeaturePolicyTypeToString(policy));
|
|||
+
|
|||
+ if (!(driver = cpuGetSubDriver(arch)))
|
|||
+ return -1;
|
|||
+
|
|||
+ if (!driver->updateFeatures)
|
|||
+ return 0;
|
|||
+
|
|||
+ return driver->updateFeatures(cpu, cpuData, policy);
|
|||
+}
|
|||
+
|
|||
+
|
|||
/** |
|||
* virCPUArchIsSupported: |
|||
* |
|||
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
|
|||
index 36fd123675..65711ac085 100644
|
|||
--- a/src/cpu/cpu.h
|
|||
+++ b/src/cpu/cpu.h
|
|||
@@ -143,6 +143,11 @@ typedef int
|
|||
typedef const char * |
|||
(*virCPUArchGetCanonicalModel)(const char *model); |
|||
|
|||
+typedef int
|
|||
+(*virCPUArchUpdateFeatures)(virCPUDef *cpu,
|
|||
+ virCPUData *cpuData,
|
|||
+ virCPUFeaturePolicy policy);
|
|||
+
|
|||
struct cpuArchDriver { |
|||
const char *name; |
|||
const virArch *arch; |
|||
@@ -172,6 +177,7 @@ struct cpuArchDriver {
|
|||
virCPUArchDataGetHost dataGetHost; |
|||
virCPUArchGetCheckMode getCheckMode; |
|||
virCPUArchGetCanonicalModel getCanonicalModel; |
|||
+ virCPUArchUpdateFeatures updateFeatures;
|
|||
}; |
|||
|
|||
|
|||
@@ -332,6 +338,12 @@ const char *
|
|||
virCPUGetCanonicalModel(virArch arch, |
|||
const char *model); |
|||
|
|||
+int
|
|||
+virCPUUpdateFeatures(virArch arch,
|
|||
+ virCPUDef *cpu,
|
|||
+ virCPUData *cpuData,
|
|||
+ virCPUFeaturePolicy policy);
|
|||
+
|
|||
bool |
|||
virCPUArchIsSupported(virArch arch); |
|||
|
|||
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
|
|||
index e5825fbb4d..6e860de458 100644
|
|||
--- a/src/cpu/cpu_x86.c
|
|||
+++ b/src/cpu/cpu_x86.c
|
|||
@@ -3790,6 +3790,28 @@ virCPUx86GetCanonicalModel(const char *modelName)
|
|||
} |
|||
|
|||
|
|||
+static int
|
|||
+virCPUx86UpdateFeatures(virCPUDef *cpu,
|
|||
+ virCPUData *cpuData,
|
|||
+ virCPUFeaturePolicy policy)
|
|||
+{
|
|||
+ virCPUx86Data *data = &cpuData->data.x86;
|
|||
+ virCPUx86Map *map;
|
|||
+ size_t i;
|
|||
+
|
|||
+ if (!(map = virCPUx86GetMap()))
|
|||
+ return -1;
|
|||
+
|
|||
+ for (i = 0; i < map->nfeatures; i++) {
|
|||
+ virCPUx86Feature *feature = map->features[i];
|
|||
+ if (x86DataIsSubset(data, &feature->data))
|
|||
+ virCPUDefUpdateFeature(cpu, feature->name, policy);
|
|||
+ }
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+
|
|||
struct cpuArchDriver cpuDriverX86 = { |
|||
.name = "x86", |
|||
.arch = archs, |
|||
@@ -3824,4 +3846,5 @@ struct cpuArchDriver cpuDriverX86 = {
|
|||
#endif |
|||
.getCheckMode = virCPUx86GetCheckMode, |
|||
.getCanonicalModel = virCPUx86GetCanonicalModel, |
|||
+ .updateFeatures = virCPUx86UpdateFeatures,
|
|||
}; |
|||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|||
index 3eb6943440..4a0f9065fa 100644
|
|||
--- a/src/libvirt_private.syms
|
|||
+++ b/src/libvirt_private.syms
|
|||
@@ -1586,6 +1586,7 @@ virCPUGetVendorForModel;
|
|||
virCPUProbeHost; |
|||
virCPUTranslate; |
|||
virCPUUpdate; |
|||
+virCPUUpdateFeatures;
|
|||
virCPUUpdateLive; |
|||
virCPUValidateFeatures; |
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,109 @@ |
|||
From 6a2bd2d2e74d8c07266558c62d3fb724e677e256 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <6a2bd2d2e74d8c07266558c62d3fb724e677e256.1780571166.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Fri, 29 May 2026 13:00:10 +0200 |
|||
Subject: [PATCH] cpu_conf: Introduce virCPUDefSortFeatures |
|||
|
|||
Separate the sorting code from virCPUExpandFeatures into a standalone |
|||
function. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 0900cc4f2dca2c17e8854330d45dffa4cc7952c4) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/conf/cpu_conf.c | 20 ++++++++++++++++++++ |
|||
src/conf/cpu_conf.h | 3 +++ |
|||
src/cpu/cpu.c | 15 +-------------- |
|||
src/libvirt_private.syms | 1 + |
|||
4 files changed, 25 insertions(+), 14 deletions(-) |
|||
|
|||
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
|
|||
index 7aeedf64f5..f5a2004ee6 100644
|
|||
--- a/src/conf/cpu_conf.c
|
|||
+++ b/src/conf/cpu_conf.c
|
|||
@@ -1277,3 +1277,23 @@ virCPUDefListFree(virCPUDef **cpus)
|
|||
|
|||
g_free(cpus); |
|||
} |
|||
+
|
|||
+
|
|||
+static int
|
|||
+virCPUFeatureDefCompare(const void *p1,
|
|||
+ const void *p2,
|
|||
+ void *opaque G_GNUC_UNUSED)
|
|||
+{
|
|||
+ const virCPUFeatureDef *f1 = p1;
|
|||
+ const virCPUFeatureDef *f2 = p2;
|
|||
+
|
|||
+ return strcmp(f1->name, f2->name);
|
|||
+}
|
|||
+
|
|||
+
|
|||
+void
|
|||
+virCPUDefSortFeatures(virCPUDef *cpu)
|
|||
+{
|
|||
+ g_qsort_with_data(cpu->features, cpu->nfeatures, sizeof(*cpu->features),
|
|||
+ virCPUFeatureDefCompare, NULL);
|
|||
+}
|
|||
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
|
|||
index cfb8f1a461..0cac1a1489 100644
|
|||
--- a/src/conf/cpu_conf.h
|
|||
+++ b/src/conf/cpu_conf.h
|
|||
@@ -280,3 +280,6 @@ virCPUDefListParse(const char **xmlCPUs,
|
|||
virCPUType cpuType); |
|||
void |
|||
virCPUDefListFree(virCPUDef **cpus); |
|||
+
|
|||
+void
|
|||
+virCPUDefSortFeatures(virCPUDef *cpu);
|
|||
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
|
|||
index 233686485d..d81e620a1d 100644
|
|||
--- a/src/cpu/cpu.c
|
|||
+++ b/src/cpu/cpu.c
|
|||
@@ -1125,18 +1125,6 @@ virCPUConvertLegacy(virArch arch,
|
|||
} |
|||
|
|||
|
|||
-static int
|
|||
-virCPUFeatureCompare(const void *p1,
|
|||
- const void *p2,
|
|||
- void *opaque G_GNUC_UNUSED)
|
|||
-{
|
|||
- const virCPUFeatureDef *f1 = p1;
|
|||
- const virCPUFeatureDef *f2 = p2;
|
|||
-
|
|||
- return strcmp(f1->name, f2->name);
|
|||
-}
|
|||
-
|
|||
-
|
|||
/** |
|||
* virCPUExpandFeatures: |
|||
* |
|||
@@ -1168,8 +1156,7 @@ virCPUExpandFeatures(virArch arch,
|
|||
driver->expandFeatures(cpu) < 0) |
|||
return -1; |
|||
|
|||
- g_qsort_with_data(cpu->features, cpu->nfeatures, sizeof(*cpu->features),
|
|||
- virCPUFeatureCompare, NULL);
|
|||
+ virCPUDefSortFeatures(cpu);
|
|||
|
|||
VIR_DEBUG("nfeatures=%zu", cpu->nfeatures); |
|||
return 0; |
|||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|||
index d2563e587a..1733286bad 100644
|
|||
--- a/src/libvirt_private.syms
|
|||
+++ b/src/libvirt_private.syms
|
|||
@@ -118,6 +118,7 @@ virCPUDefNew;
|
|||
virCPUDefParseXML; |
|||
virCPUDefParseXMLString; |
|||
virCPUDefRef; |
|||
+virCPUDefSortFeatures;
|
|||
virCPUDefStealModel; |
|||
virCPUDefUpdateFeature; |
|||
virCPUMaxPhysAddrModeTypeFromString; |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,109 @@ |
|||
From d34cc77ac31f6df5195dad6b53d5aed00bda7dd7 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <d34cc77ac31f6df5195dad6b53d5aed00bda7dd7.1780571167.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Mon, 25 May 2026 13:17:47 +0200 |
|||
Subject: [PATCH] cpu_x86: Introduce virCPUx86DataAddMSR |
|||
|
|||
This just makes the relevant part of virCPUx86GetHost reusable in other |
|||
places. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit a8952076d8e5062a2fac08e11597ad47871c2236) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/cpu/cpu_x86.c | 40 ++++++++++++++++++++++++++++------------ |
|||
src/cpu/cpu_x86.h | 4 ++++ |
|||
src/libvirt_private.syms | 1 + |
|||
3 files changed, 33 insertions(+), 12 deletions(-) |
|||
|
|||
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
|
|||
index 0f7eb8f48b..e5825fbb4d 100644
|
|||
--- a/src/cpu/cpu_x86.c
|
|||
+++ b/src/cpu/cpu_x86.c
|
|||
@@ -2912,18 +2912,8 @@ virCPUx86GetHost(virCPUDef *cpu,
|
|||
/* This is best effort since there might be no way to read the MSR |
|||
* when we are not running as root. */ |
|||
for (i = 0; i < nmsrs; i++) { |
|||
- if (virHostCPUGetMSR(msrs[i], &msr) == 0) {
|
|||
- virCPUx86DataItem item = {
|
|||
- .type = VIR_CPU_X86_DATA_MSR,
|
|||
- .data.msr = {
|
|||
- .index = msrs[i],
|
|||
- .eax = msr & 0xffffffff,
|
|||
- .edx = msr >> 32,
|
|||
- },
|
|||
- };
|
|||
-
|
|||
- virCPUx86DataAdd(cpuData, &item);
|
|||
- }
|
|||
+ if (virHostCPUGetMSR(msrs[i], &msr) == 0)
|
|||
+ virCPUx86DataAddMSR(cpuData, msrs[i], msr);
|
|||
} |
|||
|
|||
ret = x86DecodeCPUData(cpu, cpuData, models); |
|||
@@ -3461,6 +3451,32 @@ virCPUx86DataAdd(virCPUData *cpuData,
|
|||
} |
|||
|
|||
|
|||
+/**
|
|||
+ * virCPUx86DataAddMSR:
|
|||
+ * @cpuData: CPU data to update
|
|||
+ * @index: MSR index
|
|||
+ * @value: content of the @index MSR
|
|||
+ *
|
|||
+ * Adds the specified MSR content to CPU data.
|
|||
+ */
|
|||
+void
|
|||
+virCPUx86DataAddMSR(virCPUData *cpuData,
|
|||
+ uint32_t index,
|
|||
+ uint64_t value)
|
|||
+{
|
|||
+ virCPUx86DataItem item = {
|
|||
+ .type = VIR_CPU_X86_DATA_MSR,
|
|||
+ .data.msr = {
|
|||
+ .index = index,
|
|||
+ .eax = value & 0xffffffff,
|
|||
+ .edx = value >> 32,
|
|||
+ },
|
|||
+ };
|
|||
+
|
|||
+ virCPUx86DataAdd(cpuData, &item);
|
|||
+}
|
|||
+
|
|||
+
|
|||
void |
|||
virCPUx86DataSetSignature(virCPUData *cpuData, |
|||
unsigned int family, |
|||
diff --git a/src/cpu/cpu_x86.h b/src/cpu/cpu_x86.h
|
|||
index 2cd965fea4..bbc2a16447 100644
|
|||
--- a/src/cpu/cpu_x86.h
|
|||
+++ b/src/cpu/cpu_x86.h
|
|||
@@ -28,6 +28,10 @@ extern struct cpuArchDriver cpuDriverX86;
|
|||
void virCPUx86DataAdd(virCPUData *cpuData, |
|||
const virCPUx86DataItem *cpuid); |
|||
|
|||
+void virCPUx86DataAddMSR(virCPUData *cpuData,
|
|||
+ uint32_t index,
|
|||
+ uint64_t value);
|
|||
+
|
|||
void virCPUx86DataSetSignature(virCPUData *cpuData, |
|||
unsigned int family, |
|||
unsigned int model, |
|||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|||
index 3eca15f066..3eb6943440 100644
|
|||
--- a/src/libvirt_private.syms
|
|||
+++ b/src/libvirt_private.syms
|
|||
@@ -1592,6 +1592,7 @@ virCPUValidateFeatures;
|
|||
|
|||
# cpu/cpu_x86.h |
|||
virCPUx86DataAdd; |
|||
+virCPUx86DataAddMSR;
|
|||
virCPUx86DataGetSignature; |
|||
virCPUx86DataSetSignature; |
|||
virCPUx86DataSetVendor; |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,34 @@ |
|||
From 4c6ab1e34ea5e57dc0f9880f178354538adf55f7 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <4c6ab1e34ea5e57dc0f9880f178354538adf55f7.1780571166.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Wed, 11 Mar 2026 12:13:45 +0100 |
|||
Subject: [PATCH] docs: Clarify host-model description in domain capabilities |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 0b54c9d535b9b7c832ff8422dca28c84eb75ed2e) |
|||
|
|||
https://issues.redhat.com/browse/RHEL-153653 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
docs/formatdomaincaps.rst | 4 ++++ |
|||
1 file changed, 4 insertions(+) |
|||
|
|||
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
|
|||
index 6ba7f84f96..add550a4a5 100644
|
|||
--- a/docs/formatdomaincaps.rst
|
|||
+++ b/docs/formatdomaincaps.rst
|
|||
@@ -244,6 +244,10 @@ more details about it:
|
|||
reports physical address size of the host CPU if this value is available and |
|||
applicable for the requested domain type. This is useful for computing |
|||
baseline CPU definition which should be compatible with several hosts. |
|||
+ Consistently with all other CPU definitions used by libvirt, features
|
|||
+ implicitly enabled by the selected CPU model (in ``model`` sub element) are
|
|||
+ not listed. Use ``--expand-cpu-features`` virsh option or the equivalent API
|
|||
+ flag to request all supported features to be listed in the CPU definition.
|
|||
``custom`` |
|||
The ``mode`` element contains a list of supported CPU models, each described |
|||
by a dedicated ``model`` element. The ``usable`` attribute specifies whether |
|||
--
|
|||
2.54.0 |
|||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,45 @@ |
|||
From b338719eb9908c7dfd493d5ab4a1b0bcc2258d9b Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <b338719eb9908c7dfd493d5ab4a1b0bcc2258d9b.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Thu, 26 Mar 2026 14:32:36 +0100 |
|||
Subject: [PATCH] hypervisor: Call virWaitForDevices() after detaching host |
|||
devices |
|||
MIME-Version: 1.0 |
|||
Content-Type: text/plain; charset=UTF-8 |
|||
Content-Transfer-Encoding: 8bit |
|||
|
|||
On systems with selinux enabled starting a VM with managed host device |
|||
using IOMMUFD backend can run into race-condition where both libvirt and |
|||
udev are setting selinux label on /dev/vfio/devices/vfioX device. If |
|||
udev is the last one to set selinux label starting VM fails with: |
|||
|
|||
error: internal error: QEMU unexpectedly closed the monitor (vm='test'): 2026-03-26T15:47:36.620422Z qemu-kvm: -device {"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"20","bus":"pci.7","addr":"0x0"}: vfio hostdev0: Failed to add fd 20 to KVM VFIO device: Invalid argument |
|||
|
|||
We need to wait for udev to finish processing all events. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Ján Tomko <jtomko@redhat.com> |
|||
(cherry picked from commit b96ea4db3aabac4790d6e1d53e2f309f5e73efae) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/hypervisor/virhostdev.c | 3 +++ |
|||
1 file changed, 3 insertions(+) |
|||
|
|||
diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c
|
|||
index 43155ceb6c..981ca4cd20 100644
|
|||
--- a/src/hypervisor/virhostdev.c
|
|||
+++ b/src/hypervisor/virhostdev.c
|
|||
@@ -782,6 +782,9 @@ virHostdevPreparePCIDevicesImpl(virHostdevManager *mgr,
|
|||
} |
|||
} |
|||
|
|||
+ /* Step 2.5: Wait for udev to handle all events for devices. */
|
|||
+ virWaitForDevices();
|
|||
+
|
|||
/* At this point, all devices are attached to the stub driver and have |
|||
* been marked as inactive */ |
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,98 @@ |
|||
From 2f8eef47f391248abf5253c6836520100d5d49c1 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <2f8eef47f391248abf5253c6836520100d5d49c1.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Wed, 18 Mar 2026 11:57:43 +0100 |
|||
Subject: [PATCH] hypervisor: Fix virHostdevNeedsVFIO detection |
|||
|
|||
Function virHostdevNeedsVFIO is used only in QEMU to figure out if the |
|||
host device needs access to /dev/vfio/vfio, for PCI host devices that is |
|||
true only if libvirt is not using IOMMUFD. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit ffa8020d3665f7ff27c6b82e88d3a93674155c8d) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/conf/domain_conf.c | 13 +++++++++++++ |
|||
src/conf/domain_conf.h | 3 +++ |
|||
src/hypervisor/virhostdev.c | 9 ++++++++- |
|||
src/libvirt_private.syms | 1 + |
|||
4 files changed, 25 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|||
index 59df028192..99d2a0aa53 100644
|
|||
--- a/src/conf/domain_conf.c
|
|||
+++ b/src/conf/domain_conf.c
|
|||
@@ -32835,6 +32835,19 @@ virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev)
|
|||
} |
|||
|
|||
|
|||
+/**
|
|||
+ * virHostdevIsPCIDeviceWithIOMMUFD:
|
|||
+ * @hostdev: host device to check
|
|||
+ *
|
|||
+ * Returns true if @hostdev is a PCI device with IOMMUFD disabled, false otherwise.
|
|||
+ */
|
|||
+bool
|
|||
+virHostdevIsPCIDeviceWithoutIOMMUFD(const virDomainHostdevDef *hostdev)
|
|||
+{
|
|||
+ return virHostdevIsPCIDeviceImpl(hostdev, VIR_TRISTATE_BOOL_NO);
|
|||
+}
|
|||
+
|
|||
+
|
|||
static void |
|||
virDomainObjGetMessagesIOErrorsSrc(virStorageSource *src, |
|||
const char *diskdst, |
|||
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
|||
index 69a8e79c6d..8f5780ee4c 100644
|
|||
--- a/src/conf/domain_conf.h
|
|||
+++ b/src/conf/domain_conf.h
|
|||
@@ -4719,6 +4719,9 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
|
|||
bool |
|||
virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev) |
|||
ATTRIBUTE_NONNULL(1); |
|||
+bool
|
|||
+virHostdevIsPCIDeviceWithoutIOMMUFD(const virDomainHostdevDef *hostdev)
|
|||
+ ATTRIBUTE_NONNULL(1);
|
|||
|
|||
void |
|||
virDomainObjGetMessagesIOErrorsChain(virStorageSource *src, |
|||
diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c
|
|||
index 7d7df4418d..43155ceb6c 100644
|
|||
--- a/src/hypervisor/virhostdev.c
|
|||
+++ b/src/hypervisor/virhostdev.c
|
|||
@@ -2510,10 +2510,17 @@ virHostdevUpdateActiveNVMeDevices(virHostdevManager *hostdev_mgr,
|
|||
goto cleanup; |
|||
} |
|||
|
|||
+/**
|
|||
+ * virHostdevNeedsVFIO:
|
|||
+ * @hostdev: host device to check
|
|||
+ *
|
|||
+ * Returns true if using the @hostdev requires access to /dev/vfio/vfio,
|
|||
+ * otherwise false.
|
|||
+ */
|
|||
bool |
|||
virHostdevNeedsVFIO(const virDomainHostdevDef *hostdev) |
|||
{ |
|||
- return virHostdevIsPCIDevice(hostdev) ||
|
|||
+ return virHostdevIsPCIDeviceWithoutIOMMUFD(hostdev) ||
|
|||
virHostdevIsMdevDevice(hostdev); |
|||
} |
|||
|
|||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|||
index 386e757d81..ea1e2d8586 100644
|
|||
--- a/src/libvirt_private.syms
|
|||
+++ b/src/libvirt_private.syms
|
|||
@@ -814,6 +814,7 @@ virDomainQemuMonitorEventStateRegisterID;
|
|||
virHostdevIsMdevDevice; |
|||
virHostdevIsPCIDevice; |
|||
virHostdevIsPCIDeviceWithIOMMUFD; |
|||
+virHostdevIsPCIDeviceWithoutIOMMUFD;
|
|||
virHostdevIsSCSIDevice; |
|||
|
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,51 @@ |
|||
From 5512f4ffa8f4ea8a4afd354e4592b69dc5c39c61 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <5512f4ffa8f4ea8a4afd354e4592b69dc5c39c61.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Wed, 18 Mar 2026 12:52:05 +0100 |
|||
Subject: [PATCH] qemu: Expand call to qemuDomainNeedsVFIO |
|||
|
|||
The function qemuDomainNeedsVFIO() was originally used by other parts |
|||
of qemu code to figure out if the VM needs /dev/vfio/vfio. |
|||
|
|||
Later it was also used by code calculating locked memory limit for all |
|||
architectures, and after that change again and used only for PPC64. |
|||
|
|||
Now it needs to be changed again due to IOMMUFD support, the |
|||
/dev/vfio/vfio device is used by QEMU only if IOMMUFD is not used |
|||
but for accounting we still need consider all PCI host devices |
|||
because if IOMMUFD is used it still requires increasing locked |
|||
memory limit. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit c89b2bf1a80e3261bd18cdb352be1ffce9f4639e) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/qemu/qemu_domain.c | 10 ++++++++-- |
|||
1 file changed, 8 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|||
index 5c9f4831fd..57f18a02b6 100644
|
|||
--- a/src/qemu/qemu_domain.c
|
|||
+++ b/src/qemu/qemu_domain.c
|
|||
@@ -8259,8 +8259,14 @@ getPPC64MemLockLimitBytes(virDomainDef *def)
|
|||
passthroughLimit = maxMemory + |
|||
128 * (1ULL<<30) / 512 * nPCIHostBridges + |
|||
8192; |
|||
- } else if (qemuDomainNeedsVFIO(def) || virDomainDefHasVDPANet(def)) {
|
|||
- /* For regular (non-NVLink2 present) VFIO passthrough, the value
|
|||
+ } else if (virDomainDefHasPCIHostdev(def) ||
|
|||
+ virDomainDefHasMdevHostdev(def) ||
|
|||
+ virDomainDefHasNVMeDisk(def) ||
|
|||
+ virDomainDefHasVDPANet(def)) {
|
|||
+ /* Not using qemuDomainNeedsVFIO() as that doesn't take PCI host
|
|||
+ * devices with IOMMFD into account.
|
|||
+ *
|
|||
+ * For regular (non-NVLink2 present) VFIO passthrough, the value
|
|||
* of passthroughLimit is: |
|||
* |
|||
* passthroughLimit := max( 2 GiB * #PHBs, (c) |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,245 @@ |
|||
From 39dd90e66f661ce816592c1ee7cfd5bba54ea6f5 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <39dd90e66f661ce816592c1ee7cfd5bba54ea6f5.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Fri, 27 Feb 2026 17:55:34 +0100 |
|||
Subject: [PATCH] qemu: Fix IOMMUFD and VFIO security labels |
|||
MIME-Version: 1.0 |
|||
Content-Type: text/plain; charset=UTF-8 |
|||
Content-Transfer-Encoding: 8bit |
|||
|
|||
When IOMMUFD support was introduced it incorrectly tried to label |
|||
`/dev/iommu` and `/dev/vfio/devices/vfioX` but they are not added to |
|||
QEMU namespace because libvirt opens FDs and passes these FDs to QEMU. |
|||
|
|||
We need to label these FDs instead. |
|||
|
|||
Fixes: 7d2f91f9cb572ab95d0916bdd1a46dd198874529 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Ján Tomko <jtomko@redhat.com> |
|||
(cherry picked from commit 03f2672ab4eff8ee01410c9acba6288bfb4fa231) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-159902 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/qemu/qemu_hotplug.c | 2 +- |
|||
src/qemu/qemu_process.c | 16 ++++++++++++---- |
|||
src/qemu/qemu_process.h | 3 ++- |
|||
src/security/security_apparmor.c | 12 ------------ |
|||
src/security/security_dac.c | 27 --------------------------- |
|||
src/security/security_selinux.c | 23 ----------------------- |
|||
6 files changed, 15 insertions(+), 68 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
|||
index 845f42bf20..994cc749f6 100644
|
|||
--- a/src/qemu/qemu_hotplug.c
|
|||
+++ b/src/qemu/qemu_hotplug.c
|
|||
@@ -1621,7 +1621,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
|
|||
} |
|||
|
|||
if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { |
|||
- if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
|
|||
+ if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0)
|
|||
goto error; |
|||
|
|||
if (!priv->iommufdState) { |
|||
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|||
index 29601683a0..0a69063a4b 100644
|
|||
--- a/src/qemu/qemu_process.c
|
|||
+++ b/src/qemu/qemu_process.c
|
|||
@@ -7691,13 +7691,16 @@ int
|
|||
qemuProcessOpenIommuFd(virDomainObj *vm) |
|||
{ |
|||
qemuDomainObjPrivate *priv = vm->privateData; |
|||
- int iommufd;
|
|||
+ VIR_AUTOCLOSE iommufd = -1;
|
|||
|
|||
VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name); |
|||
|
|||
if ((iommufd = virIOMMUFDOpenDevice()) < 0) |
|||
return -1; |
|||
|
|||
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
|
|||
+ return -1;
|
|||
+
|
|||
priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd); |
|||
|
|||
return 0; |
|||
@@ -7712,16 +7715,21 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
|
|||
* Returns: 0 on success, -1 on failure |
|||
*/ |
|||
int |
|||
-qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev)
|
|||
+qemuProcessOpenVfioDeviceFd(virDomainObj *vm,
|
|||
+ virDomainHostdevDef *hostdev)
|
|||
{ |
|||
+ qemuDomainObjPrivate *priv = vm->privateData;
|
|||
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); |
|||
virDomainHostdevSubsysPCI *pci = &hostdev->source.subsys.u.pci; |
|||
g_autofree char *name = g_strdup_printf("hostdev-%s-fd", hostdev->info->alias); |
|||
- int vfioDeviceFd;
|
|||
+ VIR_AUTOCLOSE vfioDeviceFd = -1;
|
|||
|
|||
if ((vfioDeviceFd = virPCIDeviceOpenVfioFd(&pci->addr)) < 0) |
|||
return -1; |
|||
|
|||
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, vfioDeviceFd) < 0)
|
|||
+ return -1;
|
|||
+
|
|||
hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, &vfioDeviceFd); |
|||
|
|||
return 0; |
|||
@@ -7739,7 +7747,7 @@ qemuProcessPrepareHostHostdev(virDomainObj *vm)
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: |
|||
if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { |
|||
/* Open VFIO device FD */ |
|||
- if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
|
|||
+ if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0)
|
|||
return -1; |
|||
} |
|||
break; |
|||
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
|
|||
index 1023b7cb25..dc16622ed9 100644
|
|||
--- a/src/qemu/qemu_process.h
|
|||
+++ b/src/qemu/qemu_process.h
|
|||
@@ -136,7 +136,8 @@ int qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm,
|
|||
|
|||
int qemuProcessOpenIommuFd(virDomainObj *vm); |
|||
|
|||
-int qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev);
|
|||
+int qemuProcessOpenVfioDeviceFd(virDomainObj *vm,
|
|||
+ virDomainHostdevDef *hostdev);
|
|||
|
|||
int qemuProcessPrepareHost(virQEMUDriver *driver, |
|||
virDomainObj *vm, |
|||
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
|
|||
index 1c3496893c..40f13ec1a5 100644
|
|||
--- a/src/security/security_apparmor.c
|
|||
+++ b/src/security/security_apparmor.c
|
|||
@@ -45,7 +45,6 @@
|
|||
#include "virstring.h" |
|||
#include "virscsi.h" |
|||
#include "virmdev.h" |
|||
-#include "viriommufd.h"
|
|||
|
|||
#define VIR_FROM_THIS VIR_FROM_SECURITY |
|||
|
|||
@@ -856,17 +855,6 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
|
|||
if (AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr) < 0) |
|||
return -1; |
|||
- } else {
|
|||
- g_autofree char *vfiofdDev = NULL;
|
|||
-
|
|||
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
|
|||
- return -1;
|
|||
-
|
|||
- if (AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr) < 0)
|
|||
- return -1;
|
|||
-
|
|||
- if (AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr) < 0)
|
|||
- return -1;
|
|||
} |
|||
} else { |
|||
if (virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr) < 0) |
|||
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
|
|||
index 2a4c7f6a3c..d8cf117fc4 100644
|
|||
--- a/src/security/security_dac.c
|
|||
+++ b/src/security/security_dac.c
|
|||
@@ -41,7 +41,6 @@
|
|||
#include "virscsivhost.h" |
|||
#include "virstring.h" |
|||
#include "virutil.h" |
|||
-#include "viriommufd.h"
|
|||
|
|||
#define VIR_FROM_THIS VIR_FROM_SECURITY |
|||
|
|||
@@ -1295,17 +1294,6 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
|
|||
&cbdata) < 0) { |
|||
return -1; |
|||
} |
|||
- } else {
|
|||
- g_autofree char *vfiofdDev = NULL;
|
|||
-
|
|||
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
|
|||
- return -1;
|
|||
-
|
|||
- if (virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata) < 0)
|
|||
- return -1;
|
|||
-
|
|||
- if (virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata) < 0)
|
|||
- return -1;
|
|||
} |
|||
} else { |
|||
if (virPCIDeviceFileIterate(pci, |
|||
@@ -1476,21 +1464,6 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
|
|||
vfioGroupDev, false) < 0) { |
|||
return -1; |
|||
} |
|||
- } else {
|
|||
- g_autofree char *vfiofdDev = NULL;
|
|||
-
|
|||
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
|
|||
- return -1;
|
|||
-
|
|||
- if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
|
|||
- vfiofdDev, false) < 0) {
|
|||
- return -1;
|
|||
- }
|
|||
-
|
|||
- if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
|
|||
- VIR_IOMMU_DEV_PATH, false) < 0) {
|
|||
- return -1;
|
|||
- }
|
|||
} |
|||
} else { |
|||
if (virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr) < 0) |
|||
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
|
|||
index 96ca59a7a4..0fa50630f7 100644
|
|||
--- a/src/security/security_selinux.c
|
|||
+++ b/src/security/security_selinux.c
|
|||
@@ -41,7 +41,6 @@
|
|||
#include "virconf.h" |
|||
#include "virtpm.h" |
|||
#include "virstring.h" |
|||
-#include "viriommufd.h"
|
|||
|
|||
#define VIR_FROM_THIS VIR_FROM_SECURITY |
|||
|
|||
@@ -2267,17 +2266,6 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
&data) < 0) { |
|||
return -1; |
|||
} |
|||
- } else {
|
|||
- g_autofree char *vfiofdDev = NULL;
|
|||
-
|
|||
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
|
|||
- return -1;
|
|||
-
|
|||
- if (virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data) < 0)
|
|||
- return -1;
|
|||
-
|
|||
- if (virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data) < 0)
|
|||
- return -1;
|
|||
} |
|||
} else { |
|||
if (virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data) < 0) |
|||
@@ -2519,17 +2507,6 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
|
|||
if (virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false) < 0) |
|||
return -1; |
|||
- } else {
|
|||
- g_autofree char *vfiofdDev = NULL;
|
|||
-
|
|||
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
|
|||
- return -1;
|
|||
-
|
|||
- if (virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false) < 0)
|
|||
- return -1;
|
|||
-
|
|||
- if (virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false) < 0)
|
|||
- return -1;
|
|||
} |
|||
} else { |
|||
if (virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr) < 0) |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,60 @@ |
|||
From 0c8a23f5f3e063b35b890d5538e5497f51d1095c Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <0c8a23f5f3e063b35b890d5538e5497f51d1095c.1780571166.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Mon, 23 Feb 2026 16:23:10 +0100 |
|||
Subject: [PATCH] qemu: Fix job handling when domain dies in post-copy |
|||
migration |
|||
|
|||
When a domain is in post-copy migration phase, we need to keep the job |
|||
active if something fails to protect the domain from changes. |
|||
Unfortunately, there is a race between migration code and |
|||
qemuProcessStop that can cause the job to stay active even when the |
|||
domain is gone and thus preventing the domain from being started again |
|||
(until virtqemud is restarted). The race is caused by unlocking the vm |
|||
object when calling virConnectUnregisterCloseCallback. While the domain |
|||
is unlocked qemuProcessStop can finish its work and the domain may no |
|||
longer be active when we get the lock back. The post-copy path does not |
|||
properly check if a domain is still active. |
|||
|
|||
Instead of adding the virDomainObjIsActive check in all places where |
|||
this could happen, we can add it in virDomainObjIsPostcopy and |
|||
virDomainObjIsFailedPostcopy and let the code take the pre-copy cleanup |
|||
path. Clearly an inactive domain can never be in (failed) post-copy |
|||
migration. |
|||
|
|||
https://issues.redhat.com/browse/RHEL-145179 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 3d1e6d92de784e5c9d2a5e4bc18829c92278343a) |
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/conf/domain_conf.c | 6 ++++++ |
|||
1 file changed, 6 insertions(+) |
|||
|
|||
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|||
index 1f7b1ca340..35de8bab6b 100644
|
|||
--- a/src/conf/domain_conf.c
|
|||
+++ b/src/conf/domain_conf.c
|
|||
@@ -30493,6 +30493,9 @@ bool
|
|||
virDomainObjIsFailedPostcopy(virDomainObj *dom, |
|||
virDomainJobObj *job) |
|||
{ |
|||
+ if (!virDomainObjIsActive(dom))
|
|||
+ return false;
|
|||
+
|
|||
if (job && job->asyncPaused && |
|||
(job->asyncJob == VIR_ASYNC_JOB_MIGRATION_IN || |
|||
job->asyncJob == VIR_ASYNC_JOB_MIGRATION_OUT)) |
|||
@@ -30509,6 +30512,9 @@ bool
|
|||
virDomainObjIsPostcopy(virDomainObj *dom, |
|||
virDomainJobObj *job) |
|||
{ |
|||
+ if (!virDomainObjIsActive(dom))
|
|||
+ return false;
|
|||
+
|
|||
if (virDomainObjIsFailedPostcopy(dom, job)) |
|||
return true; |
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,47 @@ |
|||
From eccea5104691012040f130ee0d400c2cc0b174f7 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <eccea5104691012040f130ee0d400c2cc0b174f7.1780571166.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Wed, 11 Mar 2026 12:12:40 +0100 |
|||
Subject: [PATCH] qemu: Implement |
|||
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 3215fee34967c49f37a965154879fc5860293cac) |
|||
|
|||
https://issues.redhat.com/browse/RHEL-153653 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/qemu/qemu_driver.c | 9 ++++++++- |
|||
1 file changed, 8 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|||
index f3e7410f9e..ecd19663ce 100644
|
|||
--- a/src/qemu/qemu_driver.c
|
|||
+++ b/src/qemu/qemu_driver.c
|
|||
@@ -16720,7 +16720,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
|
|||
virDomainVirtType virttype; |
|||
g_autoptr(virDomainCaps) domCaps = NULL; |
|||
|
|||
- virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES,
|
|||
+ virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES |
|
|||
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
|
|||
NULL); |
|||
|
|||
if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0) |
|||
@@ -16746,6 +16747,12 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
|
|||
VIR_CPU_FEATURE_DISABLE); |
|||
} |
|||
|
|||
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) {
|
|||
+ virCPUDef *cpu = domCaps->cpu.hostModel;
|
|||
+ if (cpu && virCPUExpandFeatures(arch, cpu) < 0)
|
|||
+ return NULL;
|
|||
+ }
|
|||
+
|
|||
return virDomainCapsFormat(domCaps); |
|||
} |
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,127 @@ |
|||
From 8cdc3bb132898c37fe17762aba7dabb59819ce0a Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <8cdc3bb132898c37fe17762aba7dabb59819ce0a.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Mon, 16 Mar 2026 15:29:32 +0100 |
|||
Subject: [PATCH] qemu: Implement iommufd fdgroup |
|||
|
|||
When fdgroup is used for iommufd we will start QEMU with -object iommufd |
|||
even if the VM has no host device. When virDomainFDAssociate() is used |
|||
the FD libvirt is holding is closed with connection. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 0a83b28795f0c18592f9d842927528f0676cc56d) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/qemu/qemu_command.c | 4 +++- |
|||
src/qemu/qemu_hotplug.c | 4 ++-- |
|||
src/qemu/qemu_process.c | 47 ++++++++++++++++++++++++++++++++++++++--- |
|||
3 files changed, 49 insertions(+), 6 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|||
index 23e799de3c..db72407ecc 100644
|
|||
--- a/src/qemu/qemu_command.c
|
|||
+++ b/src/qemu/qemu_command.c
|
|||
@@ -5360,8 +5360,10 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd,
|
|||
qemuDomainObjPrivate *priv = vm->privateData; |
|||
g_autoptr(virJSONValue) props = NULL; |
|||
|
|||
- if (!virDomainDefHasPCIHostdevWithIOMMUFD(def))
|
|||
+ if (!virDomainDefHasPCIHostdevWithIOMMUFD(def) &&
|
|||
+ !def->iommufd_fdgroup) {
|
|||
return 0; |
|||
+ }
|
|||
|
|||
qemuFDPassDirectTransferCommand(priv->iommufd, cmd); |
|||
|
|||
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
|||
index 25fe699bb3..8944062aa4 100644
|
|||
--- a/src/qemu/qemu_hotplug.c
|
|||
+++ b/src/qemu/qemu_hotplug.c
|
|||
@@ -1624,7 +1624,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
|
|||
if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0) |
|||
goto error; |
|||
|
|||
- if (!priv->iommufdState) {
|
|||
+ if (!priv->iommufdState && !vm->def->iommufd_fdgroup) {
|
|||
if (qemuProcessOpenIommuFd(vm) < 0) |
|||
goto error; |
|||
|
|||
@@ -5031,7 +5031,7 @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver,
|
|||
} |
|||
} |
|||
|
|||
- if (priv->iommufdState &&
|
|||
+ if (priv->iommufdState && !vm->def->iommufd_fdgroup &&
|
|||
!virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) { |
|||
qemuDomainObjEnterMonitor(vm); |
|||
ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false)); |
|||
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|||
index d13bce8fcf..e4746374f6 100644
|
|||
--- a/src/qemu/qemu_process.c
|
|||
+++ b/src/qemu/qemu_process.c
|
|||
@@ -7706,6 +7706,44 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
|
|||
return 0; |
|||
} |
|||
|
|||
+/**
|
|||
+ * qemuProcessGetPassedIommuFd:
|
|||
+ * @vm: domain object
|
|||
+ *
|
|||
+ * Find passed FD via virDomainFDAssociate() API for the VM.
|
|||
+ *
|
|||
+ * Returns: 0 on success, -1 on failure
|
|||
+ */
|
|||
+static int
|
|||
+qemuProcessGetPassedIommuFd(virDomainObj *vm)
|
|||
+{
|
|||
+ qemuDomainObjPrivate *priv = vm->privateData;
|
|||
+ virDomainFDTuple *fdt = virHashLookup(priv->fds, vm->def->iommufd_fdgroup);
|
|||
+ VIR_AUTOCLOSE iommufd = -1;
|
|||
+
|
|||
+ if (!fdt) {
|
|||
+ virReportError(VIR_ERR_INVALID_ARG,
|
|||
+ _("file descriptor group '%1$s' was not associated with the domain"),
|
|||
+ vm->def->iommufd_fdgroup);
|
|||
+ return -1;
|
|||
+ }
|
|||
+
|
|||
+ if (fdt->nfds != 1) {
|
|||
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|||
+ _("Only one file descriptor needs to be associated with iommufd"));
|
|||
+ return -1;
|
|||
+ }
|
|||
+
|
|||
+ iommufd = dup(fdt->fds[0]);
|
|||
+
|
|||
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
|
|||
+ return -1;
|
|||
+
|
|||
+ priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
/** |
|||
* qemuProcessOpenVfioDeviceFd: |
|||
* @hostdev: host device definition |
|||
@@ -7761,9 +7799,12 @@ qemuProcessPrepareHostHostdev(virDomainObj *vm)
|
|||
} |
|||
|
|||
/* Open IOMMU FD */ |
|||
- if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def) &&
|
|||
- qemuProcessOpenIommuFd(vm) < 0) {
|
|||
- return -1;
|
|||
+ if (vm->def->iommufd_fdgroup) {
|
|||
+ if (qemuProcessGetPassedIommuFd(vm) < 0)
|
|||
+ return -1;
|
|||
+ } else if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
|
|||
+ if (qemuProcessOpenIommuFd(vm) < 0)
|
|||
+ return -1;
|
|||
} |
|||
|
|||
return 0; |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,119 @@ |
|||
From e52edf2ed7f3e1e379fb85ae0c0870113912c9d6 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <e52edf2ed7f3e1e379fb85ae0c0870113912c9d6.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Wed, 18 Mar 2026 17:59:01 +0100 |
|||
Subject: [PATCH] qemu: Implement iommufd |
|||
|
|||
Ideally this should be done in qemuDomainHostdevDefPostParse but that |
|||
would require a lot of refactoring mainly due to how interface backed by |
|||
hostdev works. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit fc516031ed865f78d590068424ada19a941046ba) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/qemu/qemu_domain.c | 12 +++++++++--- |
|||
src/qemu/qemu_domain.h | 3 ++- |
|||
src/qemu/qemu_hotplug.c | 2 +- |
|||
src/qemu/qemu_process.c | 4 ++-- |
|||
4 files changed, 14 insertions(+), 7 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|||
index a61939aa15..495cbd4f7d 100644
|
|||
--- a/src/qemu/qemu_domain.c
|
|||
+++ b/src/qemu/qemu_domain.c
|
|||
@@ -10120,10 +10120,12 @@ qemuDomainPrepareHostdevSCSI(virDomainHostdevDef *hostdev,
|
|||
|
|||
|
|||
static int |
|||
-qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev,
|
|||
+qemuDomainPrepareHostdevPCI(const virDomainDef *def,
|
|||
+ virDomainHostdevDef *hostdev,
|
|||
virQEMUCaps *qemuCaps) |
|||
{ |
|||
virDeviceHostdevPCIDriverName *driverName = &hostdev->source.subsys.u.pci.driver.name; |
|||
+ virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci;
|
|||
|
|||
/* assign defaults for hostdev passthrough */ |
|||
switch (*driverName) { |
|||
@@ -10160,12 +10162,16 @@ qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev,
|
|||
return -1; |
|||
} |
|||
|
|||
+ if (pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_ABSENT)
|
|||
+ pcisrc->driver.iommufd = def->iommufd;
|
|||
+
|
|||
return 0; |
|||
} |
|||
|
|||
|
|||
int |
|||
-qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
|
|||
+qemuDomainPrepareHostdev(const virDomainDef *def,
|
|||
+ virDomainHostdevDef *hostdev,
|
|||
qemuDomainObjPrivate *priv) |
|||
{ |
|||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) |
|||
@@ -10175,7 +10181,7 @@ qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: |
|||
return qemuDomainPrepareHostdevSCSI(hostdev, priv); |
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: |
|||
- return qemuDomainPrepareHostdevPCI(hostdev, priv->qemuCaps);
|
|||
+ return qemuDomainPrepareHostdevPCI(def, hostdev, priv->qemuCaps);
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: |
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: |
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: |
|||
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
|
|||
index 62c5252b9f..8cd221062c 100644
|
|||
--- a/src/qemu/qemu_domain.h
|
|||
+++ b/src/qemu/qemu_domain.h
|
|||
@@ -1048,7 +1048,8 @@ qemuDomainDiskCachemodeFlags(virDomainDiskCache cachemode,
|
|||
bool *noflush); |
|||
|
|||
int |
|||
-qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
|
|||
+qemuDomainPrepareHostdev(const virDomainDef *def,
|
|||
+ virDomainHostdevDef *hostdev,
|
|||
qemuDomainObjPrivate *priv); |
|||
|
|||
char * qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivate *priv); |
|||
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
|||
index 994cc749f6..25fe699bb3 100644
|
|||
--- a/src/qemu/qemu_hotplug.c
|
|||
+++ b/src/qemu/qemu_hotplug.c
|
|||
@@ -2900,7 +2900,7 @@ qemuDomainAttachHostDevice(virQEMUDriver *driver,
|
|||
return -1; |
|||
} |
|||
|
|||
- if (qemuDomainPrepareHostdev(hostdev, vm->privateData) < 0)
|
|||
+ if (qemuDomainPrepareHostdev(vm->def, hostdev, vm->privateData) < 0)
|
|||
return -1; |
|||
|
|||
switch (hostdev->source.subsys.type) { |
|||
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|||
index 9b8b378b1f..d13bce8fcf 100644
|
|||
--- a/src/qemu/qemu_process.c
|
|||
+++ b/src/qemu/qemu_process.c
|
|||
@@ -6050,7 +6050,7 @@ qemuProcessPrepareDomainNetwork(virDomainObj *vm)
|
|||
/* 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)
|
|||
+ if (qemuDomainPrepareHostdev(def, hostdev, priv) < 0)
|
|||
return -1; |
|||
|
|||
virDomainHostdevInsert(def, hostdev); |
|||
@@ -6838,7 +6838,7 @@ qemuProcessPrepareDomainHostdevs(virDomainObj *vm,
|
|||
for (i = 0; i < vm->def->nhostdevs; i++) { |
|||
virDomainHostdevDef *hostdev = vm->def->hostdevs[i]; |
|||
|
|||
- if (qemuDomainPrepareHostdev(hostdev, priv) < 0)
|
|||
+ if (qemuDomainPrepareHostdev(vm->def, hostdev, priv) < 0)
|
|||
return -1; |
|||
} |
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,196 @@ |
|||
From 9ec1c8fc52cd3150712f5ada134e070fbdabb7bb Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <9ec1c8fc52cd3150712f5ada134e070fbdabb7bb.1780571166.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Thu, 21 May 2026 12:36:48 +0200 |
|||
Subject: [PATCH] qemu: Move domain caps flags handling to |
|||
virQEMUCapsFillDomainCPUHostModel |
|||
|
|||
We will need to generate the capabilities in a different way based on |
|||
the flags. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit b4d3572198848e6a2886352e1a48b46afa37bec1) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/qemu/qemu_capabilities.c | 34 ++++++++++++++++++++++++---------- |
|||
src/qemu/qemu_capabilities.h | 3 ++- |
|||
src/qemu/qemu_conf.c | 6 ++++-- |
|||
src/qemu/qemu_conf.h | 3 ++- |
|||
src/qemu/qemu_driver.c | 15 ++------------- |
|||
tests/domaincapstest.c | 2 +- |
|||
6 files changed, 35 insertions(+), 28 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
|||
index 0b32296cc8..c17b55420d 100644
|
|||
--- a/src/qemu/qemu_capabilities.c
|
|||
+++ b/src/qemu/qemu_capabilities.c
|
|||
@@ -6584,14 +6584,26 @@ virQEMUCapsFillDomainCPUMaximum(virDomainCaps *domCaps)
|
|||
|
|||
static void |
|||
virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps, |
|||
- virDomainCaps *domCaps)
|
|||
+ virDomainCaps *domCaps,
|
|||
+ unsigned int flags)
|
|||
{ |
|||
- virCPUDef *cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
|
|||
- VIR_QEMU_CAPS_HOST_CPU_REPORTED);
|
|||
+ virQEMUCapsHostCPUType cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED;
|
|||
+ virCPUDef *cpu;
|
|||
|
|||
- domCaps->cpu.hostModel = virCPUDefCopy(cpu);
|
|||
- domCaps->cpu.hostModel->addr = virQEMUCapsGetHostPhysAddr(qemuCaps,
|
|||
- domCaps->virttype);
|
|||
+ cpu = virCPUDefCopy(virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
|
|||
+ cpuType));
|
|||
+
|
|||
+ cpu->addr = virQEMUCapsGetHostPhysAddr(qemuCaps, domCaps->virttype);
|
|||
+
|
|||
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES) {
|
|||
+ virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, domCaps->virttype,
|
|||
+ cpu, VIR_CPU_FEATURE_DISABLE);
|
|||
+ }
|
|||
+
|
|||
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
|
|||
+ virCPUExpandFeatures(domCaps->arch, cpu);
|
|||
+
|
|||
+ domCaps->cpu.hostModel = cpu;
|
|||
} |
|||
|
|||
|
|||
@@ -6616,7 +6628,8 @@ virQEMUCapsFillDomainCPUCustom(virQEMUCaps *qemuCaps,
|
|||
static void |
|||
virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps, |
|||
virArch hostarch, |
|||
- virDomainCaps *domCaps)
|
|||
+ virDomainCaps *domCaps,
|
|||
+ unsigned int flags)
|
|||
{ |
|||
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype, |
|||
VIR_CPU_MODE_HOST_PASSTHROUGH, |
|||
@@ -6633,7 +6646,7 @@ virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
|
|||
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype, |
|||
VIR_CPU_MODE_HOST_MODEL, |
|||
domCaps->machine)) { |
|||
- virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps);
|
|||
+ virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps, flags);
|
|||
} |
|||
|
|||
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype, |
|||
@@ -7263,7 +7276,8 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
|
|||
virQEMUCaps *qemuCaps, |
|||
virArch hostarch, |
|||
virDomainCaps *domCaps, |
|||
- bool privileged)
|
|||
+ bool privileged,
|
|||
+ unsigned int flags)
|
|||
{ |
|||
virDomainCapsOS *os = &domCaps->os; |
|||
virDomainCapsDeviceDisk *disk = &domCaps->disk; |
|||
@@ -7305,7 +7319,7 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
|
|||
firmwares, nfirmwares) < 0) |
|||
return -1; |
|||
|
|||
- virQEMUCapsFillDomainCPUCaps(qemuCaps, hostarch, domCaps);
|
|||
+ virQEMUCapsFillDomainCPUCaps(qemuCaps, hostarch, domCaps, flags);
|
|||
virQEMUCapsFillDomainMemoryBackingCaps(qemuCaps, memoryBacking); |
|||
virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, domCaps->machine, disk); |
|||
virQEMUCapsFillDomainDeviceGraphicsCaps(cfg, qemuCaps, graphics); |
|||
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
|
|||
index f7c8680f94..bc3ecbb89f 100644
|
|||
--- a/src/qemu/qemu_capabilities.h
|
|||
+++ b/src/qemu/qemu_capabilities.h
|
|||
@@ -896,7 +896,8 @@ int virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
|
|||
virQEMUCaps *qemuCaps, |
|||
virArch hostarch, |
|||
virDomainCaps *domCaps, |
|||
- bool privileged);
|
|||
+ bool privileged,
|
|||
+ unsigned int flags);
|
|||
|
|||
void virQEMUCapsFillDomainMemoryBackingCaps(virQEMUCaps *qemuCaps, |
|||
virDomainCapsMemoryBacking *memoryBacking); |
|||
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
|
|||
index 242955200a..5e40635871 100644
|
|||
--- a/src/qemu/qemu_conf.c
|
|||
+++ b/src/qemu/qemu_conf.c
|
|||
@@ -1708,7 +1708,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
|
|||
virQEMUCaps *qemuCaps, |
|||
const char *machine, |
|||
virArch arch, |
|||
- virDomainVirtType virttype)
|
|||
+ virDomainVirtType virttype,
|
|||
+ unsigned int flags)
|
|||
{ |
|||
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); |
|||
g_autoptr(virDomainCaps) domCaps = NULL; |
|||
@@ -1742,7 +1743,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
|
|||
qemuCaps, |
|||
driver->hostarch, |
|||
domCaps, |
|||
- driver->privileged) < 0)
|
|||
+ driver->privileged,
|
|||
+ flags) < 0)
|
|||
return NULL; |
|||
|
|||
return g_steal_pointer(&domCaps); |
|||
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
|
|||
index edb65c99f4..36d7808e10 100644
|
|||
--- a/src/qemu/qemu_conf.h
|
|||
+++ b/src/qemu/qemu_conf.h
|
|||
@@ -375,7 +375,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
|
|||
virQEMUCaps *qemuCaps, |
|||
const char *machine, |
|||
virArch arch, |
|||
- virDomainVirtType virttype);
|
|||
+ virDomainVirtType virttype,
|
|||
+ unsigned int flags);
|
|||
|
|||
int qemuDriverAllocateID(virQEMUDriver *driver); |
|||
virDomainXMLOption *virQEMUDriverCreateXMLConf(virQEMUDriver *driver, |
|||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|||
index 8db9cbb6a2..0a61f97666 100644
|
|||
--- a/src/qemu/qemu_driver.c
|
|||
+++ b/src/qemu/qemu_driver.c
|
|||
@@ -16738,21 +16738,10 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
|
|||
|
|||
if (!(domCaps = virQEMUDriverGetDomainCapabilities(driver, |
|||
qemuCaps, machine, |
|||
- arch, virttype)))
|
|||
+ arch, virttype,
|
|||
+ flags)))
|
|||
return NULL; |
|||
|
|||
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES) {
|
|||
- virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, virttype,
|
|||
- domCaps->cpu.hostModel,
|
|||
- VIR_CPU_FEATURE_DISABLE);
|
|||
- }
|
|||
-
|
|||
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) {
|
|||
- virCPUDef *cpu = domCaps->cpu.hostModel;
|
|||
- if (cpu && virCPUExpandFeatures(arch, cpu) < 0)
|
|||
- return NULL;
|
|||
- }
|
|||
-
|
|||
return virDomainCapsFormat(domCaps); |
|||
} |
|||
|
|||
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
|
|||
index 5b2fc80f0a..f2248c2435 100644
|
|||
--- a/tests/domaincapstest.c
|
|||
+++ b/tests/domaincapstest.c
|
|||
@@ -101,7 +101,7 @@ fillQemuCaps(virDomainCaps *domCaps,
|
|||
|
|||
if (virQEMUCapsFillDomainCaps(cfg, |
|||
qemuCaps, domCaps->arch, domCaps, |
|||
- false) < 0)
|
|||
+ false, 0) < 0)
|
|||
return -1; |
|||
|
|||
/* As of f05b6a918e28 we are expecting to see OVMF_CODE.fd file which |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,107 @@ |
|||
From 84c12b67bed448ae5129e3b7c18b52fa397cf217 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <84c12b67bed448ae5129e3b7c18b52fa397cf217.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Wed, 18 Mar 2026 13:10:37 +0100 |
|||
Subject: [PATCH] qemu: Update qemuDomainNeedsVFIO to ignore PCI hostdev with |
|||
IOMMUFD |
|||
|
|||
This function is used to figure out if VM needs access to /dev/vfio/vfio. |
|||
In case of PCI host devices that is true only if IOMMUFD is not enabled. |
|||
|
|||
This fixes error when hotplugging PCI host device with IOMMUFD disabled |
|||
to a VM that already has PCI host device with IOMMIFD enabled: |
|||
|
|||
Could not open '/dev/vfio/vfio': No such file or directory |
|||
|
|||
The function is used in this case to check if /dev/vfio/vfio was already |
|||
made available to QEMU or not. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit d1fb5cf127d7681fa6c27e5b163ef410132aea49) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/conf/domain_conf.c | 14 ++++++++++++++ |
|||
src/conf/domain_conf.h | 3 +++ |
|||
src/libvirt_private.syms | 1 + |
|||
src/qemu/qemu_domain.c | 9 ++++++++- |
|||
4 files changed, 26 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|||
index 99d2a0aa53..576a1bd79b 100644
|
|||
--- a/src/conf/domain_conf.c
|
|||
+++ b/src/conf/domain_conf.c
|
|||
@@ -32520,6 +32520,20 @@ virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def)
|
|||
} |
|||
|
|||
|
|||
+bool
|
|||
+virDomainDefHasPCIHostdevWithoutIOMMUFD(const virDomainDef *def)
|
|||
+{
|
|||
+ size_t i;
|
|||
+
|
|||
+ for (i = 0; i < def->nhostdevs; i++) {
|
|||
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(def->hostdevs[i]))
|
|||
+ return true;
|
|||
+ }
|
|||
+
|
|||
+ return false;
|
|||
+}
|
|||
+
|
|||
+
|
|||
bool |
|||
virDomainDefHasMdevHostdev(const virDomainDef *def) |
|||
{ |
|||
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
|||
index 8f5780ee4c..f1c8478208 100644
|
|||
--- a/src/conf/domain_conf.h
|
|||
+++ b/src/conf/domain_conf.h
|
|||
@@ -4658,6 +4658,9 @@ virDomainDefHasPCIHostdev(const virDomainDef *def);
|
|||
bool |
|||
virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def); |
|||
|
|||
+bool
|
|||
+virDomainDefHasPCIHostdevWithoutIOMMUFD(const virDomainDef *def);
|
|||
+
|
|||
bool |
|||
virDomainDefHasMdevHostdev(const virDomainDef *def); |
|||
|
|||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|||
index ea1e2d8586..d2563e587a 100644
|
|||
--- a/src/libvirt_private.syms
|
|||
+++ b/src/libvirt_private.syms
|
|||
@@ -349,6 +349,7 @@ virDomainDefHasOldStyleROUEFI;
|
|||
virDomainDefHasOldStyleUEFI; |
|||
virDomainDefHasPCIHostdev; |
|||
virDomainDefHasPCIHostdevWithIOMMUFD; |
|||
+virDomainDefHasPCIHostdevWithoutIOMMUFD;
|
|||
virDomainDefHasTimer; |
|||
virDomainDefHasUSB; |
|||
virDomainDefHasVcpusOffline; |
|||
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|||
index 57f18a02b6..a61939aa15 100644
|
|||
--- a/src/qemu/qemu_domain.c
|
|||
+++ b/src/qemu/qemu_domain.c
|
|||
@@ -9284,10 +9284,17 @@ qemuDomainSupportsVideoVga(const virDomainVideoDef *video,
|
|||
} |
|||
|
|||
|
|||
+/**
|
|||
+ * qemuDomainNeedsVFIO:
|
|||
+ * @def: domain definition to check
|
|||
+ *
|
|||
+ * Check the domain definition to figure out if QEMU needs access
|
|||
+ * to /dev/vfio/vfio. It's not required if IOMMUFD is used.
|
|||
+ */
|
|||
bool |
|||
qemuDomainNeedsVFIO(const virDomainDef *def) |
|||
{ |
|||
- return virDomainDefHasPCIHostdev(def) ||
|
|||
+ return virDomainDefHasPCIHostdevWithoutIOMMUFD(def) ||
|
|||
virDomainDefHasMdevHostdev(def) || |
|||
virDomainDefHasNVMeDisk(def); |
|||
} |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,59 @@ |
|||
From dbaf42b6deae0149f88a3be8fbf52a5e94eb799d Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <dbaf42b6deae0149f88a3be8fbf52a5e94eb799d.1780571166.git.jdenemar@redhat.com> |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Wed, 11 Feb 2026 10:16:34 +0100 |
|||
Subject: [PATCH] qemu: Wire up new hyperv host-model mode behavior |
|||
|
|||
Since some hyperv features might be already enabled/disabled when |
|||
entering qemuProcessEnableDomainFeatures() only those which are |
|||
not set in domain XML (i.e. are VIR_TRISTATE_SWITCH_ABSENT) |
|||
should be modified. Furthermore, some features are not a simple |
|||
on/off switch, but a number or a string even. Well, that doesn't |
|||
matter really as the logic for setting them is the same: only set |
|||
their value iff they are not already set. |
|||
|
|||
Resolves: https://issues.redhat.com/browse/RHEL-148219 |
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 11057abfd13f6aad15f9821235b66c68e6211af6) |
|||
Resolves: https://issues.redhat.com/browse/RHEL-151688 |
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
---
|
|||
src/qemu/qemu_process.c | 8 +++++++- |
|||
.../qemuxmlconfdata/hyperv-host-model.x86_64-latest.args | 2 +- |
|||
2 files changed, 8 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|||
index 1aff3a277b..29601683a0 100644
|
|||
--- a/src/qemu/qemu_process.c
|
|||
+++ b/src/qemu/qemu_process.c
|
|||
@@ -6964,7 +6964,13 @@ qemuProcessEnableDomainFeatures(virDomainObj *vm)
|
|||
if (!VIR_DOMAIN_CAPS_ENUM_IS_SET(hv->features, i)) |
|||
continue; |
|||
|
|||
- vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
|
|||
+ if (vm->def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ABSENT) {
|
|||
+ vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
|
|||
+ } else {
|
|||
+ /* if the user provided already config for this we skip the
|
|||
+ * auto-population code */
|
|||
+ continue;
|
|||
+ }
|
|||
|
|||
if (i == VIR_DOMAIN_HYPERV_SPINLOCKS) { |
|||
if (hv->spinlocks != 0) { |
|||
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
|
|||
index 58502ff51e..d1f2326da1 100644
|
|||
--- a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
|
|||
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
|
|||
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
|
|||
-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=on \ |
|||
-accel tcg \ |
|||
--cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0xfff,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on,hv-reset=on,hv-vendor-id=Linux KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-avic=on,hv-emsr-bitmap=on,hv-xmm-input=on' \
|
|||
+-cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x2000,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on,hv-reset=on,hv-vendor-id=Linux KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-avic=on,hv-emsr-bitmap=on' \
|
|||
-m size=219136k \ |
|||
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ |
|||
-overcommit mem-lock=off \ |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,46 @@ |
|||
From 3e6b8f45de2cef2a8f08f84d62915b3cbaa050de Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <3e6b8f45de2cef2a8f08f84d62915b3cbaa050de.1780571166.git.jdenemar@redhat.com> |
|||
From: Peter Krempa <pkrempa@redhat.com> |
|||
Date: Wed, 18 Mar 2026 08:54:16 +0100 |
|||
Subject: [PATCH] qemuMigrationSrcBeginPhase: Don't call |
|||
'qemuBlockNodesEnsureActive' with offline VM |
|||
|
|||
Commits 7b5566ce67b18a and f879d5f40385358 ( v11.8.0-92-gf879d5f403 ) |
|||
moved around code for re-activating block backends after migration. |
|||
While previously it was done when migration failed now we do it when we |
|||
need qemu to do some block operations. |
|||
|
|||
'qemuBlockNodesEnsureActive' is thus called also when 'VIR_MIGRATE_OFFLINE' |
|||
is used. This doesn't cause failure similar to previous patch only due |
|||
to a conincidence as 'qemuCaps' wasn't initialized yet and thus we |
|||
assume that QEMU doesn't support 'blockdev-set-active' and skip all |
|||
monitor code. |
|||
|
|||
Make the code more robust and explicit by calling |
|||
'qemuBlockNodesEnsureActive' only on active VMs during migration. |
|||
|
|||
Fixes: 7b5566ce67b18a2bebe68fdb07e046f25185f8d3 |
|||
Signed-off-by: Peter Krempa <pkrempa@redhat.com> |
|||
Reviewed-by: Jiri Denemark <jdenemar@redhat.com> |
|||
(cherry picked from commit 4537c0b8708851136b8246b1869c6008a56240ae) |
|||
https://redhat.atlassian.net/browse/RHEL-173433 |
|||
---
|
|||
src/qemu/qemu_migration.c | 3 ++- |
|||
1 file changed, 2 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
|
|||
index 1fd9b1dd55..2b3f464fa6 100644
|
|||
--- a/src/qemu/qemu_migration.c
|
|||
+++ b/src/qemu/qemu_migration.c
|
|||
@@ -2868,7 +2868,8 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver,
|
|||
vm->newDef && !qemuDomainVcpuHotplugIsInOrder(vm->newDef))) |
|||
cookieFlags |= QEMU_MIGRATION_COOKIE_CPU_HOTPLUG; |
|||
|
|||
- if (qemuBlockNodesEnsureActive(vm, vm->job->asyncJob) < 0)
|
|||
+ if (virDomainObjIsActive(vm) &&
|
|||
+ qemuBlockNodesEnsureActive(vm, vm->job->asyncJob) < 0)
|
|||
return NULL; |
|||
|
|||
return qemuMigrationSrcBeginXML(vm, xmlin, |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,45 @@ |
|||
From f875d6f1e560dd9d73e373d576f2c784f6f8cb4c Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <f875d6f1e560dd9d73e373d576f2c784f6f8cb4c.1780571166.git.jdenemar@redhat.com> |
|||
From: Peter Krempa <pkrempa@redhat.com> |
|||
Date: Mon, 23 Mar 2026 22:39:58 +0100 |
|||
Subject: [PATCH] qemuMigrationSrcBeginXML: Don't call |
|||
'qemuMigrationSrcBeginPhaseBlockDirtyBitmaps' with offline VM |
|||
|
|||
Commit a4f610ff3fe190058f1 made the call to |
|||
'qemuMigrationSrcBeginPhaseBlockDirtyBitmaps' inside |
|||
'qemuMigrationSrcBeginXML' unconditional. This unfortunately means that |
|||
it was called also with 'VIR_MIGRATE_OFFLINE'. |
|||
|
|||
Attempting to enter the monitor in such case results in an error: |
|||
|
|||
error: operation failed: domain is no longer running |
|||
|
|||
Restrict the call only to non-offline migration. |
|||
|
|||
Fixes: a4f610ff3fe190058f18baea18b095d0bc69441b |
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156800 |
|||
Closes: https://gitlab.com/libvirt/libvirt/-/work_items/865 |
|||
Signed-off-by: Peter Krempa <pkrempa@redhat.com> |
|||
Reviewed-by: Jiri Denemark <jdenemar@redhat.com> |
|||
(cherry picked from commit 59fde80f39567101010e7ba4dece4fd68b50090d) |
|||
https://redhat.atlassian.net/browse/RHEL-173433 |
|||
---
|
|||
src/qemu/qemu_migration.c | 3 ++- |
|||
1 file changed, 2 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
|
|||
index 2a4df1191d..1fd9b1dd55 100644
|
|||
--- a/src/qemu/qemu_migration.c
|
|||
+++ b/src/qemu/qemu_migration.c
|
|||
@@ -2689,7 +2689,8 @@ qemuMigrationSrcBeginXML(virDomainObj *vm,
|
|||
if (!(mig = qemuMigrationCookieNew(vm->def, priv->origname))) |
|||
return NULL; |
|||
|
|||
- if (qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm) < 0)
|
|||
+ if (!(flags & VIR_MIGRATE_OFFLINE) &&
|
|||
+ qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm) < 0)
|
|||
return NULL; |
|||
|
|||
if (qemuMigrationCookieFormat(mig, driver, vm, |
|||
--
|
|||
2.54.0 |
|||
File diff suppressed because it is too large
@ -0,0 +1,158 @@ |
|||
From fba9c200834d8d31ed34e632470563a0074fe528 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <fba9c200834d8d31ed34e632470563a0074fe528.1780571167.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Thu, 21 May 2026 17:55:28 +0200 |
|||
Subject: [PATCH] qemu_capabilities: Cache expanded CPU |
|||
|
|||
When probing host model CPU we already expand it to get a list of all |
|||
CPU features. Let's store the expanded CPU definition in virQEMUCaps and |
|||
copy it to domain capabilities when requested by the |
|||
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES flag instead of |
|||
expanding the CPU over and over on each request. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 312000a739aebaa9de655bb1f6a539326ea8783d) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/qemu/qemu_capabilities.c | 39 ++++++++++++++++++++++++++---------- |
|||
src/qemu/qemu_capabilities.h | 3 +++ |
|||
2 files changed, 31 insertions(+), 11 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
|||
index 2e8f220abc..555723cafb 100644
|
|||
--- a/src/qemu/qemu_capabilities.c
|
|||
+++ b/src/qemu/qemu_capabilities.c
|
|||
@@ -788,6 +788,9 @@ struct _virQEMUCapsHostCPUData {
|
|||
unsigned int physAddrSize; |
|||
/* Host CPU definition reported in domain capabilities. */ |
|||
virCPUDef *reported; |
|||
+ /* Expanded host CPU definition with features that are implicitly enabled
|
|||
+ * by the selected CPU model. */
|
|||
+ virCPUDef *expanded;
|
|||
/* Migratable host CPU definition used for updating guest CPU. */ |
|||
virCPUDef *migratable; |
|||
/* CPU definition with features detected by libvirt using virCPUGetHost |
|||
@@ -1962,6 +1965,9 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUData *dst,
|
|||
if (src->reported) |
|||
dst->reported = virCPUDefCopy(src->reported); |
|||
|
|||
+ if (src->expanded)
|
|||
+ dst->expanded = virCPUDefCopy(src->expanded);
|
|||
+
|
|||
if (src->migratable) |
|||
dst->migratable = virCPUDefCopy(src->migratable); |
|||
|
|||
@@ -1975,6 +1981,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUData *cpuData)
|
|||
{ |
|||
qemuMonitorCPUModelInfoFree(cpuData->info); |
|||
virCPUDefFree(cpuData->reported); |
|||
+ virCPUDefFree(cpuData->expanded);
|
|||
virCPUDefFree(cpuData->migratable); |
|||
virCPUDefFree(cpuData->full); |
|||
|
|||
@@ -2301,6 +2308,9 @@ virQEMUCapsGetHostModel(virQEMUCaps *qemuCaps,
|
|||
/* 'full' is non-NULL only if we have data from both QEMU and |
|||
* virCPUGetHost */ |
|||
return cpuData->full ? cpuData->full : cpuData->reported; |
|||
+
|
|||
+ case VIR_QEMU_CAPS_HOST_CPU_EXPANDED:
|
|||
+ return cpuData->expanded;
|
|||
} |
|||
|
|||
return NULL; |
|||
@@ -2312,6 +2322,7 @@ virQEMUCapsSetHostModel(virQEMUCaps *qemuCaps,
|
|||
virDomainVirtType type, |
|||
unsigned int physAddrSize, |
|||
virCPUDef *reported, |
|||
+ virCPUDef *expanded,
|
|||
virCPUDef *migratable, |
|||
virCPUDef *full) |
|||
{ |
|||
@@ -2320,6 +2331,7 @@ virQEMUCapsSetHostModel(virQEMUCaps *qemuCaps,
|
|||
cpuData = &virQEMUCapsGetAccel(qemuCaps, type)->hostCPU; |
|||
cpuData->physAddrSize = physAddrSize; |
|||
cpuData->reported = reported; |
|||
+ cpuData->expanded = expanded;
|
|||
cpuData->migratable = migratable; |
|||
cpuData->full = full; |
|||
} |
|||
@@ -4123,16 +4135,18 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
|
|||
|
|||
virCPUDefCopyModelFilter(cpu, hostCPU, true, virQEMUCapsCPUFilterFeatures, |
|||
&qemuCaps->arch); |
|||
- } else if (virQEMUCapsTypeIsAccelerated(type) &&
|
|||
- virCPUGetHostIsSupported(qemuCaps->arch)) {
|
|||
+ }
|
|||
+
|
|||
+ cpuExpanded = virCPUDefCopy(cpu);
|
|||
+ if (virCPUExpandFeatures(qemuCaps->arch, cpuExpanded) < 0)
|
|||
+ goto error;
|
|||
+
|
|||
+ if (rc == 0 &&
|
|||
+ virQEMUCapsTypeIsAccelerated(type) &&
|
|||
+ virCPUGetHostIsSupported(qemuCaps->arch)) {
|
|||
if (!(fullCPU = virQEMUCapsProbeHostCPU(qemuCaps->arch, NULL))) |
|||
goto error; |
|||
|
|||
- cpuExpanded = virCPUDefCopy(cpu);
|
|||
-
|
|||
- if (virCPUExpandFeatures(qemuCaps->arch, cpuExpanded) < 0)
|
|||
- goto error;
|
|||
-
|
|||
for (i = 0; i < cpuExpanded->nfeatures; i++) { |
|||
if (cpuExpanded->features[i].policy == VIR_CPU_FEATURE_REQUIRE) |
|||
virCPUDefUpdateFeature(fullCPU, cpuExpanded->features[i].name, |
|||
@@ -4171,6 +4185,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
|
|||
|
|||
virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize, |
|||
g_steal_pointer(&cpu), |
|||
+ g_steal_pointer(&cpuExpanded),
|
|||
g_steal_pointer(&migCPU), |
|||
g_steal_pointer(&fullCPU)); |
|||
|
|||
@@ -6587,9 +6602,14 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
|
|||
virDomainCaps *domCaps, |
|||
unsigned int flags) |
|||
{ |
|||
- virQEMUCapsHostCPUType cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED;
|
|||
+ virQEMUCapsHostCPUType cpuType;
|
|||
virCPUDef *cpu; |
|||
|
|||
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
|
|||
+ cpuType = VIR_QEMU_CAPS_HOST_CPU_EXPANDED;
|
|||
+ else
|
|||
+ cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED;
|
|||
+
|
|||
cpu = virCPUDefCopy(virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype, |
|||
cpuType)); |
|||
|
|||
@@ -6600,9 +6620,6 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
|
|||
cpu, VIR_CPU_FEATURE_DISABLE); |
|||
} |
|||
|
|||
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
|
|||
- virCPUExpandFeatures(domCaps->arch, cpu);
|
|||
-
|
|||
virCPUDefSortFeatures(cpu); |
|||
domCaps->cpu.hostModel = cpu; |
|||
} |
|||
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
|
|||
index bc3ecbb89f..8822bf120b 100644
|
|||
--- a/src/qemu/qemu_capabilities.h
|
|||
+++ b/src/qemu/qemu_capabilities.h
|
|||
@@ -788,6 +788,9 @@ typedef enum {
|
|||
* combined with features reported by QEMU. This is used for backward |
|||
* compatible comparison between a guest CPU and a host CPU. */ |
|||
VIR_QEMU_CAPS_HOST_CPU_FULL, |
|||
+ /* Expanded host CPU definition with features that are implicitly enabled
|
|||
+ * by the selected CPU model. */
|
|||
+ VIR_QEMU_CAPS_HOST_CPU_EXPANDED,
|
|||
} virQEMUCapsHostCPUType; |
|||
|
|||
virCPUDef *virQEMUCapsGetHostModel(virQEMUCaps *qemuCaps, |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,156 @@ |
|||
From ce373eb396f931d5ebdd03105a3f1950eb842cfd Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <ce373eb396f931d5ebdd03105a3f1950eb842cfd.1780571167.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Mon, 25 May 2026 14:31:07 +0200 |
|||
Subject: [PATCH] qemu_capabilities: Fix domain capabilities on AMD CPUs |
|||
|
|||
The arch-capabilities MSR is not defined on AMD CPUs, but KVM has always |
|||
been emulating them. Unfortunately, this may cause Windows to crash so |
|||
QEMU (since 10.1, commit d3a24134e37d57abd3e7445842cda2717f49e96d) |
|||
decided to mask the MSR by default with some additional compatibility |
|||
code for older machine types. |
|||
|
|||
This is all mostly transparent except for probing when we run QEMU |
|||
without a machine type and expand the "host" CPU model. With QEMU 10.1 |
|||
and newer none of the arch-capabilities features will be shown as |
|||
enabled, which may cause unexpected issues for users (such as KubeVirt) |
|||
that get the list of all supported features from the host-model CPU |
|||
definition in domain capabilities to select possible target nodes for |
|||
migration. As a result of the change, no AMD host with new QEMU will be |
|||
shown as available for incoming migration from older hosts. |
|||
|
|||
Since the features are supported on the host (it's possible to |
|||
explicitly enable them), but they should not be enabled by default in |
|||
host-model CPU, we only add the to domain capabilities when |
|||
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag is set. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 54ff2058d6f7bb2547afebbd9c65c7b4b501e372) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Conflicts: |
|||
tests/domaincapsdata/qemu_11.0.0-q35.x86_64+sgx-supported.xml |
|||
tests/domaincapsdata/qemu_11.0.0-q35.x86_64-supported.xml |
|||
- QEMU 11.0 data do not exist downstream |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/qemu/qemu_capabilities.c | 24 +++++++++++++++++++ |
|||
src/qemu/qemu_driver.c | 3 ++- |
|||
.../qemu_10.1.0-q35.x86_64-supported.xml | 7 ++++++ |
|||
.../qemu_10.2.0-q35.x86_64-supported.xml | 7 ++++++ |
|||
4 files changed, 40 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
|||
index 555723cafb..f06f376dd7 100644
|
|||
--- a/src/qemu/qemu_capabilities.c
|
|||
+++ b/src/qemu/qemu_capabilities.c
|
|||
@@ -6604,6 +6604,7 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
|
|||
{ |
|||
virQEMUCapsHostCPUType cpuType; |
|||
virCPUDef *cpu; |
|||
+ virArch arch = domCaps->arch;
|
|||
|
|||
if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) |
|||
cpuType = VIR_QEMU_CAPS_HOST_CPU_EXPANDED; |
|||
@@ -6620,6 +6621,29 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
|
|||
cpu, VIR_CPU_FEATURE_DISABLE); |
|||
} |
|||
|
|||
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES) {
|
|||
+ uint32_t index = 0x10a; /* arch-capabilities MSR */
|
|||
+ uint64_t msr = 0;
|
|||
+
|
|||
+ /* While the arch-capabilities MSR is not defined on AMD CPUs, KVM has
|
|||
+ * always been emulating them. Unfortunately, this may cause some
|
|||
+ * Windows version to crash so QEMU decided to mask the MSR by default.
|
|||
+ * When asked for all CPU features supported on a host we need to add
|
|||
+ * the affected features to the host-model.
|
|||
+ */
|
|||
+ if (ARCH_IS_X86(arch) &&
|
|||
+ STREQ_NULLABLE(cpu->vendor, "AMD") &&
|
|||
+ virCPUCheckFeature(arch, cpu, "arch-capabilities") == 0 &&
|
|||
+ virHostCPUGetMSRFromKVM(index, &msr) == 0) {
|
|||
+ g_autoptr(virCPUData) data = virCPUDataNew(arch);
|
|||
+ virCPUFeaturePolicy policy = VIR_CPU_FEATURE_REQUIRE;
|
|||
+
|
|||
+ virCPUx86DataAddMSR(data, index, msr);
|
|||
+ virCPUUpdateFeatures(arch, cpu, data, policy);
|
|||
+ virCPUDefUpdateFeature(cpu, "arch-capabilities", policy);
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
virCPUDefSortFeatures(cpu); |
|||
domCaps->cpu.hostModel = cpu; |
|||
} |
|||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|||
index 0a61f97666..dcb49a9d42 100644
|
|||
--- a/src/qemu/qemu_driver.c
|
|||
+++ b/src/qemu/qemu_driver.c
|
|||
@@ -16721,7 +16721,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
|
|||
g_autoptr(virDomainCaps) domCaps = NULL; |
|||
|
|||
virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES | |
|||
- VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
|
|||
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES |
|
|||
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES,
|
|||
NULL); |
|||
|
|||
if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0) |
|||
diff --git a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml
|
|||
index 244fce575b..4ea61a6cbe 100644
|
|||
--- a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml
|
|||
+++ b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml
|
|||
@@ -45,17 +45,24 @@
|
|||
<vendor>AMD</vendor> |
|||
<maxphysaddr mode='passthrough' limit='64'/> |
|||
<feature policy='require' name='amd-ssbd'/> |
|||
+ <feature policy='require' name='arch-capabilities'/>
|
|||
<feature policy='require' name='cmp_legacy'/> |
|||
<feature policy='require' name='flushbyasid'/> |
|||
+ <feature policy='require' name='gds-no'/>
|
|||
<feature policy='require' name='hypervisor'/> |
|||
<feature policy='require' name='ibpb-brtype'/> |
|||
<feature policy='require' name='invtsc'/> |
|||
<feature policy='require' name='lbrv'/> |
|||
<feature policy='require' name='lfence-always-serializing'/> |
|||
+ <feature policy='require' name='mds-no'/>
|
|||
<feature policy='require' name='null-sel-clr-base'/> |
|||
<feature policy='require' name='overflow-recov'/> |
|||
<feature policy='require' name='pause-filter'/> |
|||
<feature policy='require' name='pfthreshold'/> |
|||
+ <feature policy='require' name='pschange-mc-no'/>
|
|||
+ <feature policy='require' name='rdctl-no'/>
|
|||
+ <feature policy='require' name='rfds-no'/>
|
|||
+ <feature policy='require' name='skip-l1dfl-vmentry'/>
|
|||
<feature policy='require' name='ssbd'/> |
|||
<feature policy='require' name='stibp'/> |
|||
<feature policy='require' name='succor'/> |
|||
diff --git a/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml b/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml
|
|||
index 9389141012..d9c0ea6f1d 100644
|
|||
--- a/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml
|
|||
+++ b/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml
|
|||
@@ -44,12 +44,19 @@
|
|||
<model fallback='forbid'>EPYC-Turin</model> |
|||
<vendor>AMD</vendor> |
|||
<maxphysaddr mode='passthrough' limit='64'/> |
|||
+ <feature policy='require' name='arch-capabilities'/>
|
|||
<feature policy='require' name='cmp_legacy'/> |
|||
<feature policy='require' name='flush-l1d'/> |
|||
+ <feature policy='require' name='gds-no'/>
|
|||
<feature policy='require' name='hypervisor'/> |
|||
<feature policy='require' name='invtsc'/> |
|||
<feature policy='disable' name='la57'/> |
|||
+ <feature policy='require' name='mds-no'/>
|
|||
<feature policy='disable' name='pcid'/> |
|||
+ <feature policy='require' name='pschange-mc-no'/>
|
|||
+ <feature policy='require' name='rdctl-no'/>
|
|||
+ <feature policy='require' name='rfds-no'/>
|
|||
+ <feature policy='require' name='skip-l1dfl-vmentry'/>
|
|||
<feature policy='require' name='spec-ctrl'/> |
|||
<feature policy='require' name='ssbd'/> |
|||
<feature policy='require' name='stibp'/> |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,71 @@ |
|||
From 1b72f3955f62a442b8482eed46e6456ba2e1c14b Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <1b72f3955f62a442b8482eed46e6456ba2e1c14b.1780571167.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Thu, 21 May 2026 17:30:21 +0200 |
|||
Subject: [PATCH] qemu_capabilities: Split conditions in |
|||
virQEMUCapsInitHostCPUModel |
|||
|
|||
Having 'else' after goto is useless. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 8b4f56447f32171671e18b82fbdfd478f2ec4293) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/qemu/qemu_capabilities.c | 22 +++++++++++++--------- |
|||
1 file changed, 13 insertions(+), 9 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
|||
index 2265dae7ba..2e8f220abc 100644
|
|||
--- a/src/qemu/qemu_capabilities.c
|
|||
+++ b/src/qemu/qemu_capabilities.c
|
|||
@@ -4102,9 +4102,17 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
|
|||
if (!(cpu = virQEMUCapsNewHostCPUModel())) |
|||
goto error; |
|||
|
|||
- if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
|
|||
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0)
|
|||
goto error; |
|||
- } else if (rc == 1) {
|
|||
+
|
|||
+ if (rc == 2) {
|
|||
+ VIR_DEBUG("QEMU does not provide CPU model for arch=%s virttype=%s",
|
|||
+ virArchToString(qemuCaps->arch),
|
|||
+ virDomainVirtTypeToString(type));
|
|||
+ goto error;
|
|||
+ }
|
|||
+
|
|||
+ if (rc == 1) {
|
|||
g_autoptr(virDomainCapsCPUModels) cpuModels = NULL; |
|||
|
|||
VIR_DEBUG("No host CPU model info from QEMU; probing host CPU directly"); |
|||
@@ -4115,11 +4123,6 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
|
|||
|
|||
virCPUDefCopyModelFilter(cpu, hostCPU, true, virQEMUCapsCPUFilterFeatures, |
|||
&qemuCaps->arch); |
|||
- } else if (rc == 2) {
|
|||
- VIR_DEBUG("QEMU does not provide CPU model for arch=%s virttype=%s",
|
|||
- virArchToString(qemuCaps->arch),
|
|||
- virDomainVirtTypeToString(type));
|
|||
- goto error;
|
|||
} else if (virQEMUCapsTypeIsAccelerated(type) && |
|||
virCPUGetHostIsSupported(qemuCaps->arch)) { |
|||
if (!(fullCPU = virQEMUCapsProbeHostCPU(qemuCaps->arch, NULL))) |
|||
@@ -4140,9 +4143,10 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
|
|||
if (!(migCPU = virQEMUCapsNewHostCPUModel())) |
|||
goto error; |
|||
|
|||
- if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0) {
|
|||
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0)
|
|||
goto error; |
|||
- } else if (rc == 1) {
|
|||
+
|
|||
+ if (rc == 1) {
|
|||
VIR_DEBUG("CPU migratability not provided by QEMU"); |
|||
|
|||
virCPUDefFree(migCPU); |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,150 @@ |
|||
From b41da9180160e455bf36d9db7870b64457a6ca8c Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <b41da9180160e455bf36d9db7870b64457a6ca8c.1780571166.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Thu, 21 May 2026 12:24:25 +0200 |
|||
Subject: [PATCH] qemu_capabilities: Split virQEMUCapsFillDomainCPUCaps |
|||
|
|||
Each CPU mode is filled in its own dedicated function. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 354ac21caba1da52d3d48e57c7395f899efc9ca4) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/qemu/qemu_capabilities.c | 96 ++++++++++++++++++++++++------------ |
|||
1 file changed, 64 insertions(+), 32 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
|||
index ed6aa86da2..0b32296cc8 100644
|
|||
--- a/src/qemu/qemu_capabilities.c
|
|||
+++ b/src/qemu/qemu_capabilities.c
|
|||
@@ -6553,6 +6553,66 @@ virQEMUCapsFillDomainOSCaps(virDomainCapsOS *os,
|
|||
} |
|||
|
|||
|
|||
+static void
|
|||
+virQEMUCapsFillDomainCPUHostPassthrough(virQEMUCaps *qemuCaps,
|
|||
+ virDomainCaps *domCaps)
|
|||
+{
|
|||
+ domCaps->cpu.hostPassthrough = true;
|
|||
+
|
|||
+ domCaps->cpu.hostPassthroughMigratable.report = true;
|
|||
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_MIGRATABLE)) {
|
|||
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
|
|||
+ VIR_TRISTATE_SWITCH_ON);
|
|||
+ }
|
|||
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
|
|||
+ VIR_TRISTATE_SWITCH_OFF);
|
|||
+}
|
|||
+
|
|||
+
|
|||
+static void
|
|||
+virQEMUCapsFillDomainCPUMaximum(virDomainCaps *domCaps)
|
|||
+{
|
|||
+ domCaps->cpu.maximum = true;
|
|||
+
|
|||
+ domCaps->cpu.maximumMigratable.report = true;
|
|||
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
|
|||
+ VIR_TRISTATE_SWITCH_ON);
|
|||
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
|
|||
+ VIR_TRISTATE_SWITCH_OFF);
|
|||
+}
|
|||
+
|
|||
+
|
|||
+static void
|
|||
+virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
|
|||
+ virDomainCaps *domCaps)
|
|||
+{
|
|||
+ virCPUDef *cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
|
|||
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
|
|||
+
|
|||
+ domCaps->cpu.hostModel = virCPUDefCopy(cpu);
|
|||
+ domCaps->cpu.hostModel->addr = virQEMUCapsGetHostPhysAddr(qemuCaps,
|
|||
+ domCaps->virttype);
|
|||
+}
|
|||
+
|
|||
+
|
|||
+static void
|
|||
+virQEMUCapsFillDomainCPUCustom(virQEMUCaps *qemuCaps,
|
|||
+ virDomainCaps *domCaps)
|
|||
+{
|
|||
+ const char *forbidden[] = { "host", NULL };
|
|||
+ g_auto(GStrv) models = NULL;
|
|||
+
|
|||
+ if (virCPUGetModels(domCaps->arch, &models) >= 0) {
|
|||
+ domCaps->cpu.custom = virQEMUCapsGetCPUModels(qemuCaps,
|
|||
+ domCaps->virttype,
|
|||
+ (const char **)models,
|
|||
+ forbidden);
|
|||
+ } else {
|
|||
+ domCaps->cpu.custom = NULL;
|
|||
+ }
|
|||
+}
|
|||
+
|
|||
+
|
|||
static void |
|||
virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps, |
|||
virArch hostarch, |
|||
@@ -6561,53 +6621,25 @@ virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
|
|||
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype, |
|||
VIR_CPU_MODE_HOST_PASSTHROUGH, |
|||
domCaps->machine)) { |
|||
- domCaps->cpu.hostPassthrough = true;
|
|||
-
|
|||
- domCaps->cpu.hostPassthroughMigratable.report = true;
|
|||
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_MIGRATABLE)) {
|
|||
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
|
|||
- VIR_TRISTATE_SWITCH_ON);
|
|||
- }
|
|||
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
|
|||
- VIR_TRISTATE_SWITCH_OFF);
|
|||
+ virQEMUCapsFillDomainCPUHostPassthrough(qemuCaps, domCaps);
|
|||
} |
|||
|
|||
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype, |
|||
VIR_CPU_MODE_MAXIMUM, |
|||
domCaps->machine)) { |
|||
- domCaps->cpu.maximum = true;
|
|||
-
|
|||
- domCaps->cpu.maximumMigratable.report = true;
|
|||
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
|
|||
- VIR_TRISTATE_SWITCH_ON);
|
|||
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
|
|||
- VIR_TRISTATE_SWITCH_OFF);
|
|||
+ virQEMUCapsFillDomainCPUMaximum(domCaps);
|
|||
} |
|||
|
|||
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype, |
|||
VIR_CPU_MODE_HOST_MODEL, |
|||
domCaps->machine)) { |
|||
- virCPUDef *cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
|
|||
- VIR_QEMU_CAPS_HOST_CPU_REPORTED);
|
|||
- domCaps->cpu.hostModel = virCPUDefCopy(cpu);
|
|||
- domCaps->cpu.hostModel->addr = virQEMUCapsGetHostPhysAddr(qemuCaps,
|
|||
- domCaps->virttype);
|
|||
+ virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps);
|
|||
} |
|||
|
|||
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype, |
|||
VIR_CPU_MODE_CUSTOM, |
|||
domCaps->machine)) { |
|||
- const char *forbidden[] = { "host", NULL };
|
|||
- g_auto(GStrv) models = NULL;
|
|||
-
|
|||
- if (virCPUGetModels(domCaps->arch, &models) >= 0) {
|
|||
- domCaps->cpu.custom = virQEMUCapsGetCPUModels(qemuCaps,
|
|||
- domCaps->virttype,
|
|||
- (const char **)models,
|
|||
- forbidden);
|
|||
- } else {
|
|||
- domCaps->cpu.custom = NULL;
|
|||
- }
|
|||
+ virQEMUCapsFillDomainCPUCustom(qemuCaps, domCaps);
|
|||
} |
|||
} |
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,65 @@ |
|||
From 2141acf3d9891c1451d741abc1d043e35b1ed074 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <2141acf3d9891c1451d741abc1d043e35b1ed074.1780571167.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Thu, 21 May 2026 14:15:01 +0200 |
|||
Subject: [PATCH] qemu_capabilities: Use g_autoptr in |
|||
virQEMUCapsInitHostCPUModel |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit eca4c6672d3f373bb9cff271adfc2cd8b13cb4bc) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/qemu/qemu_capabilities.c | 22 +++++++++------------- |
|||
1 file changed, 9 insertions(+), 13 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
|||
index 6951e50c03..2265dae7ba 100644
|
|||
--- a/src/qemu/qemu_capabilities.c
|
|||
+++ b/src/qemu/qemu_capabilities.c
|
|||
@@ -4087,11 +4087,11 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
|
|||
virArch hostArch, |
|||
virDomainVirtType type) |
|||
{ |
|||
- virCPUDef *cpu = NULL;
|
|||
- virCPUDef *cpuExpanded = NULL;
|
|||
- virCPUDef *migCPU = NULL;
|
|||
- virCPUDef *hostCPU = NULL;
|
|||
- virCPUDef *fullCPU = NULL;
|
|||
+ g_autoptr(virCPUDef) cpu = NULL;
|
|||
+ g_autoptr(virCPUDef) cpuExpanded = NULL;
|
|||
+ g_autoptr(virCPUDef) migCPU = NULL;
|
|||
+ g_autoptr(virCPUDef) hostCPU = NULL;
|
|||
+ g_autoptr(virCPUDef) fullCPU = NULL;
|
|||
unsigned int physAddrSize = 0; |
|||
size_t i; |
|||
int rc; |
|||
@@ -4165,19 +4165,15 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
|
|||
if (virQEMUCapsTypeIsAccelerated(type)) |
|||
virHostCPUGetPhysAddrSize(hostArch, &physAddrSize); |
|||
|
|||
- virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize, cpu, migCPU, fullCPU);
|
|||
+ virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize,
|
|||
+ g_steal_pointer(&cpu),
|
|||
+ g_steal_pointer(&migCPU),
|
|||
+ g_steal_pointer(&fullCPU));
|
|||
|
|||
- cleanup:
|
|||
- virCPUDefFree(cpuExpanded);
|
|||
- virCPUDefFree(hostCPU);
|
|||
return; |
|||
|
|||
error: |
|||
- virCPUDefFree(cpu);
|
|||
- virCPUDefFree(migCPU);
|
|||
- virCPUDefFree(fullCPU);
|
|||
virResetLastError(); |
|||
- goto cleanup;
|
|||
} |
|||
|
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,611 @@ |
|||
From ab58ab56b88b4a5fc4a2d5dc85b249220951ce36 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <ab58ab56b88b4a5fc4a2d5dc85b249220951ce36.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Mon, 2 Mar 2026 12:46:00 +0100 |
|||
Subject: [PATCH] security: Cleanup hostdev label error logic |
|||
MIME-Version: 1.0 |
|||
Content-Type: text/plain; charset=UTF-8 |
|||
Content-Transfer-Encoding: 8bit |
|||
|
|||
Current code used mix of return, goto, break and setting ret variable. |
|||
Simplify the logic to just return -1 on error. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Ján Tomko <jtomko@redhat.com> |
|||
(cherry picked from commit b7483e6558acbb0d80e2ff2c3648ca63cb7f41f9) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-159902 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/security/security_apparmor.c | 56 +++++++++-------- |
|||
src/security/security_dac.c | 103 ++++++++++++++++++------------- |
|||
src/security/security_selinux.c | 87 ++++++++++++++------------ |
|||
3 files changed, 139 insertions(+), 107 deletions(-) |
|||
|
|||
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
|
|||
index 74c5b10063..1c3496893c 100644
|
|||
--- a/src/security/security_apparmor.c
|
|||
+++ b/src/security/security_apparmor.c
|
|||
@@ -800,7 +800,6 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
const char *vroot) |
|||
{ |
|||
g_autofree struct SDPDOP *ptr = NULL; |
|||
- int ret = -1;
|
|||
virSecurityLabelDef *secdef = |
|||
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME); |
|||
virDomainHostdevSubsysUSB *usbsrc = &dev->source.subsys.u.usb; |
|||
@@ -834,9 +833,10 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
g_autoptr(virUSBDevice) usb = |
|||
virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot); |
|||
if (!usb) |
|||
- goto done;
|
|||
+ return -1;
|
|||
|
|||
- ret = virUSBDeviceFileIterate(usb, AppArmorSetSecurityUSBLabel, ptr);
|
|||
+ if (virUSBDeviceFileIterate(usb, AppArmorSetSecurityUSBLabel, ptr) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
@@ -845,30 +845,32 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
virPCIDeviceNew(&pcisrc->addr); |
|||
|
|||
if (!pci) |
|||
- goto done;
|
|||
+ return -1;
|
|||
|
|||
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { |
|||
if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) { |
|||
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); |
|||
|
|||
- if (!vfioGroupDev) {
|
|||
- goto done;
|
|||
- }
|
|||
- ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr);
|
|||
+ if (!vfioGroupDev)
|
|||
+ return -1;
|
|||
+
|
|||
+ if (AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr) < 0)
|
|||
+ return -1;
|
|||
} else { |
|||
g_autofree char *vfiofdDev = NULL; |
|||
|
|||
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0) |
|||
- goto done;
|
|||
+ return -1;
|
|||
|
|||
- ret = AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr);
|
|||
- if (ret < 0)
|
|||
- goto done;
|
|||
+ if (AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr) < 0)
|
|||
+ return -1;
|
|||
|
|||
- ret = AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr);
|
|||
+ if (AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr) < 0)
|
|||
+ return -1;
|
|||
} |
|||
} else { |
|||
- ret = virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr);
|
|||
+ if (virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr) < 0)
|
|||
+ return -1;
|
|||
} |
|||
break; |
|||
} |
|||
@@ -881,10 +883,11 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
scsihostsrc->target, scsihostsrc->unit, |
|||
dev->readonly, dev->shareable); |
|||
|
|||
- if (!scsi)
|
|||
- goto done;
|
|||
+ if (!scsi)
|
|||
+ return -1;
|
|||
|
|||
- ret = virSCSIDeviceFileIterate(scsi, AppArmorSetSecuritySCSILabel, ptr);
|
|||
+ if (virSCSIDeviceFileIterate(scsi, AppArmorSetSecuritySCSILabel, ptr) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
@@ -892,11 +895,13 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
g_autoptr(virSCSIVHostDevice) host = virSCSIVHostDeviceNew(hostsrc->wwpn); |
|||
|
|||
if (!host) |
|||
- goto done;
|
|||
+ return -1;
|
|||
|
|||
- ret = virSCSIVHostDeviceFileIterate(host,
|
|||
- AppArmorSetSecurityHostLabel,
|
|||
- ptr);
|
|||
+ if (virSCSIVHostDeviceFileIterate(host,
|
|||
+ AppArmorSetSecurityHostLabel,
|
|||
+ ptr) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
break; |
|||
} |
|||
|
|||
@@ -904,19 +909,18 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
g_autofree char *vfiodev = NULL; |
|||
|
|||
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr))) |
|||
- goto done;
|
|||
+ return -1;
|
|||
|
|||
- ret = AppArmorSetSecurityHostdevLabelHelper(vfiodev, ptr);
|
|||
+ if (AppArmorSetSecurityHostdevLabelHelper(vfiodev, ptr) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: |
|||
- ret = 0;
|
|||
break; |
|||
} |
|||
|
|||
- done:
|
|||
- return ret;
|
|||
+ return 0;
|
|||
} |
|||
|
|||
|
|||
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
|
|||
index 704c8dbfec..2a4c7f6a3c 100644
|
|||
--- a/src/security/security_dac.c
|
|||
+++ b/src/security/security_dac.c
|
|||
@@ -1234,7 +1234,6 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
|
|||
virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi; |
|||
virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host; |
|||
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev; |
|||
- int ret = -1;
|
|||
|
|||
if (!priv->dynamicOwnership) |
|||
return 0; |
|||
@@ -1265,9 +1264,11 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
|
|||
if (!(usb = virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot))) |
|||
return -1; |
|||
|
|||
- ret = virUSBDeviceFileIterate(usb,
|
|||
- virSecurityDACSetUSBLabel,
|
|||
- &cbdata);
|
|||
+ if (virUSBDeviceFileIterate(usb,
|
|||
+ virSecurityDACSetUSBLabel,
|
|||
+ &cbdata) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
break; |
|||
} |
|||
|
|||
@@ -1275,7 +1276,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
|
|||
g_autoptr(virPCIDevice) pci = NULL; |
|||
|
|||
if (!virPCIDeviceExists(&pcisrc->addr)) |
|||
- break;
|
|||
+ return -1;
|
|||
|
|||
pci = virPCIDeviceNew(&pcisrc->addr); |
|||
|
|||
@@ -1289,25 +1290,29 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
|
|||
if (!vfioGroupDev) |
|||
return -1; |
|||
|
|||
- ret = virSecurityDACSetHostdevLabelHelper(vfioGroupDev,
|
|||
- false,
|
|||
- &cbdata);
|
|||
+ if (virSecurityDACSetHostdevLabelHelper(vfioGroupDev,
|
|||
+ false,
|
|||
+ &cbdata) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
} else { |
|||
g_autofree char *vfiofdDev = NULL; |
|||
|
|||
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0) |
|||
return -1; |
|||
|
|||
- ret = virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata);
|
|||
- if (ret < 0)
|
|||
- break;
|
|||
+ if (virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata) < 0)
|
|||
+ return -1;
|
|||
|
|||
- ret = virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata);
|
|||
+ if (virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata) < 0)
|
|||
+ return -1;
|
|||
} |
|||
} else { |
|||
- ret = virPCIDeviceFileIterate(pci,
|
|||
- virSecurityDACSetPCILabel,
|
|||
- &cbdata);
|
|||
+ if (virPCIDeviceFileIterate(pci,
|
|||
+ virSecurityDACSetPCILabel,
|
|||
+ &cbdata) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
} |
|||
break; |
|||
} |
|||
@@ -1323,9 +1328,11 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
|
|||
if (!scsi) |
|||
return -1; |
|||
|
|||
- ret = virSCSIDeviceFileIterate(scsi,
|
|||
- virSecurityDACSetSCSILabel,
|
|||
- &cbdata);
|
|||
+ if (virSCSIDeviceFileIterate(scsi,
|
|||
+ virSecurityDACSetSCSILabel,
|
|||
+ &cbdata) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
break; |
|||
} |
|||
|
|||
@@ -1335,9 +1342,11 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
|
|||
if (!host) |
|||
return -1; |
|||
|
|||
- ret = virSCSIVHostDeviceFileIterate(host,
|
|||
- virSecurityDACSetHostLabel,
|
|||
- &cbdata);
|
|||
+ if (virSCSIVHostDeviceFileIterate(host,
|
|||
+ virSecurityDACSetHostLabel,
|
|||
+ &cbdata) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
break; |
|||
} |
|||
|
|||
@@ -1347,16 +1356,16 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
|
|||
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr))) |
|||
return -1; |
|||
|
|||
- ret = virSecurityDACSetHostdevLabelHelper(vfiodev, false, &cbdata);
|
|||
+ if (virSecurityDACSetHostdevLabelHelper(vfiodev, false, &cbdata) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: |
|||
- ret = 0;
|
|||
break; |
|||
} |
|||
|
|||
- return ret;
|
|||
+ return 0;
|
|||
} |
|||
|
|||
|
|||
@@ -1414,7 +1423,6 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
|
|||
virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi; |
|||
virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host; |
|||
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev; |
|||
- int ret = -1;
|
|||
|
|||
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME); |
|||
|
|||
@@ -1441,7 +1449,8 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
|
|||
if (!(usb = virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot))) |
|||
return -1; |
|||
|
|||
- ret = virUSBDeviceFileIterate(usb, virSecurityDACRestoreUSBLabel, mgr);
|
|||
+ if (virUSBDeviceFileIterate(usb, virSecurityDACRestoreUSBLabel, mgr) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
@@ -1449,7 +1458,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
|
|||
g_autoptr(virPCIDevice) pci = NULL; |
|||
|
|||
if (!virPCIDeviceExists(&pcisrc->addr)) |
|||
- break;
|
|||
+ return -1;
|
|||
|
|||
pci = virPCIDeviceNew(&pcisrc->addr); |
|||
|
|||
@@ -1463,24 +1472,29 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
|
|||
if (!vfioGroupDev) |
|||
return -1; |
|||
|
|||
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
|
|||
- vfioGroupDev, false);
|
|||
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
|
|||
+ vfioGroupDev, false) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
} else { |
|||
g_autofree char *vfiofdDev = NULL; |
|||
|
|||
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0) |
|||
return -1; |
|||
|
|||
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
|
|||
- vfiofdDev, false);
|
|||
- if (ret < 0)
|
|||
- break;
|
|||
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
|
|||
+ vfiofdDev, false) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
|
|||
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
|
|||
- VIR_IOMMU_DEV_PATH, false);
|
|||
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
|
|||
+ VIR_IOMMU_DEV_PATH, false) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
} |
|||
} else { |
|||
- ret = virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr);
|
|||
+ if (virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr) < 0)
|
|||
+ return -1;
|
|||
} |
|||
break; |
|||
} |
|||
@@ -1496,7 +1510,8 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
|
|||
if (!scsi) |
|||
return -1; |
|||
|
|||
- ret = virSCSIDeviceFileIterate(scsi, virSecurityDACRestoreSCSILabel, mgr);
|
|||
+ if (virSCSIDeviceFileIterate(scsi, virSecurityDACRestoreSCSILabel, mgr) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
@@ -1506,9 +1521,11 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
|
|||
if (!host) |
|||
return -1; |
|||
|
|||
- ret = virSCSIVHostDeviceFileIterate(host,
|
|||
- virSecurityDACRestoreHostLabel,
|
|||
- mgr);
|
|||
+ if (virSCSIVHostDeviceFileIterate(host,
|
|||
+ virSecurityDACRestoreHostLabel,
|
|||
+ mgr) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
break; |
|||
} |
|||
|
|||
@@ -1518,16 +1535,16 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
|
|||
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr))) |
|||
return -1; |
|||
|
|||
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL, vfiodev, false);
|
|||
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL, vfiodev, false) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: |
|||
- ret = 0;
|
|||
break; |
|||
} |
|||
|
|||
- return ret;
|
|||
+ return 0;
|
|||
} |
|||
|
|||
|
|||
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
|
|||
index 4a5f61d16b..96ca59a7a4 100644
|
|||
--- a/src/security/security_selinux.c
|
|||
+++ b/src/security/security_selinux.c
|
|||
@@ -2219,8 +2219,6 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev; |
|||
virSecuritySELinuxCallbackData data = {.mgr = mgr, .def = def}; |
|||
|
|||
- int ret = -1;
|
|||
-
|
|||
/* Like virSecuritySELinuxSetImageLabelInternal() for a networked |
|||
* disk, do nothing for an iSCSI hostdev |
|||
*/ |
|||
@@ -2241,7 +2239,8 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
if (!usb) |
|||
return -1; |
|||
|
|||
- ret = virUSBDeviceFileIterate(usb, virSecuritySELinuxSetUSBLabel, &data);
|
|||
+ if (virUSBDeviceFileIterate(usb, virSecuritySELinuxSetUSBLabel, &data) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
@@ -2249,7 +2248,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
g_autoptr(virPCIDevice) pci = NULL; |
|||
|
|||
if (!virPCIDeviceExists(&pcisrc->addr)) |
|||
- break;
|
|||
+ return -1;
|
|||
|
|||
pci = virPCIDeviceNew(&pcisrc->addr); |
|||
|
|||
@@ -2263,23 +2262,26 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
if (!vfioGroupDev) |
|||
return -1; |
|||
|
|||
- ret = virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev,
|
|||
- false,
|
|||
- &data);
|
|||
+ if (virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev,
|
|||
+ false,
|
|||
+ &data) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
} else { |
|||
g_autofree char *vfiofdDev = NULL; |
|||
|
|||
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0) |
|||
return -1; |
|||
|
|||
- ret = virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data);
|
|||
- if (ret)
|
|||
- break;
|
|||
+ if (virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data) < 0)
|
|||
+ return -1;
|
|||
|
|||
- ret = virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data);
|
|||
+ if (virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data) < 0)
|
|||
+ return -1;
|
|||
} |
|||
} else { |
|||
- ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data);
|
|||
+ if (virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data) < 0)
|
|||
+ return -1;
|
|||
} |
|||
break; |
|||
} |
|||
@@ -2296,9 +2298,11 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
if (!scsi) |
|||
return -1; |
|||
|
|||
- ret = virSCSIDeviceFileIterate(scsi,
|
|||
- virSecuritySELinuxSetSCSILabel,
|
|||
- &data);
|
|||
+ if (virSCSIDeviceFileIterate(scsi,
|
|||
+ virSecuritySELinuxSetSCSILabel,
|
|||
+ &data) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
break; |
|||
} |
|||
|
|||
@@ -2308,9 +2312,11 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
if (!host) |
|||
return -1; |
|||
|
|||
- ret = virSCSIVHostDeviceFileIterate(host,
|
|||
- virSecuritySELinuxSetHostLabel,
|
|||
- &data);
|
|||
+ if (virSCSIVHostDeviceFileIterate(host,
|
|||
+ virSecuritySELinuxSetHostLabel,
|
|||
+ &data) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
break; |
|||
} |
|||
|
|||
@@ -2318,18 +2324,18 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
g_autofree char *vfiodev = NULL; |
|||
|
|||
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr))) |
|||
- return ret;
|
|||
+ return -1;
|
|||
|
|||
- ret = virSecuritySELinuxSetHostdevLabelHelper(vfiodev, false, &data);
|
|||
+ if (virSecuritySELinuxSetHostdevLabelHelper(vfiodev, false, &data) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: |
|||
- ret = 0;
|
|||
break; |
|||
} |
|||
|
|||
- return ret;
|
|||
+ return 0;
|
|||
} |
|||
|
|||
|
|||
@@ -2467,7 +2473,6 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi; |
|||
virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host; |
|||
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev; |
|||
- int ret = -1;
|
|||
|
|||
/* Like virSecuritySELinuxRestoreImageLabelInt() for a networked |
|||
* disk, do nothing for an iSCSI hostdev |
|||
@@ -2489,7 +2494,8 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
if (!usb) |
|||
return -1; |
|||
|
|||
- ret = virUSBDeviceFileIterate(usb, virSecuritySELinuxRestoreUSBLabel, mgr);
|
|||
+ if (virUSBDeviceFileIterate(usb, virSecuritySELinuxRestoreUSBLabel, mgr) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
@@ -2497,7 +2503,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
g_autoptr(virPCIDevice) pci = NULL; |
|||
|
|||
if (!virPCIDeviceExists(&pcisrc->addr)) |
|||
- break;
|
|||
+ return -1;
|
|||
|
|||
pci = virPCIDeviceNew(&pcisrc->addr); |
|||
|
|||
@@ -2511,21 +2517,23 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
if (!vfioGroupDev) |
|||
return -1; |
|||
|
|||
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false);
|
|||
+ if (virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false) < 0)
|
|||
+ return -1;
|
|||
} else { |
|||
g_autofree char *vfiofdDev = NULL; |
|||
|
|||
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0) |
|||
return -1; |
|||
|
|||
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false);
|
|||
- if (ret < 0)
|
|||
- break;
|
|||
+ if (virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false) < 0)
|
|||
+ return -1;
|
|||
|
|||
- ret = virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false);
|
|||
+ if (virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false) < 0)
|
|||
+ return -1;
|
|||
} |
|||
} else { |
|||
- ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr);
|
|||
+ if (virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr) < 0)
|
|||
+ return -1;
|
|||
} |
|||
break; |
|||
} |
|||
@@ -2541,7 +2549,8 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
if (!scsi) |
|||
return -1; |
|||
|
|||
- ret = virSCSIDeviceFileIterate(scsi, virSecuritySELinuxRestoreSCSILabel, mgr);
|
|||
+ if (virSCSIDeviceFileIterate(scsi, virSecuritySELinuxRestoreSCSILabel, mgr) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
@@ -2551,9 +2560,11 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
if (!host) |
|||
return -1; |
|||
|
|||
- ret = virSCSIVHostDeviceFileIterate(host,
|
|||
- virSecuritySELinuxRestoreHostLabel,
|
|||
- mgr);
|
|||
+ if (virSCSIVHostDeviceFileIterate(host,
|
|||
+ virSecuritySELinuxRestoreHostLabel,
|
|||
+ mgr) < 0) {
|
|||
+ return -1;
|
|||
+ }
|
|||
break; |
|||
} |
|||
|
|||
@@ -2563,16 +2574,16 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr))) |
|||
return -1; |
|||
|
|||
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiodev, false, false);
|
|||
+ if (virSecuritySELinuxRestoreFileLabel(mgr, vfiodev, false, false) < 0)
|
|||
+ return -1;
|
|||
break; |
|||
} |
|||
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: |
|||
- ret = 0;
|
|||
break; |
|||
} |
|||
|
|||
- return ret;
|
|||
+ return 0;
|
|||
} |
|||
|
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,118 @@ |
|||
From b2037dd33febe910a6dad3521549b747322d37cb Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <b2037dd33febe910a6dad3521549b747322d37cb.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Mon, 2 Mar 2026 12:47:43 +0100 |
|||
Subject: [PATCH] security_apparmor: Use g_auto* in |
|||
AppArmorSetSecurityHostdevLabel |
|||
MIME-Version: 1.0 |
|||
Content-Type: text/plain; charset=UTF-8 |
|||
Content-Transfer-Encoding: 8bit |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Ján Tomko <jtomko@redhat.com> |
|||
(cherry picked from commit 75f698c77f0705ae9793331eadb08fbbf89572f6) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-159902 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/security/security_apparmor.c | 20 ++++++-------------- |
|||
1 file changed, 6 insertions(+), 14 deletions(-) |
|||
|
|||
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
|
|||
index 6c5da2a650..74c5b10063 100644
|
|||
--- a/src/security/security_apparmor.c
|
|||
+++ b/src/security/security_apparmor.c
|
|||
@@ -799,7 +799,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
virDomainHostdevDef *dev, |
|||
const char *vroot) |
|||
{ |
|||
- struct SDPDOP *ptr;
|
|||
+ g_autofree struct SDPDOP *ptr = NULL;
|
|||
int ret = -1; |
|||
virSecurityLabelDef *secdef = |
|||
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME); |
|||
@@ -831,13 +831,12 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
|
|||
switch (dev->source.subsys.type) { |
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: { |
|||
- virUSBDevice *usb =
|
|||
+ g_autoptr(virUSBDevice) usb =
|
|||
virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot); |
|||
if (!usb) |
|||
goto done; |
|||
|
|||
ret = virUSBDeviceFileIterate(usb, AppArmorSetSecurityUSBLabel, ptr); |
|||
- virUSBDeviceFree(usb);
|
|||
break; |
|||
} |
|||
|
|||
@@ -850,13 +849,12 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
|
|||
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { |
|||
if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) { |
|||
- char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
|
|||
+ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
|
|||
|
|||
if (!vfioGroupDev) { |
|||
goto done; |
|||
} |
|||
ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr); |
|||
- VIR_FREE(vfioGroupDev);
|
|||
} else { |
|||
g_autofree char *vfiofdDev = NULL; |
|||
|
|||
@@ -877,7 +875,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: { |
|||
virDomainHostdevSubsysSCSIHost *scsihostsrc = &scsisrc->u.host; |
|||
- virSCSIDevice *scsi =
|
|||
+ g_autoptr(virSCSIDevice) scsi =
|
|||
virSCSIDeviceNew(NULL, |
|||
scsihostsrc->adapter, scsihostsrc->bus, |
|||
scsihostsrc->target, scsihostsrc->unit, |
|||
@@ -887,13 +885,11 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
goto done; |
|||
|
|||
ret = virSCSIDeviceFileIterate(scsi, AppArmorSetSecuritySCSILabel, ptr); |
|||
- virSCSIDeviceFree(scsi);
|
|||
-
|
|||
break; |
|||
} |
|||
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: { |
|||
- virSCSIVHostDevice *host = virSCSIVHostDeviceNew(hostsrc->wwpn);
|
|||
+ g_autoptr(virSCSIVHostDevice) host = virSCSIVHostDeviceNew(hostsrc->wwpn);
|
|||
|
|||
if (!host) |
|||
goto done; |
|||
@@ -901,19 +897,16 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
ret = virSCSIVHostDeviceFileIterate(host, |
|||
AppArmorSetSecurityHostLabel, |
|||
ptr); |
|||
- virSCSIVHostDeviceFree(host);
|
|||
break; |
|||
} |
|||
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: { |
|||
- char *vfiodev = NULL;
|
|||
+ g_autofree char *vfiodev = NULL;
|
|||
|
|||
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr))) |
|||
goto done; |
|||
|
|||
ret = AppArmorSetSecurityHostdevLabelHelper(vfiodev, ptr); |
|||
-
|
|||
- VIR_FREE(vfiodev);
|
|||
break; |
|||
} |
|||
|
|||
@@ -923,7 +916,6 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
} |
|||
|
|||
done: |
|||
- VIR_FREE(ptr);
|
|||
return ret; |
|||
} |
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,152 @@ |
|||
From 8442235a61de81d3572cc955a0b40969347fa6a1 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <8442235a61de81d3572cc955a0b40969347fa6a1.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Fri, 13 Mar 2026 12:25:13 +0100 |
|||
Subject: [PATCH] src: Use virHostdevIsPCIDeviceWith* to check for IOMMUFD |
|||
|
|||
Use virHostdevIsPCIDeviceWithIOMMUFD where we need to check if hostdev |
|||
is PCI device using IOMMUFD and virHostdevIsPCIDeviceWithoutIOMMUFD |
|||
where we need to check if hostdev is PCI device not using IOMMUFD. |
|||
|
|||
Fixes: 7d2f91f9cb572ab95d0916bdd1a46dd198874529 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit c1d38e9428783730f063b59ad32f08d2e80aff9f) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/qemu/qemu_cgroup.c | 2 +- |
|||
src/qemu/qemu_command.c | 2 +- |
|||
src/qemu/qemu_namespace.c | 2 +- |
|||
src/qemu/qemu_validate.c | 2 +- |
|||
src/security/security_apparmor.c | 2 +- |
|||
src/security/security_dac.c | 4 ++-- |
|||
src/security/security_selinux.c | 4 ++-- |
|||
src/security/virt-aa-helper.c | 2 +- |
|||
8 files changed, 10 insertions(+), 10 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
|
|||
index 6148990f19..0e1815f571 100644
|
|||
--- a/src/qemu/qemu_cgroup.c
|
|||
+++ b/src/qemu/qemu_cgroup.c
|
|||
@@ -479,7 +479,7 @@ qemuSetupHostdevCgroup(virDomainObj *vm,
|
|||
g_autofree char *path = NULL; |
|||
int perms; |
|||
|
|||
- if (dev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES)
|
|||
+ if (virHostdevIsPCIDeviceWithIOMMUFD(dev))
|
|||
return 0; |
|||
|
|||
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) |
|||
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|||
index db512f6757..23e799de3c 100644
|
|||
--- a/src/qemu/qemu_command.c
|
|||
+++ b/src/qemu/qemu_command.c
|
|||
@@ -5259,7 +5259,7 @@ qemuBuildHostdevCommandLine(virCommand *cmd,
|
|||
if (qemuCommandAddExtDevice(cmd, hostdev->info, def, qemuCaps) < 0) |
|||
return -1; |
|||
|
|||
- if (subsys->u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) {
|
|||
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
|
|||
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); |
|||
|
|||
qemuFDPassDirectTransferCommand(hostdevPriv->vfioDeviceFd, cmd); |
|||
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
|
|||
index fb0734193d..4a063064f1 100644
|
|||
--- a/src/qemu/qemu_namespace.c
|
|||
+++ b/src/qemu/qemu_namespace.c
|
|||
@@ -345,7 +345,7 @@ qemuDomainSetupHostdev(virDomainObj *vm,
|
|||
{ |
|||
g_autofree char *path = NULL; |
|||
|
|||
- if (hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES)
|
|||
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev))
|
|||
return 0; |
|||
|
|||
if (qemuDomainGetHostdevPath(hostdev, &path, NULL) < 0) |
|||
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
|
|||
index 5c8c21335d..63c5f8e037 100644
|
|||
--- a/src/qemu/qemu_validate.c
|
|||
+++ b/src/qemu/qemu_validate.c
|
|||
@@ -2722,7 +2722,7 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev,
|
|||
return -1; |
|||
} |
|||
|
|||
- if (hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) {
|
|||
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
|
|||
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOMMUFD)) { |
|||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", |
|||
_("IOMMUFD is not supported by this version of qemu")); |
|||
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
|
|||
index 40f13ec1a5..e53486ee0c 100644
|
|||
--- a/src/security/security_apparmor.c
|
|||
+++ b/src/security/security_apparmor.c
|
|||
@@ -847,7 +847,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|||
return -1; |
|||
|
|||
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { |
|||
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
|
|||
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
|
|||
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); |
|||
|
|||
if (!vfioGroupDev) |
|||
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
|
|||
index d8cf117fc4..b891f6f121 100644
|
|||
--- a/src/security/security_dac.c
|
|||
+++ b/src/security/security_dac.c
|
|||
@@ -1283,7 +1283,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
|
|||
return -1; |
|||
|
|||
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { |
|||
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
|
|||
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
|
|||
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); |
|||
|
|||
if (!vfioGroupDev) |
|||
@@ -1454,7 +1454,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
|
|||
return -1; |
|||
|
|||
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { |
|||
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
|
|||
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
|
|||
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); |
|||
|
|||
if (!vfioGroupDev) |
|||
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
|
|||
index 0fa50630f7..2b801aecd5 100644
|
|||
--- a/src/security/security_selinux.c
|
|||
+++ b/src/security/security_selinux.c
|
|||
@@ -2255,7 +2255,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
return -1; |
|||
|
|||
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { |
|||
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
|
|||
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
|
|||
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); |
|||
|
|||
if (!vfioGroupDev) |
|||
@@ -2499,7 +2499,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
|
|||
return -1; |
|||
|
|||
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) { |
|||
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
|
|||
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
|
|||
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci); |
|||
|
|||
if (!vfioGroupDev) |
|||
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
|
|||
index 29e844c7ff..af95a64c42 100644
|
|||
--- a/src/security/virt-aa-helper.c
|
|||
+++ b/src/security/virt-aa-helper.c
|
|||
@@ -1117,7 +1117,7 @@ get_files(vahControl * ctl)
|
|||
|
|||
if ((driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO || |
|||
driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT) && |
|||
- dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
|
|||
+ virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
|
|||
needsVfio = true; |
|||
} |
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,266 @@ |
|||
From c0d508913546c66014f4cad54779ff4ad1549d7a Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <c0d508913546c66014f4cad54779ff4ad1549d7a.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Mon, 16 Mar 2026 15:30:18 +0100 |
|||
Subject: [PATCH] tests: Add iommufd fdgroup test |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 406b7fb0bd82251d94ce1fcb5fd7e35d51e1a1b7) |
|||
|
|||
Conflicts: |
|||
- tests/qemuxmlconftest.c |
|||
missing upstream commit 6d6da1cbac4f0194ca257c8ff8f5038a96791a62 |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/qemu/qemu_process.c | 14 +++-- |
|||
src/qemu/qemu_processpriv.h | 2 + |
|||
.../iommufd-q35-fd.x86_64-latest.args | 41 +++++++++++++ |
|||
.../iommufd-q35-fd.x86_64-latest.xml | 60 +++++++++++++++++++ |
|||
tests/qemuxmlconfdata/iommufd-q35-fd.xml | 38 ++++++++++++ |
|||
tests/qemuxmlconftest.c | 9 ++- |
|||
6 files changed, 159 insertions(+), 5 deletions(-) |
|||
create mode 100644 tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args |
|||
create mode 100644 tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml |
|||
create mode 100644 tests/qemuxmlconfdata/iommufd-q35-fd.xml |
|||
|
|||
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|||
index e4746374f6..b56e79ed1c 100644
|
|||
--- a/src/qemu/qemu_process.c
|
|||
+++ b/src/qemu/qemu_process.c
|
|||
@@ -7712,9 +7712,11 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
|
|||
* |
|||
* Find passed FD via virDomainFDAssociate() API for the VM. |
|||
* |
|||
+ * Exported only to be used in tests.
|
|||
+ *
|
|||
* Returns: 0 on success, -1 on failure |
|||
*/ |
|||
-static int
|
|||
+int
|
|||
qemuProcessGetPassedIommuFd(virDomainObj *vm) |
|||
{ |
|||
qemuDomainObjPrivate *priv = vm->privateData; |
|||
@@ -7734,10 +7736,14 @@ qemuProcessGetPassedIommuFd(virDomainObj *vm)
|
|||
return -1; |
|||
} |
|||
|
|||
- iommufd = dup(fdt->fds[0]);
|
|||
+ if (fdt->testfds) {
|
|||
+ iommufd = dup2(fdt->fds[0], fdt->testfds[0]);
|
|||
+ } else {
|
|||
+ iommufd = dup(fdt->fds[0]);
|
|||
|
|||
- if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
|
|||
- return -1;
|
|||
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
|
|||
+ return -1;
|
|||
+ }
|
|||
|
|||
priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd); |
|||
|
|||
diff --git a/src/qemu/qemu_processpriv.h b/src/qemu/qemu_processpriv.h
|
|||
index 0ba5897f40..4bef5025b9 100644
|
|||
--- a/src/qemu/qemu_processpriv.h
|
|||
+++ b/src/qemu/qemu_processpriv.h
|
|||
@@ -37,3 +37,5 @@ void qemuProcessHandleDeviceDeleted(qemuMonitor *mon,
|
|||
const char *devAlias); |
|||
|
|||
int qemuProcessQMPInitMonitor(qemuMonitor *mon); |
|||
+
|
|||
+int qemuProcessGetPassedIommuFd(virDomainObj *vm);
|
|||
diff --git a/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args
|
|||
new file mode 100644 |
|||
index 0000000000..7df3d173f3
|
|||
--- /dev/null
|
|||
+++ b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args
|
|||
@@ -0,0 +1,41 @@
|
|||
+LC_ALL=C \
|
|||
+PATH=/bin \
|
|||
+HOME=/var/lib/libvirt/qemu/domain--1-q35-test \
|
|||
+USER=test \
|
|||
+LOGNAME=test \
|
|||
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.local/share \
|
|||
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.cache \
|
|||
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.config \
|
|||
+/usr/bin/qemu-system-x86_64 \
|
|||
+-name guest=q35-test,debug-threads=on \
|
|||
+-S \
|
|||
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-q35-test/master-key.aes"}' \
|
|||
+-machine q35,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
|
|||
+-accel tcg \
|
|||
+-cpu qemu64 \
|
|||
+-m size=2097152k \
|
|||
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":2147483648}' \
|
|||
+-overcommit mem-lock=off \
|
|||
+-smp 2,sockets=2,cores=1,threads=1 \
|
|||
+-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \
|
|||
+-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 \
|
|||
+-device '{"driver":"pcie-root-port","port":16,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x2"}' \
|
|||
+-device '{"driver":"pcie-root-port","port":17,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x2.0x1"}' \
|
|||
+-device '{"driver":"qemu-xhci","id":"usb","bus":"pci.1","addr":"0x0"}' \
|
|||
+-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","read-only":false}' \
|
|||
+-device '{"driver":"ide-hd","bus":"ide.0","drive":"libvirt-1-storage","id":"sata0-0-0","bootindex":1}' \
|
|||
+-audiodev '{"id":"audio1","driver":"none"}' \
|
|||
+-device '{"driver":"qxl-vga","id":"video0","max_outputs":1,"ram_size":67108864,"vram_size":33554432,"vram64_size_mb":0,"vgamem_mb":8,"bus":"pcie.0","addr":"0x1"}' \
|
|||
+-global ICH9-LPC.noreboot=off \
|
|||
+-watchdog-action reset \
|
|||
+-object '{"qom-type":"iommufd","id":"iommufd0","fd":"20"}' \
|
|||
+-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x3"}' \
|
|||
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
|
|||
+-msg timestamp=on
|
|||
diff --git a/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml
|
|||
new file mode 100644 |
|||
index 0000000000..a6be49cbb3
|
|||
--- /dev/null
|
|||
+++ b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml
|
|||
@@ -0,0 +1,60 @@
|
|||
+<domain type='qemu'>
|
|||
+ <name>q35-test</name>
|
|||
+ <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
|
|||
+ <memory unit='KiB'>2097152</memory>
|
|||
+ <currentMemory unit='KiB'>2097152</currentMemory>
|
|||
+ <vcpu placement='static' cpuset='0-1'>2</vcpu>
|
|||
+ <iommufd enabled='yes' fdgroup='iommu'/>
|
|||
+ <os>
|
|||
+ <type arch='x86_64' machine='q35'>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='sda' bus='sata'/>
|
|||
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
|||
+ </disk>
|
|||
+ <controller type='pci' index='0' model='pcie-root'/>
|
|||
+ <controller type='pci' index='1' model='pcie-root-port'>
|
|||
+ <model name='pcie-root-port'/>
|
|||
+ <target chassis='1' port='0x10'/>
|
|||
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
|
|||
+ </controller>
|
|||
+ <controller type='pci' index='2' model='pcie-root-port'>
|
|||
+ <model name='pcie-root-port'/>
|
|||
+ <target chassis='2' port='0x11'/>
|
|||
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
|
|||
+ </controller>
|
|||
+ <controller type='sata' index='0'>
|
|||
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
|
|||
+ </controller>
|
|||
+ <controller type='usb' index='0' model='qemu-xhci'>
|
|||
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
|
|||
+ </controller>
|
|||
+ <input type='mouse' bus='ps2'/>
|
|||
+ <input type='keyboard' bus='ps2'/>
|
|||
+ <audio id='1' type='none'/>
|
|||
+ <video>
|
|||
+ <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1' primary='yes'/>
|
|||
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
|
|||
+ </video>
|
|||
+ <hostdev mode='subsystem' type='pci' managed='yes'>
|
|||
+ <source>
|
|||
+ <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
|
|||
+ </source>
|
|||
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
|
|||
+ </hostdev>
|
|||
+ <watchdog model='itco' action='reset'/>
|
|||
+ <memballoon model='none'/>
|
|||
+ </devices>
|
|||
+</domain>
|
|||
diff --git a/tests/qemuxmlconfdata/iommufd-q35-fd.xml b/tests/qemuxmlconfdata/iommufd-q35-fd.xml
|
|||
new file mode 100644 |
|||
index 0000000000..1cef31fffa
|
|||
--- /dev/null
|
|||
+++ b/tests/qemuxmlconfdata/iommufd-q35-fd.xml
|
|||
@@ -0,0 +1,38 @@
|
|||
+<domain type='qemu'>
|
|||
+ <name>q35-test</name>
|
|||
+ <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
|
|||
+ <memory unit='KiB'>2097152</memory>
|
|||
+ <currentMemory unit='KiB'>2097152</currentMemory>
|
|||
+ <vcpu placement='static' cpuset='0-1'>2</vcpu>
|
|||
+ <iommufd enabled='yes' fdgroup='iommu'/>
|
|||
+ <os>
|
|||
+ <type arch='x86_64' machine='q35'>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'>
|
|||
+ <source dev='/dev/HostVG/QEMUGuest1'/>
|
|||
+ <target dev='sda' bus='sata'/>
|
|||
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
|||
+ </disk>
|
|||
+ <controller type='pci' index='0' model='pcie-root'/>
|
|||
+ <hostdev mode='subsystem' type='pci' managed='yes'>
|
|||
+ <source>
|
|||
+ <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
|
|||
+ </source>
|
|||
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
|
|||
+ </hostdev>
|
|||
+ <controller type='sata' index='0'/>
|
|||
+ <input type='mouse' bus='ps2'/>
|
|||
+ <input type='keyboard' bus='ps2'/>
|
|||
+ <video>
|
|||
+ <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
|
|||
+ </video>
|
|||
+ <memballoon model='none'/>
|
|||
+ </devices>
|
|||
+</domain>
|
|||
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
|
|||
index aa877bf16a..29b7e1883c 100644
|
|||
--- a/tests/qemuxmlconftest.c
|
|||
+++ b/tests/qemuxmlconftest.c
|
|||
@@ -30,6 +30,9 @@
|
|||
# define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW |
|||
# include "qemu/qemu_capspriv.h" |
|||
|
|||
+# define LIBVIRT_QEMU_PROCESSPRIV_H_ALLOW
|
|||
+# include "qemu/qemu_processpriv.h"
|
|||
+
|
|||
# include "testutilsqemu.h" |
|||
|
|||
# define VIR_FROM_THIS VIR_FROM_QEMU |
|||
@@ -408,7 +411,9 @@ testQemuPrepareHostdev(virDomainObj *vm)
|
|||
} |
|||
} |
|||
|
|||
- if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
|
|||
+ if (vm->def->iommufd_fdgroup) {
|
|||
+ ignore_value(qemuProcessGetPassedIommuFd(vm));
|
|||
+ } else if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
|
|||
int iommufd = 0; |
|||
priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd); |
|||
} |
|||
@@ -3099,6 +3104,8 @@ mymain(void)
|
|||
|
|||
DO_TEST_CAPS_LATEST("iommufd"); |
|||
DO_TEST_CAPS_LATEST("iommufd-q35"); |
|||
+ DO_TEST_CAPS_ARCH_LATEST_FULL("iommufd-q35-fd", "x86_64",
|
|||
+ ARG_FD_GROUP, "iommu", false, 1, 20);
|
|||
DO_TEST_CAPS_ARCH_LATEST("iommufd-virt", "aarch64"); |
|||
DO_TEST_CAPS_ARCH_LATEST("iommufd-virt-pci-bus-single", "aarch64"); |
|||
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,127 @@ |
|||
From d1421d7387a3a747d3476471d7c94b294cfb2748 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <d1421d7387a3a747d3476471d7c94b294cfb2748.1780571167.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Mon, 25 May 2026 12:27:41 +0200 |
|||
Subject: [PATCH] util: Publish and mock virHostCPUGetMSRFromKVM |
|||
|
|||
The function will later be called when probing QEMU capabilities. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 3184289356bd97daa75f77bec189e5ce152ba5e6) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
src/libvirt_private.syms | 1 + |
|||
src/util/virhostcpu.c | 22 +++++++++++++++++++++- |
|||
src/util/virhostcpu.h | 3 +++ |
|||
tests/qemucpumock.c | 22 ++++++++++++++++++++++ |
|||
4 files changed, 47 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|||
index 1733286bad..3eca15f066 100644
|
|||
--- a/src/libvirt_private.syms
|
|||
+++ b/src/libvirt_private.syms
|
|||
@@ -2586,6 +2586,7 @@ virHostCPUGetKVMMaxVCPUs;
|
|||
virHostCPUGetMap; |
|||
virHostCPUGetMicrocodeVersion; |
|||
virHostCPUGetMSR; |
|||
+virHostCPUGetMSRFromKVM;
|
|||
virHostCPUGetOnline; |
|||
virHostCPUGetOnlineBitmap; |
|||
virHostCPUGetPhysAddrSize; |
|||
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
|
|||
index 09395ddb04..a23a3f95e7 100644
|
|||
--- a/src/util/virhostcpu.c
|
|||
+++ b/src/util/virhostcpu.c
|
|||
@@ -1329,7 +1329,18 @@ virHostCPUGetMicrocodeVersion(virArch hostArch G_GNUC_UNUSED)
|
|||
|
|||
#if WITH_LINUX_KVM_H && defined(KVM_GET_MSRS) && \ |
|||
(defined(__i386__) || defined(__x86_64__)) |
|||
-static int
|
|||
+/**
|
|||
+ * virHostCPUGetMSRFromKVM:
|
|||
+ * @index: MSR to read
|
|||
+ * @result: where to store the content of the @index register
|
|||
+ *
|
|||
+ * Reads the 64b content of the specified register via KVM_GET_MSRS ioctl.
|
|||
+ *
|
|||
+ * Returns 0 on success,
|
|||
+ * 1 when the MSR is not supported by the host CPU,
|
|||
+ * -1 on error.
|
|||
+ */
|
|||
+int
|
|||
virHostCPUGetMSRFromKVM(unsigned long index, |
|||
uint64_t *result) |
|||
{ |
|||
@@ -1566,6 +1577,15 @@ virHostCPUGetCPUID(void)
|
|||
return NULL; |
|||
} |
|||
|
|||
+int
|
|||
+virHostCPUGetMSRFromKVM(unsigned long index G_GNUC_UNUSED,
|
|||
+ uint64_t *result G_GNUC_UNUSED)
|
|||
+{
|
|||
+ virReportSystemError(ENOSYS, "%s",
|
|||
+ _("Reading MSRs is not supported on this platform"));
|
|||
+ return -1;
|
|||
+}
|
|||
+
|
|||
int |
|||
virHostCPUGetMSR(unsigned long index G_GNUC_UNUSED, |
|||
uint64_t *msr G_GNUC_UNUSED) |
|||
diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
|
|||
index 289ae41439..24c7fdaf7c 100644
|
|||
--- a/src/util/virhostcpu.h
|
|||
+++ b/src/util/virhostcpu.h
|
|||
@@ -80,6 +80,9 @@ int virHostCPUGetOnline(unsigned int cpu, bool *online);
|
|||
unsigned int |
|||
virHostCPUGetMicrocodeVersion(virArch hostArch) ATTRIBUTE_MOCKABLE; |
|||
|
|||
+int virHostCPUGetMSRFromKVM(unsigned long index,
|
|||
+ uint64_t *result) ATTRIBUTE_MOCKABLE;
|
|||
+
|
|||
int virHostCPUGetMSR(unsigned long index, |
|||
uint64_t *msr); |
|||
|
|||
diff --git a/tests/qemucpumock.c b/tests/qemucpumock.c
|
|||
index 5a63308347..de1e79bfc1 100644
|
|||
--- a/tests/qemucpumock.c
|
|||
+++ b/tests/qemucpumock.c
|
|||
@@ -23,6 +23,7 @@
|
|||
#include "qemu/qemu_capspriv.h" |
|||
#include "testutilshostcpus.h" |
|||
#include "virarch.h" |
|||
+#include "util/virhostcpu.h"
|
|||
|
|||
|
|||
virCPUDef * |
|||
@@ -33,3 +34,24 @@ virQEMUCapsProbeHostCPU(virArch hostArch G_GNUC_UNUSED,
|
|||
|
|||
return testUtilsHostCpusGetDefForModel(model); |
|||
} |
|||
+
|
|||
+
|
|||
+int
|
|||
+virHostCPUGetMSRFromKVM(unsigned long index,
|
|||
+ uint64_t *result)
|
|||
+{
|
|||
+ if (index == 0x10a) {
|
|||
+ /* Return some arbitrary bits in arch-capabilities MSR */
|
|||
+ *result =
|
|||
+ 0x00000001 | /* rdctl-no */
|
|||
+ 0x00000008 | /* skip-l1dfl-vmentry */
|
|||
+ 0x00000020 | /* mds-no */
|
|||
+ 0x00000040 | /* pschange-mc-no */
|
|||
+ 0x04000000 | /* gds-no */
|
|||
+ 0x08000000; /* rfds-no */
|
|||
+ return 0;
|
|||
+ }
|
|||
+
|
|||
+ errno = ENOTSUP;
|
|||
+ return -1;
|
|||
+}
|
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,43 @@ |
|||
From 89d55e7dc4be2177645e6090a21ce0f293feec6a Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <89d55e7dc4be2177645e6090a21ce0f293feec6a.1780571166.git.jdenemar@redhat.com> |
|||
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com> |
|||
Date: Tue, 12 May 2026 13:10:43 +0200 |
|||
Subject: [PATCH] util: virGetSubIDs: do not limit file size |
|||
MIME-Version: 1.0 |
|||
Content-Type: text/plain; charset=UTF-8 |
|||
Content-Transfer-Encoding: 8bit |
|||
|
|||
On systems with many users, this file can be larger than BUFSIZ. |
|||
Since the file should only be editable by root and virFileReadAll |
|||
reallocates the buffer in increments as needed as opposed to |
|||
allocating for 'maxlen' upfront, set the maximum to INT_MAX. |
|||
|
|||
https://gitlab.com/libvirt/libvirt/-/work_items/874 |
|||
|
|||
Signed-off-by: Ján Tomko <jtomko@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit b0c104e7aaf9cde62702dd66e2c7e4343495de59) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-174491 |
|||
Signed-off-by: Ján Tomko <jtomko@redhat.com> |
|||
---
|
|||
src/util/virutil.c | 4 +++- |
|||
1 file changed, 3 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/src/util/virutil.c b/src/util/virutil.c
|
|||
index fb64237692..94a6958582 100644
|
|||
--- a/src/util/virutil.c
|
|||
+++ b/src/util/virutil.c
|
|||
@@ -1202,7 +1202,9 @@ virGetSubIDs(virSubID **retval, const char *file)
|
|||
|
|||
*retval = NULL; |
|||
|
|||
- if (virFileReadAll(file, BUFSIZ, &buf) < 0)
|
|||
+ /* We trust the source of the file so we set the limit absurdly high.
|
|||
+ * For smaller files, the helper function will not allocate as much space */
|
|||
+ if (virFileReadAll(file, INT_MAX, &buf) < 0)
|
|||
return -1; |
|||
|
|||
lines = g_strsplit(buf, "\n", 0); |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,79 @@ |
|||
From 32ff11b8bbc74b61f5ff531f9fb5c83f1a4da343 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <32ff11b8bbc74b61f5ff531f9fb5c83f1a4da343.1780571166.git.jdenemar@redhat.com> |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Fri, 13 Mar 2026 10:50:36 +0100 |
|||
Subject: [PATCH] viriommufd: Set IOMMU_OPTION_RLIMIT_MODE only when running |
|||
privileged |
|||
|
|||
If libvirt daemon is running unprivileged it will fail so we should not |
|||
even try to set it. |
|||
|
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Jiri Denemark <jdenemar@redhat.com> |
|||
(cherry picked from commit 293bb59e75f4b4c975bbeccb1bb8b39b6f439a35) |
|||
|
|||
Resolves: https://redhat.atlassian.net/browse/RHEL-156803 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/qemu/qemu_process.c | 2 +- |
|||
src/util/viriommufd.c | 6 +++--- |
|||
src/util/viriommufd.h | 2 +- |
|||
3 files changed, 5 insertions(+), 5 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|||
index 0a69063a4b..9b8b378b1f 100644
|
|||
--- a/src/qemu/qemu_process.c
|
|||
+++ b/src/qemu/qemu_process.c
|
|||
@@ -7695,7 +7695,7 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
|
|||
|
|||
VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name); |
|||
|
|||
- if ((iommufd = virIOMMUFDOpenDevice()) < 0)
|
|||
+ if ((iommufd = virIOMMUFDOpenDevice(priv->driver->privileged)) < 0)
|
|||
return -1; |
|||
|
|||
if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0) |
|||
diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c
|
|||
index b62d59241d..82920923a2 100644
|
|||
--- a/src/util/viriommufd.c
|
|||
+++ b/src/util/viriommufd.c
|
|||
@@ -80,14 +80,14 @@ virIOMMUFDSetRLimitMode(int fd, bool processAccounting)
|
|||
} |
|||
|
|||
int |
|||
-virIOMMUFDOpenDevice(void)
|
|||
+virIOMMUFDOpenDevice(bool privileged)
|
|||
{ |
|||
int fd = -1; |
|||
|
|||
if ((fd = open(VIR_IOMMU_DEV_PATH, O_RDWR | O_CLOEXEC)) < 0) |
|||
virReportSystemError(errno, "%s", _("cannot open IOMMUFD device")); |
|||
|
|||
- if (virIOMMUFDSetRLimitMode(fd, true) < 0) {
|
|||
+ if (privileged && virIOMMUFDSetRLimitMode(fd, true) < 0) {
|
|||
VIR_FORCE_CLOSE(fd); |
|||
return -1; |
|||
} |
|||
@@ -98,7 +98,7 @@ virIOMMUFDOpenDevice(void)
|
|||
#else |
|||
|
|||
int |
|||
-virIOMMUFDOpenDevice(void)
|
|||
+virIOMMUFDOpenDevice(bool privileged G_GNUC_UNUSED)
|
|||
{ |
|||
virReportError(VIR_ERR_NO_SUPPORT, "%s", |
|||
_("IOMMUFD is not supported on this platform")); |
|||
diff --git a/src/util/viriommufd.h b/src/util/viriommufd.h
|
|||
index 223f44eb5c..7bad5c7472 100644
|
|||
--- a/src/util/viriommufd.h
|
|||
+++ b/src/util/viriommufd.h
|
|||
@@ -22,6 +22,6 @@
|
|||
|
|||
#define VIR_IOMMU_DEV_PATH "/dev/iommu" |
|||
|
|||
-int virIOMMUFDOpenDevice(void);
|
|||
+int virIOMMUFDOpenDevice(bool privileged);
|
|||
|
|||
bool virIOMMUFDSupported(void); |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,68 @@ |
|||
From 169253f6cc07e089162c1350d434e8d197298f6a Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <169253f6cc07e089162c1350d434e8d197298f6a.1780571166.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Wed, 11 Mar 2026 12:13:22 +0100 |
|||
Subject: [PATCH] virsh: Add --expand-cpu-features option for domcapabilities |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 57e5bb55cef5e97eea14fcecef7114e804576d6c) |
|||
|
|||
https://issues.redhat.com/browse/RHEL-153653 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
docs/manpages/virsh.rst | 5 +++++ |
|||
tools/virsh-host.c | 7 +++++++ |
|||
2 files changed, 12 insertions(+) |
|||
|
|||
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
|
|||
index ff0cf1a715..85fa6ab011 100644
|
|||
--- a/docs/manpages/virsh.rst
|
|||
+++ b/docs/manpages/virsh.rst
|
|||
@@ -592,6 +592,7 @@ domcapabilities
|
|||
domcapabilities [virttype] [emulatorbin] [arch] [machine] |
|||
[--xpath EXPRESSION] [--wrap] |
|||
[--disable-deprecated-features] |
|||
+ [--expand-cpu-features]
|
|||
|
|||
|
|||
Print an XML document describing the domain capabilities for the |
|||
@@ -638,6 +639,10 @@ of host-model CPU XML, updating the features list with any features
|
|||
flagged as deprecated for the CPU model by the hypervisor. These |
|||
features will be paired with the "disable" policy. |
|||
|
|||
+The **--expand-cpu-features** option will cause the host-model CPU definition
|
|||
+to contain all CPU features supported on the host including those implicitly
|
|||
+enabled by the selected CPU model.
|
|||
+
|
|||
|
|||
pool-capabilities |
|||
----------------- |
|||
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
|
|||
index e918cfa4ca..dd98917fa8 100644
|
|||
--- a/tools/virsh-host.c
|
|||
+++ b/tools/virsh-host.c
|
|||
@@ -118,6 +118,10 @@ static const vshCmdOptDef opts_domcapabilities[] = {
|
|||
.type = VSH_OT_BOOL, |
|||
.help = N_("report host CPU model with deprecated features disabled"), |
|||
}, |
|||
+ {.name = "expand-cpu-features",
|
|||
+ .type = VSH_OT_BOOL,
|
|||
+ .help = N_("show all features in host CPU model"),
|
|||
+ },
|
|||
{.name = NULL} |
|||
}; |
|||
|
|||
@@ -137,6 +141,9 @@ cmdDomCapabilities(vshControl *ctl, const vshCmd *cmd)
|
|||
if (vshCommandOptBool(cmd, "disable-deprecated-features")) |
|||
flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES; |
|||
|
|||
+ if (vshCommandOptBool(cmd, "expand-cpu-features"))
|
|||
+ flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES;
|
|||
+
|
|||
if (vshCommandOptString(ctl, cmd, "virttype", &virttype) < 0 || |
|||
vshCommandOptString(ctl, cmd, "emulatorbin", &emulatorbin) < 0 || |
|||
vshCommandOptString(ctl, cmd, "arch", &arch) < 0 || |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,75 @@ |
|||
From ec36f1c9c281c98378dd937ba60aeee60e95daaf Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <ec36f1c9c281c98378dd937ba60aeee60e95daaf.1780571167.git.jdenemar@redhat.com> |
|||
From: Jiri Denemark <jdenemar@redhat.com> |
|||
Date: Fri, 29 May 2026 12:52:59 +0200 |
|||
Subject: [PATCH] virsh: Add --supported-cpu-features option for |
|||
domcapabilities |
|||
|
|||
The option corresponds to the |
|||
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES API flag. |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
(cherry picked from commit 26ffa1d4f0b74c7cda5a6906510cf2d6362b5b8b) |
|||
|
|||
https://redhat.atlassian.net/browse/RHEL-177364 |
|||
|
|||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> |
|||
---
|
|||
docs/manpages/virsh.rst | 8 +++++++- |
|||
tools/virsh-host.c | 7 +++++++ |
|||
2 files changed, 14 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
|
|||
index 7169b6bc05..2936df6a73 100644
|
|||
--- a/docs/manpages/virsh.rst
|
|||
+++ b/docs/manpages/virsh.rst
|
|||
@@ -592,7 +592,7 @@ domcapabilities
|
|||
domcapabilities [virttype] [emulatorbin] [arch] [machine] |
|||
[--xpath EXPRESSION] [--wrap] |
|||
[--disable-deprecated-features] |
|||
- [--expand-cpu-features]
|
|||
+ [--expand-cpu-features] [--supported-cpu-features]
|
|||
|
|||
|
|||
Print an XML document describing the domain capabilities for the |
|||
@@ -644,6 +644,12 @@ to contain all required CPU features including those implicitly enabled by the
|
|||
selected CPU model. Without this flag features that are part of the CPU model |
|||
itself will not be listed. |
|||
|
|||
+The **--supported-cpu-features** option will update the host-model CPU
|
|||
+definition with features that are supported on the host, but will not be
|
|||
+enabled by default when starting a domain with host-model CPU. Using both
|
|||
+**--supported-cpu-features** and **--expand-cpu-features** will provide a
|
|||
+complete list of features that can be enabled on the host.
|
|||
+
|
|||
|
|||
pool-capabilities |
|||
----------------- |
|||
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
|
|||
index 5dbeb54ae5..4b95d2748e 100644
|
|||
--- a/tools/virsh-host.c
|
|||
+++ b/tools/virsh-host.c
|
|||
@@ -122,6 +122,10 @@ static const vshCmdOptDef opts_domcapabilities[] = {
|
|||
.type = VSH_OT_BOOL, |
|||
.help = N_("expand 'host-model' CPU to also show features enabled by the CPU model"), |
|||
}, |
|||
+ {.name = "supported-cpu-features",
|
|||
+ .type = VSH_OT_BOOL,
|
|||
+ .help = N_("include all supported CPU features in 'host-model' mode, not only those enabled by default"),
|
|||
+ },
|
|||
{.name = NULL} |
|||
}; |
|||
|
|||
@@ -144,6 +148,9 @@ cmdDomCapabilities(vshControl *ctl, const vshCmd *cmd)
|
|||
if (vshCommandOptBool(cmd, "expand-cpu-features")) |
|||
flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES; |
|||
|
|||
+ if (vshCommandOptBool(cmd, "supported-cpu-features"))
|
|||
+ flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES;
|
|||
+
|
|||
if (vshCommandOptString(ctl, cmd, "virttype", &virttype) < 0 || |
|||
vshCommandOptString(ctl, cmd, "emulatorbin", &emulatorbin) < 0 || |
|||
vshCommandOptString(ctl, cmd, "arch", &arch) < 0 || |
|||
--
|
|||
2.54.0 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:988a1e499aedb03d41b9b4b73ffb8162018602a6da40ae9e1b8962c15d8f85dc |
|||
size 33868717 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:727ac0e81c5446aae76839a85ea3ea7a966ed4112421db1d0f70c1b2f92dc0c0 |
|||
size 33851391 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:e40d697efb8b4d1daf042852a4575a1a168cfdbb68fcd93dde7698e8b513c28c |
|||
size 33861997 |
|||
@ -0,0 +1,91 @@ |
|||
# Common code shared between build.sh and update.sh |
|||
|
|||
# Prints the list of currently maintained Fedora versions (e.g. "42 43 44"), |
|||
# based on the Bodhi releases API. |
|||
function get_fedora_versions () { |
|||
curl -fsSL "https://bodhi.fedoraproject.org/releases/?exclude_archived=true&state=current" \ |
|||
| jq -r '.releases[] | select(.id_prefix=="FEDORA") | .version' \ |
|||
| grep -E '^[0-9]+$' | sort -n |
|||
} |
|||
|
|||
# Prints the list of active CentOS Stream versions (e.g. "9 10"), |
|||
# based on the directory listing of the official mirror. |
|||
function get_centos_stream_versions () { |
|||
curl -fsSL "https://mirror.stream.centos.org/" \ |
|||
| grep -oP '(?<=href=")[0-9]+-stream(?=/")' \ |
|||
| sed 's/-stream//' | sort -n |
|||
} |
|||
|
|||
# Prints the list of currently maintained Fedora and CentOS Stream versions (e.g. "centos-9 centos-10 fedora-42 fedora-43 fedora-44"). |
|||
function get_all_remote_dists () { |
|||
local dists=() |
|||
for v in $(get_centos_stream_versions); do |
|||
dists+=("centos-$v") |
|||
done |
|||
for v in $(get_fedora_versions); do |
|||
dists+=("fedora-$v") |
|||
done |
|||
echo "${dists[@]}" |
|||
} |
|||
|
|||
# Installs locally all source RPMs of a given distribution. |
|||
function install_all_srpm () { |
|||
local dist=$1 |
|||
echo "Importing source RPMs of $dist..." |
|||
rpm -ivh "--define=_topdir $PWD/$dist" "$dist/SRPMS/"*.src.rpm |
|||
} |
|||
|
|||
# Applies all patches for a given distribution. |
|||
function apply_patches () { |
|||
local dist=$1 |
|||
for patch in "$dist/PATCHES"/*.patch; do |
|||
echo "Applying patch $(basename "$patch")..." |
|||
patch -d "$dist"* -p1 < "$patch" |
|||
done |
|||
} |
|||
|
|||
# Downloads the libvirt and zfs source RPMs for a given Fedora distribution. |
|||
function download_sources_fedora () { |
|||
local dist=$1 |
|||
local v="${dist#*-}" |
|||
echo "Downloading libvirt source for Fedora $v..." |
|||
dnf download --repofrompath=$dist,https://dl.fedoraproject.org/pub/fedora/linux/releases/$v/Everything/source/tree/ --repofrompath=$dist-updates,https://dl.fedoraproject.org/pub/fedora/linux/updates/$v/Everything/source/tree/ --repo="$dist" --repo="$dist-updates" --source libvirt --destdir $dist/SRPMS/ |
|||
echo "Downloading zfs source for Fedora $v..." |
|||
if ! dnf download --repofrompath=zfs-$dist,http://download.zfsonlinux.org/fedora/$v/SRPMS/ --repo=zfs-$dist --source zfs zfs-dkms --destdir $dist/SRPMS/; then |
|||
echo "ZFS source RPM not found for Fedora $v, skipping..." |
|||
fi |
|||
} |
|||
|
|||
# Downloads the libvirt and zfs source RPMs for a given CentOS Stream distribution. |
|||
function download_sources_centos_stream () { |
|||
local dist=$1 |
|||
local v="${dist#*-}" |
|||
echo "Downloading libvirt source for CentOS Stream $v..." |
|||
dnf download --repofrompath=$dist,https://mirror.stream.centos.org/$v-stream/AppStream/source/tree/ --repo="$dist" --source libvirt --destdir $dist/SRPMS/ |
|||
echo "Downloading zfs source for CentOS Stream $v..." |
|||
if ! dnf download --repofrompath=zfs-$dist,http://download.zfsonlinux.org/epel/$v/SRPMS/ --repo=zfs-$dist --source zfs zfs-dkms --destdir $dist/SRPMS/; then |
|||
echo "ZFS source RPM not found for CentOS Stream $v, skipping..." |
|||
fi |
|||
} |
|||
|
|||
# Prints the latest Fedora version for which zfs source RPMs are published on |
|||
# download.zfsonlinux.org. This is not necessarily the latest Fedora version. |
|||
function get_latest_zfs_fedora_version () { |
|||
curl -fsSL "http://download.zfsonlinux.org/fedora/" \ |
|||
| grep -oP '(?<=href=")[0-9]+(?=/")' | sort -n | tail -1 |
|||
} |
|||
|
|||
# Downloads the libvirt source RPM from Fedora Rawhide and the zfs source RPMs |
|||
# from the latest Fedora version published on download.zfsonlinux.org (which |
|||
# may lag behind Rawhide). |
|||
function download_sources_fedora_rawhide () { |
|||
local dist=$1 |
|||
echo "Downloading libvirt source for Fedora Rawhide..." |
|||
dnf download --repofrompath=$dist,https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/source/tree/ --repo="$dist" --source libvirt --destdir $dist/SRPMS/ |
|||
local zfs_version |
|||
zfs_version="$(get_latest_zfs_fedora_version)" |
|||
echo "Downloading zfs source from Fedora $zfs_version (latest available on download.zfsonlinux.org)..." |
|||
if ! dnf download --repofrompath=zfs-$dist,http://download.zfsonlinux.org/fedora/$zfs_version/SRPMS/ --repo=zfs-$dist --source zfs zfs-dkms --destdir $dist/SRPMS/; then |
|||
echo "ZFS source RPM not found for Fedora $zfs_version, skipping..." |
|||
fi |
|||
} |
|||
@ -1,29 +0,0 @@ |
|||
From: Martin Kletzander <mkletzan@redhat.com> |
|||
Date: Fri, 16 Aug 2024 13:56:51 +0200 |
|||
Subject: [PATCH] virarptable: Properly calculate rtattr length |
|||
Content-type: text/plain |
|||
|
|||
Use convenience macro which does almost the same thing we were doing, |
|||
but also pads out the payload length to a multiple of NLMSG_ALIGNTO (4) |
|||
bytes. |
|||
|
|||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com> |
|||
Reviewed-by: Laine Stump <laine@redhat.com> |
|||
---
|
|||
src/util/virarptable.c | 3 +-- |
|||
1 file changed, 1 insertion(+), 2 deletions(-) |
|||
|
|||
diff --git a/src/util/virarptable.c b/src/util/virarptable.c
|
|||
index 299dddd664..d8e41c5a86 100644
|
|||
--- a/src/util/virarptable.c
|
|||
+++ b/src/util/virarptable.c
|
|||
@@ -102,8 +102,7 @@ virArpTableGet(void)
|
|||
return table; |
|||
|
|||
VIR_WARNINGS_NO_CAST_ALIGN |
|||
- parse_rtattr(tb, NDA_MAX, NDA_RTA(r),
|
|||
- nh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
|||
+ parse_rtattr(tb, NDA_MAX, NDA_RTA(r), NLMSG_PAYLOAD(nh, sizeof(*r)));
|
|||
VIR_WARNINGS_RESET |
|||
|
|||
if (tb[NDA_DST] == NULL || tb[NDA_LLADDR] == NULL) |
|||
@ -1,34 +0,0 @@ |
|||
From: Martin Kletzander <mkletzan@redhat.com> |
|||
Date: Fri, 16 Aug 2024 13:59:15 +0200 |
|||
Subject: [PATCH] virarptable: Fix check for message length |
|||
Content-type: text/plain |
|||
|
|||
The previous check was all wrong since it calculated the how long would |
|||
the netlink message be if the netlink header was the payload and then |
|||
subtracted that from the whole message length, a variable that was not |
|||
used later in the code. This check can fail if there are no additional |
|||
payloads, struct rtattr in particular, which we are parsing later, |
|||
however the RTA_OK macro would've caught that anyway. |
|||
|
|||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com> |
|||
Reviewed-by: Laine Stump <laine@redhat.com> |
|||
---
|
|||
src/util/virarptable.c | 3 +-- |
|||
1 file changed, 1 insertion(+), 2 deletions(-) |
|||
|
|||
diff --git a/src/util/virarptable.c b/src/util/virarptable.c
|
|||
index d8e41c5a86..45ee76766f 100644
|
|||
--- a/src/util/virarptable.c
|
|||
+++ b/src/util/virarptable.c
|
|||
@@ -81,10 +81,9 @@ virArpTableGet(void)
|
|||
for (; NLMSG_OK(nh, msglen); nh = NLMSG_NEXT(nh, msglen)) { |
|||
VIR_WARNINGS_RESET |
|||
struct ndmsg *r = NLMSG_DATA(nh); |
|||
- int len = nh->nlmsg_len;
|
|||
void *addr; |
|||
|
|||
- if ((len -= NLMSG_LENGTH(sizeof(*nh))) < 0) {
|
|||
+ if (nh->nlmsg_len < NLMSG_SPACE(sizeof(*r))) {
|
|||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", |
|||
_("wrong nlmsg len")); |
|||
goto cleanup; |
|||
@ -1,46 +0,0 @@ |
|||
From: Martin Kletzander <mkletzan@redhat.com> |
|||
Date: Fri, 16 Aug 2024 14:02:48 +0200 |
|||
Subject: [PATCH] virarptable: End parsing earlier in case of NLMSG_DONE |
|||
Content-type: text/plain |
|||
|
|||
Check for the last multipart message right as the first thing. The |
|||
presumption probably was that the last message might still contain a |
|||
payload we want to parse. However that cannot be true since that would |
|||
have to be a type RTM_NEWNEIGH. This was not caught because older |
|||
kernels were note sending NLMSG_DONE and probably relied on the fact |
|||
that the parsing just stops after all the messages are walked through, |
|||
which the NLMSG_OK macro successfully did. |
|||
|
|||
Resolves: https://issues.redhat.com/browse/RHEL-52449 |
|||
Resolves: https://bugzilla.redhat.com/2302245 |
|||
Fixes: a176d67cdfaf5b8237a7e3a80d8be0e6bdf2d8fd |
|||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com> |
|||
Reviewed-by: Laine Stump <laine@redhat.com> |
|||
---
|
|||
src/util/virarptable.c | 6 +++--- |
|||
1 file changed, 3 insertions(+), 3 deletions(-) |
|||
|
|||
diff --git a/src/util/virarptable.c b/src/util/virarptable.c
|
|||
index 45ee76766f..20d11f97b0 100644
|
|||
--- a/src/util/virarptable.c
|
|||
+++ b/src/util/virarptable.c
|
|||
@@ -83,6 +83,9 @@ virArpTableGet(void)
|
|||
struct ndmsg *r = NLMSG_DATA(nh); |
|||
void *addr; |
|||
|
|||
+ if (nh->nlmsg_type == NLMSG_DONE)
|
|||
+ break;
|
|||
+
|
|||
if (nh->nlmsg_len < NLMSG_SPACE(sizeof(*r))) { |
|||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", |
|||
_("wrong nlmsg len")); |
|||
@@ -97,9 +100,6 @@ virArpTableGet(void)
|
|||
(!(r->ndm_state == NUD_STALE || r->ndm_state == NUD_REACHABLE))) |
|||
continue; |
|||
|
|||
- if (nh->nlmsg_type == NLMSG_DONE)
|
|||
- return table;
|
|||
-
|
|||
VIR_WARNINGS_NO_CAST_ALIGN |
|||
parse_rtattr(tb, NDA_MAX, NDA_RTA(r), NLMSG_PAYLOAD(nh, sizeof(*r))); |
|||
VIR_WARNINGS_RESET |
|||
@ -1,315 +0,0 @@ |
|||
From 807e2670f2704c41f0a1dca81a5d2f2f9336137c Mon Sep 17 00:00:00 2001 |
|||
From: Laine Stump <laine@redhat.com> |
|||
Date: Mon, 25 Nov 2024 22:24:44 -0500 |
|||
Subject: [PATCH 4/9] util: use a single flags arg for virNetDevBandwidthSet(), |
|||
not multiple bools |
|||
|
|||
Having two bools in the arg list is on the borderline of being |
|||
confusing to anyone trying to read the code, but we're about to add a |
|||
3rd. This patch replaces the two bools with a single flags argument |
|||
which will instead have one or more bits from virNetDevBandwidthFlags |
|||
set. |
|||
|
|||
Signed-off-by: Laine Stump <laine@redhat.com> |
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> |
|||
---
|
|||
src/lxc/lxc_driver.c | 8 ++++++-- |
|||
src/lxc/lxc_process.c | 8 ++++++-- |
|||
src/network/bridge_driver.c | 10 ++++++++-- |
|||
src/qemu/qemu_command.c | 11 ++++++++--- |
|||
src/qemu/qemu_driver.c | 29 ++++++++++++++------------- |
|||
src/qemu/qemu_hotplug.c | 22 +++++++++++++++------ |
|||
src/util/virnetdevbandwidth.c | 36 ++++++++++++++++++++-------------- |
|||
src/util/virnetdevbandwidth.h | 9 +++++++-- |
|||
tests/virnetdevbandwidthtest.c | 8 +++++++- |
|||
9 files changed, 94 insertions(+), 47 deletions(-) |
|||
|
|||
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
|
|||
index 534e257f30..b693980dbb 100644
|
|||
--- a/src/lxc/lxc_driver.c
|
|||
+++ b/src/lxc/lxc_driver.c
|
|||
@@ -3570,8 +3570,12 @@ lxcDomainAttachDeviceNetLive(virLXCDriver *driver,
|
|||
actualBandwidth = virDomainNetGetActualBandwidth(net); |
|||
if (actualBandwidth) { |
|||
if (virNetDevSupportsBandwidth(actualType)) { |
|||
- if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
|
|||
- !virDomainNetTypeSharesHostView(net)) < 0)
|
|||
+ unsigned int flags = 0;
|
|||
+
|
|||
+ if (!virDomainNetTypeSharesHostView(net))
|
|||
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
|
|||
+
|
|||
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
|
|||
goto cleanup; |
|||
} else { |
|||
VIR_WARN("setting bandwidth on interfaces of " |
|||
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
|
|||
index f5eb5383ec..0e689fbb70 100644
|
|||
--- a/src/lxc/lxc_process.c
|
|||
+++ b/src/lxc/lxc_process.c
|
|||
@@ -605,8 +605,12 @@ virLXCProcessSetupInterfaces(virLXCDriver *driver,
|
|||
actualBandwidth = virDomainNetGetActualBandwidth(net); |
|||
if (actualBandwidth) { |
|||
if (virNetDevSupportsBandwidth(type)) { |
|||
- if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
|
|||
- !virDomainNetTypeSharesHostView(net)) < 0)
|
|||
+ unsigned int flags = 0;
|
|||
+
|
|||
+ if (!virDomainNetTypeSharesHostView(net))
|
|||
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
|
|||
+
|
|||
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
|
|||
goto cleanup; |
|||
} else { |
|||
VIR_WARN("setting bandwidth on interfaces of " |
|||
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
|
|||
index 32572c755f..1c53636450 100644
|
|||
--- a/src/network/bridge_driver.c
|
|||
+++ b/src/network/bridge_driver.c
|
|||
@@ -2058,8 +2058,11 @@ networkStartNetworkVirtual(virNetworkDriverState *driver,
|
|||
} |
|||
} |
|||
|
|||
- if (virNetDevBandwidthSet(def->bridge, def->bandwidth, true, true) < 0)
|
|||
+ if (virNetDevBandwidthSet(def->bridge, def->bandwidth,
|
|||
+ VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS
|
|||
+ | VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED) < 0) {
|
|||
goto error; |
|||
+ }
|
|||
|
|||
return 0; |
|||
|
|||
@@ -2141,8 +2144,11 @@ networkStartNetworkBridge(virNetworkObj *obj)
|
|||
* type BRIDGE, is started. On failure, undo anything you've done, |
|||
* and return -1. On success return 0. |
|||
*/ |
|||
- if (virNetDevBandwidthSet(def->bridge, def->bandwidth, true, true) < 0)
|
|||
+ if (virNetDevBandwidthSet(def->bridge, def->bandwidth,
|
|||
+ VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS
|
|||
+ | VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED) < 0) {
|
|||
goto error; |
|||
+ }
|
|||
|
|||
if (networkStartHandleMACTableManagerMode(obj) < 0) |
|||
goto error; |
|||
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|||
index f15e6bda1e..b4815e5e71 100644
|
|||
--- a/src/qemu/qemu_command.c
|
|||
+++ b/src/qemu/qemu_command.c
|
|||
@@ -8840,9 +8840,14 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver,
|
|||
def->uuid, |
|||
!virDomainNetTypeSharesHostView(net)) < 0) |
|||
goto cleanup; |
|||
- } else if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
|
|||
- !virDomainNetTypeSharesHostView(net)) < 0) {
|
|||
- goto cleanup;
|
|||
+ } else {
|
|||
+ unsigned int flags = 0;
|
|||
+
|
|||
+ if (!virDomainNetTypeSharesHostView(net))
|
|||
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
|
|||
+
|
|||
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
|
|||
+ goto cleanup;
|
|||
} |
|||
} else { |
|||
VIR_WARN("setting bandwidth on interfaces of " |
|||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|||
index 736602333e..14929616e5 100644
|
|||
--- a/src/qemu/qemu_driver.c
|
|||
+++ b/src/qemu/qemu_driver.c
|
|||
@@ -9941,21 +9941,22 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
|
|||
virErrorRestore(&orig_err); |
|||
goto endjob; |
|||
} |
|||
- } else if (virNetDevBandwidthSet(net->ifname, newBandwidth, false,
|
|||
- !virDomainNetTypeSharesHostView(net)) < 0) {
|
|||
- virErrorPtr orig_err;
|
|||
-
|
|||
- virErrorPreserveLast(&orig_err);
|
|||
- ignore_value(virNetDevBandwidthSet(net->ifname,
|
|||
- net->bandwidth,
|
|||
- false,
|
|||
- !virDomainNetTypeSharesHostView(net)));
|
|||
- if (net->bandwidth) {
|
|||
- ignore_value(virDomainNetBandwidthUpdate(net,
|
|||
- net->bandwidth));
|
|||
+ } else {
|
|||
+ unsigned int bwflags = 0;
|
|||
+
|
|||
+ if (!virDomainNetTypeSharesHostView(net))
|
|||
+ bwflags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
|
|||
+
|
|||
+ if (virNetDevBandwidthSet(net->ifname, newBandwidth, bwflags) < 0) {
|
|||
+ virErrorPtr orig_err;
|
|||
+
|
|||
+ virErrorPreserveLast(&orig_err);
|
|||
+ ignore_value(virNetDevBandwidthSet(net->ifname, net->bandwidth, bwflags));
|
|||
+ if (net->bandwidth)
|
|||
+ ignore_value(virDomainNetBandwidthUpdate(net, net->bandwidth));
|
|||
+ virErrorRestore(&orig_err);
|
|||
+ goto endjob;
|
|||
} |
|||
- virErrorRestore(&orig_err);
|
|||
- goto endjob;
|
|||
} |
|||
|
|||
/* If the old bandwidth was cleared out, restore qdisc. */ |
|||
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
|||
index 7cb1800504..d5e7e99359 100644
|
|||
--- a/src/qemu/qemu_hotplug.c
|
|||
+++ b/src/qemu/qemu_hotplug.c
|
|||
@@ -1279,9 +1279,14 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
|
|||
vm->def->uuid, |
|||
!virDomainNetTypeSharesHostView(net)) < 0) |
|||
goto cleanup; |
|||
- } else if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
|
|||
- !virDomainNetTypeSharesHostView(net)) < 0) {
|
|||
- goto cleanup;
|
|||
+ } else {
|
|||
+ int flags = 0;
|
|||
+
|
|||
+ if (!virDomainNetTypeSharesHostView(net))
|
|||
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
|
|||
+
|
|||
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
|
|||
+ goto cleanup;
|
|||
} |
|||
} else { |
|||
VIR_WARN("setting bandwidth on interfaces of " |
|||
@@ -4082,9 +4087,14 @@ qemuDomainChangeNet(virQEMUDriver *driver,
|
|||
vm->def->uuid, |
|||
!virDomainNetTypeSharesHostView(newdev)) < 0) |
|||
goto cleanup; |
|||
- } else if (virNetDevBandwidthSet(newdev->ifname, newb, false,
|
|||
- !virDomainNetTypeSharesHostView(newdev)) < 0) {
|
|||
- goto cleanup;
|
|||
+ } else {
|
|||
+ int flags = 0;
|
|||
+
|
|||
+ if (!virDomainNetTypeSharesHostView(newdev))
|
|||
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
|
|||
+
|
|||
+ if (virNetDevBandwidthSet(newdev->ifname, newb, flags) < 0)
|
|||
+ goto cleanup;
|
|||
} |
|||
} else { |
|||
if (virDomainInterfaceClearQoS(vm->def, olddev) < 0) |
|||
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
|
|||
index 2b58c58d3e..1baad849c6 100644
|
|||
--- a/src/util/virnetdevbandwidth.c
|
|||
+++ b/src/util/virnetdevbandwidth.c
|
|||
@@ -173,30 +173,35 @@ virNetDevBandwidthManipulateFilter(const char *ifname,
|
|||
* virNetDevBandwidthSet: |
|||
* @ifname: on which interface |
|||
* @bandwidth: rates to set (may be NULL) |
|||
- * @hierarchical_class: whether to create hierarchical class
|
|||
- * @swapped: true if IN/OUT should be set contrariwise
|
|||
+ * @flags: bits indicating certain optional actions
|
|||
* |
|||
+
|
|||
* This function enables QoS on specified interface |
|||
* and set given traffic limits for both, incoming |
|||
- * and outgoing traffic. Any previous setting get
|
|||
- * overwritten. If @hierarchical_class is TRUE, create
|
|||
- * hierarchical class. It is used to guarantee minimal
|
|||
- * throughput ('floor' attribute in NIC).
|
|||
+ * and outgoing traffic.
|
|||
+ *
|
|||
+ * @flags bits and their meanings:
|
|||
+ *
|
|||
+ * VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS
|
|||
+ * whether to create a hierarchical class
|
|||
+ * A hiearchical class structure is used to implement a minimal
|
|||
+ * throughput guarantee ('floor' attribute in NIC).
|
|||
* |
|||
- * If @swapped is set, the IN part of @bandwidth is set on
|
|||
- * @ifname's TX, and vice versa. If it is not set, IN is set on
|
|||
- * RX and OUT on TX. This is because for some types of interfaces
|
|||
- * domain and the host live on the same side of the interface (so
|
|||
- * domain's RX/TX is host's RX/TX), and for some it's swapped
|
|||
- * (domain's RX/TX is hosts's TX/RX).
|
|||
+ * VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED
|
|||
+ * set if IN/OUT should be set backwards from what's indicated in
|
|||
+ * the bandwidth, i.e. the IN part of @bandwidth is set on
|
|||
+ * @ifname's TX, and the OUT part of @bandwidth is set on
|
|||
+ * @ifname's RX. This is needed because for some types of
|
|||
+ * interfaces the domain and the host live on the same side of the
|
|||
+ * interface (so domain's RX/TX is host's RX/TX), and for some
|
|||
+ * it's swapped (domain's RX/TX is hosts's TX/RX).
|
|||
* |
|||
* Return 0 on success, -1 otherwise. |
|||
*/ |
|||
int |
|||
virNetDevBandwidthSet(const char *ifname, |
|||
const virNetDevBandwidth *bandwidth, |
|||
- bool hierarchical_class,
|
|||
- bool swapped)
|
|||
+ unsigned int flags)
|
|||
{ |
|||
int ret = -1; |
|||
virNetDevBandwidthRate *rx = NULL; /* From domain POV */ |
|||
@@ -205,6 +210,7 @@ virNetDevBandwidthSet(const char *ifname,
|
|||
char *average = NULL; |
|||
char *peak = NULL; |
|||
char *burst = NULL; |
|||
+ bool hierarchical_class = flags & VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS;
|
|||
|
|||
if (!bandwidth) { |
|||
/* nothing to be enabled */ |
|||
@@ -224,7 +230,7 @@ virNetDevBandwidthSet(const char *ifname,
|
|||
return -1; |
|||
} |
|||
|
|||
- if (swapped) {
|
|||
+ if (flags & VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED) {
|
|||
rx = bandwidth->out; |
|||
tx = bandwidth->in; |
|||
} else { |
|||
diff --git a/src/util/virnetdevbandwidth.h b/src/util/virnetdevbandwidth.h
|
|||
index 6d268fb119..80dc654486 100644
|
|||
--- a/src/util/virnetdevbandwidth.h
|
|||
+++ b/src/util/virnetdevbandwidth.h
|
|||
@@ -39,11 +39,16 @@ void virNetDevBandwidthFree(virNetDevBandwidth *def);
|
|||
|
|||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetDevBandwidth, virNetDevBandwidthFree); |
|||
|
|||
+typedef enum {
|
|||
+ VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS = (1 << 0),
|
|||
+ VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED = (1 << 1),
|
|||
+} virNetDevBandwidthSetFlags;
|
|||
+
|
|||
int virNetDevBandwidthSet(const char *ifname, |
|||
const virNetDevBandwidth *bandwidth, |
|||
- bool hierarchical_class,
|
|||
- bool swapped)
|
|||
+ unsigned int flags)
|
|||
G_GNUC_WARN_UNUSED_RESULT; |
|||
+
|
|||
int virNetDevBandwidthClear(const char *ifname); |
|||
int virNetDevBandwidthCopy(virNetDevBandwidth **dest, |
|||
const virNetDevBandwidth *src) |
|||
diff --git a/tests/virnetdevbandwidthtest.c b/tests/virnetdevbandwidthtest.c
|
|||
index f7c38faa2e..6529ff4026 100644
|
|||
--- a/tests/virnetdevbandwidthtest.c
|
|||
+++ b/tests/virnetdevbandwidthtest.c
|
|||
@@ -82,8 +82,14 @@ testVirNetDevBandwidthSet(const void *data)
|
|||
if (virNetDevOpenvswitchInterfaceSetQos(iface, band, info->uuid, true) < 0) |
|||
return -1; |
|||
} else { |
|||
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
|
|||
+
|
|||
+ if (info->hierarchical_class)
|
|||
+ flags |= VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS;
|
|||
+
|
|||
exp_cmd = info->exp_cmd_tc; |
|||
- if (virNetDevBandwidthSet(iface, band, info->hierarchical_class, true) < 0)
|
|||
+
|
|||
+ if (virNetDevBandwidthSet(iface, band, flags) < 0)
|
|||
return -1; |
|||
} |
|||
|
|||
--
|
|||
2.47.1 |
|||
|
|||
@ -1,185 +0,0 @@ |
|||
From 490f58382dca2a415a5f16b6133f298d853bb379 Mon Sep 17 00:00:00 2001 |
|||
From: Laine Stump <laine@redhat.com> |
|||
Date: Mon, 25 Nov 2024 22:24:45 -0500 |
|||
Subject: [PATCH 5/9] util: make it optional to clear existing tc |
|||
qdiscs/filters in virNetDevBandwidthSet() |
|||
|
|||
virNetDevBandwidthSet() always clears all existing qdiscs and their |
|||
subordinate filters before adding all the new qdiscs/filters. This is |
|||
normally exactly what we want, but there is one case (the network |
|||
driver) where the Qdisc added by virNetDevBandwidthSet() may already |
|||
be in use by the nftables backend (which will add a rule to fix the |
|||
checksum of dhcp packets); in that case, we *don't* want |
|||
virNetDevBandwidthSet() to clear out the qdisc that was already added |
|||
for nftables, and none of the bandwidth filters have been added yet, |
|||
so there already aren't any "old" filters that need to be removed |
|||
either - it is safe to just skip virNetDevBandwidthClear() in this |
|||
case. |
|||
|
|||
To allow the network driver to set bandwidth without first clearing |
|||
it, this patch adds the flag VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL to the |
|||
virNetDevBandwidthSetFlags enum, and recognizes it in |
|||
virNetDevBandwidthSet() - if the flag is set, then |
|||
virNetDevBandwidth() will call virNetDevBandwidthClear() just as it |
|||
always has. But if the flag isn't set it *won't* call |
|||
virNetDevBandwidthClear(). |
|||
|
|||
As suggested above, VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL is set for all |
|||
calls to virNetdevBandwidthSet() except for two places in the network |
|||
driver. |
|||
|
|||
Signed-off-by: Laine Stump <laine@redhat.com> |
|||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> |
|||
---
|
|||
src/lxc/lxc_driver.c | 2 +- |
|||
src/lxc/lxc_process.c | 2 +- |
|||
src/qemu/qemu_command.c | 2 +- |
|||
src/qemu/qemu_driver.c | 2 +- |
|||
src/qemu/qemu_hotplug.c | 4 ++-- |
|||
src/util/virnetdevbandwidth.c | 21 ++++++++++++++++++++- |
|||
src/util/virnetdevbandwidth.h | 1 + |
|||
tests/virnetdevbandwidthtest.c | 3 ++- |
|||
8 files changed, 29 insertions(+), 8 deletions(-) |
|||
|
|||
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
|
|||
index b693980dbb..81581c74df 100644
|
|||
--- a/src/lxc/lxc_driver.c
|
|||
+++ b/src/lxc/lxc_driver.c
|
|||
@@ -3570,7 +3570,7 @@ lxcDomainAttachDeviceNetLive(virLXCDriver *driver,
|
|||
actualBandwidth = virDomainNetGetActualBandwidth(net); |
|||
if (actualBandwidth) { |
|||
if (virNetDevSupportsBandwidth(actualType)) { |
|||
- unsigned int flags = 0;
|
|||
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
|
|||
|
|||
if (!virDomainNetTypeSharesHostView(net)) |
|||
flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; |
|||
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
|
|||
index 0e689fbb70..081ce03a57 100644
|
|||
--- a/src/lxc/lxc_process.c
|
|||
+++ b/src/lxc/lxc_process.c
|
|||
@@ -605,7 +605,7 @@ virLXCProcessSetupInterfaces(virLXCDriver *driver,
|
|||
actualBandwidth = virDomainNetGetActualBandwidth(net); |
|||
if (actualBandwidth) { |
|||
if (virNetDevSupportsBandwidth(type)) { |
|||
- unsigned int flags = 0;
|
|||
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
|
|||
|
|||
if (!virDomainNetTypeSharesHostView(net)) |
|||
flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; |
|||
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|||
index b4815e5e71..ed54fd4c5b 100644
|
|||
--- a/src/qemu/qemu_command.c
|
|||
+++ b/src/qemu/qemu_command.c
|
|||
@@ -8841,7 +8841,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver,
|
|||
!virDomainNetTypeSharesHostView(net)) < 0) |
|||
goto cleanup; |
|||
} else { |
|||
- unsigned int flags = 0;
|
|||
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
|
|||
|
|||
if (!virDomainNetTypeSharesHostView(net)) |
|||
flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; |
|||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|||
index 14929616e5..9549065b1f 100644
|
|||
--- a/src/qemu/qemu_driver.c
|
|||
+++ b/src/qemu/qemu_driver.c
|
|||
@@ -9942,7 +9942,7 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
|
|||
goto endjob; |
|||
} |
|||
} else { |
|||
- unsigned int bwflags = 0;
|
|||
+ unsigned int bwflags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
|
|||
|
|||
if (!virDomainNetTypeSharesHostView(net)) |
|||
bwflags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; |
|||
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
|||
index d5e7e99359..ceda4119cd 100644
|
|||
--- a/src/qemu/qemu_hotplug.c
|
|||
+++ b/src/qemu/qemu_hotplug.c
|
|||
@@ -1280,7 +1280,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
|
|||
!virDomainNetTypeSharesHostView(net)) < 0) |
|||
goto cleanup; |
|||
} else { |
|||
- int flags = 0;
|
|||
+ int flags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
|
|||
|
|||
if (!virDomainNetTypeSharesHostView(net)) |
|||
flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; |
|||
@@ -4088,7 +4088,7 @@ qemuDomainChangeNet(virQEMUDriver *driver,
|
|||
!virDomainNetTypeSharesHostView(newdev)) < 0) |
|||
goto cleanup; |
|||
} else { |
|||
- int flags = 0;
|
|||
+ int flags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
|
|||
|
|||
if (!virDomainNetTypeSharesHostView(newdev)) |
|||
flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; |
|||
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
|
|||
index 1baad849c6..9c48844c5d 100644
|
|||
--- a/src/util/virnetdevbandwidth.c
|
|||
+++ b/src/util/virnetdevbandwidth.c
|
|||
@@ -196,6 +196,21 @@ virNetDevBandwidthManipulateFilter(const char *ifname,
|
|||
* interface (so domain's RX/TX is host's RX/TX), and for some |
|||
* it's swapped (domain's RX/TX is hosts's TX/RX). |
|||
* |
|||
+ * VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL
|
|||
+ * If VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL is set, then the root
|
|||
+ * qdisc is deleted before adding any new qdisc/class/filter,
|
|||
+ * which causes any pre-existing filters to also be deleted. If
|
|||
+ * not set, then it's assumed that there are no existing rules (or
|
|||
+ * that those already there need to be kept). The caller should
|
|||
+ * set this flag for an existing interface that is having its
|
|||
+ * bandwidth settings modified, but can leave it unset if the
|
|||
+ * interface was newly created and this is the first time
|
|||
+ * bandwidth has been set, but someone else might have already
|
|||
+ * added the qdisc (e.g. this is the case when the network driver
|
|||
+ * is setting bandwidth for a virtual network bridge device - the
|
|||
+ * nftables backend may have already added qdisc handle 1:0 and a
|
|||
+ * filter, and we don't want to delete them)
|
|||
+ *
|
|||
* Return 0 on success, -1 otherwise. |
|||
*/ |
|||
int |
|||
@@ -238,7 +253,11 @@ virNetDevBandwidthSet(const char *ifname,
|
|||
tx = bandwidth->out; |
|||
} |
|||
|
|||
- virNetDevBandwidthClear(ifname);
|
|||
+ /* Only if the caller requests, clear everything including root
|
|||
+ * qdisc and all filters before adding everything.
|
|||
+ */
|
|||
+ if (flags & VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL)
|
|||
+ virNetDevBandwidthClear(ifname);
|
|||
|
|||
if (tx && tx->average) { |
|||
average = g_strdup_printf("%llukbps", tx->average); |
|||
diff --git a/src/util/virnetdevbandwidth.h b/src/util/virnetdevbandwidth.h
|
|||
index 80dc654486..744aa4c826 100644
|
|||
--- a/src/util/virnetdevbandwidth.h
|
|||
+++ b/src/util/virnetdevbandwidth.h
|
|||
@@ -42,6 +42,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetDevBandwidth, virNetDevBandwidthFree);
|
|||
typedef enum { |
|||
VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS = (1 << 0), |
|||
VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED = (1 << 1), |
|||
+ VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL = (1 << 2),
|
|||
} virNetDevBandwidthSetFlags; |
|||
|
|||
int virNetDevBandwidthSet(const char *ifname, |
|||
diff --git a/tests/virnetdevbandwidthtest.c b/tests/virnetdevbandwidthtest.c
|
|||
index 6529ff4026..6d5c847ad7 100644
|
|||
--- a/tests/virnetdevbandwidthtest.c
|
|||
+++ b/tests/virnetdevbandwidthtest.c
|
|||
@@ -82,7 +82,8 @@ testVirNetDevBandwidthSet(const void *data)
|
|||
if (virNetDevOpenvswitchInterfaceSetQos(iface, band, info->uuid, true) < 0) |
|||
return -1; |
|||
} else { |
|||
- unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
|
|||
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED |
|
|||
+ VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
|
|||
|
|||
if (info->hierarchical_class) |
|||
flags |= VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS; |
|||
--
|
|||
2.47.1 |
|||
|
|||
@ -1,98 +0,0 @@ |
|||
From faebbbbfa3b1bd4120852b3f416c8073ab82d5c5 Mon Sep 17 00:00:00 2001 |
|||
From: Laine Stump <laine@redhat.com> |
|||
Date: Mon, 25 Nov 2024 22:24:46 -0500 |
|||
Subject: [PATCH 6/9] util: put the command that adds a tx filter qdisc into a |
|||
separate function |
|||
|
|||
virNetDevBandwidthSet() adds a queue discipline (qdisc) for each |
|||
interface that it will need to add tc transmit filters to, and the |
|||
filters are then attached to the qdisc. |
|||
|
|||
There are other circumstances where some other function will need to |
|||
add tc transmit filters to an interface (in particular an upcoming |
|||
patch to the network driver nftables backend that will use a tc tx |
|||
filter to fix the checksum of dhcp packets), so that function will |
|||
also need a qdisc for the tx filter. To assure both always use exactly |
|||
the same qdisc, this patch puts the command that adds the tx filter |
|||
qdisc into a separate helper function that can (and will) be called |
|||
from either place |
|||
|
|||
Signed-off-by: Laine Stump <laine@redhat.com> |
|||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> |
|||
---
|
|||
src/libvirt_private.syms | 1 + |
|||
src/util/virnetdevbandwidth.c | 30 +++++++++++++++++++++++++----- |
|||
src/util/virnetdevbandwidth.h | 3 +++ |
|||
3 files changed, 29 insertions(+), 5 deletions(-) |
|||
|
|||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|||
index d15d6a6a9d..0211cee967 100644
|
|||
--- a/src/libvirt_private.syms
|
|||
+++ b/src/libvirt_private.syms
|
|||
@@ -2859,6 +2859,7 @@ virNetDevVFInterfaceStats;
|
|||
|
|||
|
|||
# util/virnetdevbandwidth.h |
|||
+virNetDevBandWidthAddTxFilterParentQdisc;
|
|||
virNetDevBandwidthClear; |
|||
virNetDevBandwidthCopy; |
|||
virNetDevBandwidthEqual; |
|||
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
|
|||
index 9c48844c5d..90eebe6576 100644
|
|||
--- a/src/util/virnetdevbandwidth.c
|
|||
+++ b/src/util/virnetdevbandwidth.c
|
|||
@@ -266,11 +266,7 @@ virNetDevBandwidthSet(const char *ifname,
|
|||
if (tx->burst) |
|||
burst = g_strdup_printf("%llukb", tx->burst); |
|||
|
|||
- cmd = virCommandNew(TC);
|
|||
- virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "root",
|
|||
- "handle", "1:", "htb", "default",
|
|||
- hierarchical_class ? "2" : "1", NULL);
|
|||
- if (virCommandRun(cmd, NULL) < 0)
|
|||
+ if (virNetDevBandWidthAddTxFilterParentQdisc(ifname, hierarchical_class) < 0)
|
|||
goto cleanup; |
|||
|
|||
/* If we are creating a hierarchical class, all non guaranteed traffic |
|||
@@ -794,3 +790,27 @@ virNetDevBandwidthSetRootQDisc(const char *ifname,
|
|||
|
|||
return 0; |
|||
} |
|||
+
|
|||
+/**
|
|||
+ * virNetDevBandwidthAddTxFilterParentQdisc:
|
|||
+ * @ifname: name of interface that needs a qdisc to attach tx filters to
|
|||
+ * @hierarchical_class: true if hierarchical classes will be used on this interface
|
|||
+ *
|
|||
+ * Add a root Qdisc (Queueing Discipline) for attaching Tx filters to
|
|||
+ * @ifname.
|
|||
+ *
|
|||
+ * returns 0 on success, -1 on failure
|
|||
+ */
|
|||
+int
|
|||
+virNetDevBandWidthAddTxFilterParentQdisc(const char *ifname,
|
|||
+ bool hierarchical_class)
|
|||
+{
|
|||
+ g_autoptr(virCommand) cmd = NULL;
|
|||
+
|
|||
+ cmd = virCommandNew(TC);
|
|||
+ virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "root",
|
|||
+ "handle", "1:", "htb", "default",
|
|||
+ hierarchical_class ? "2" : "1", NULL);
|
|||
+
|
|||
+ return virCommandRun(cmd, NULL);
|
|||
+}
|
|||
diff --git a/src/util/virnetdevbandwidth.h b/src/util/virnetdevbandwidth.h
|
|||
index 744aa4c826..65c1500637 100644
|
|||
--- a/src/util/virnetdevbandwidth.h
|
|||
+++ b/src/util/virnetdevbandwidth.h
|
|||
@@ -84,3 +84,6 @@ int virNetDevBandwidthUpdateFilter(const char *ifname,
|
|||
int virNetDevBandwidthSetRootQDisc(const char *ifname, |
|||
const char *qdisc) |
|||
G_NO_INLINE; |
|||
+
|
|||
+int virNetDevBandWidthAddTxFilterParentQdisc(const char *ifname,
|
|||
+ bool hierarchical_class);
|
|||
--
|
|||
2.47.1 |
|||
|
|||
@ -1,107 +0,0 @@ |
|||
From 73c0fb19ce5b816ee81ede691252855c75391c9a Mon Sep 17 00:00:00 2001 |
|||
From: Laine Stump <laine@redhat.com> |
|||
Date: Mon, 25 Nov 2024 22:24:47 -0500 |
|||
Subject: [PATCH 7/9] util: don't re-add the qdisc used for tx filters if it |
|||
already exists |
|||
|
|||
There will soon be two separate users of tc on virtual networks, and |
|||
both will use the "qdisc root handle 1: htb" to add tx filters. One or the |
|||
other could get the first chance to add the qdisc, and then if at a |
|||
later time the other decides to use it, we need to prevent the 2nd |
|||
user from attempting to re-add the qdisc (because that just generates |
|||
an error). |
|||
|
|||
We do this by running "tc qdisc show dev $bridge handle 1:" then |
|||
checking if the output of that command contains both "qdisc" and " 1: |
|||
".[*] If it does then the qdisc has already been added. If not then we |
|||
need to add it now. |
|||
|
|||
[*]As of this writing, the output more exactly starts with "qdisc |
|||
htb 1: root", but our comparison is made purposefully generous to |
|||
increase the chances that it will continue to work properly if tc |
|||
modifies the format of its output. |
|||
|
|||
Signed-off-by: Laine Stump <laine@redhat.com> |
|||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> |
|||
---
|
|||
src/util/virnetdevbandwidth.c | 35 ++++++++++++++++++++++++++++------ |
|||
tests/virnetdevbandwidthtest.c | 3 +++ |
|||
2 files changed, 32 insertions(+), 6 deletions(-) |
|||
|
|||
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
|
|||
index 90eebe6576..5c6a65528c 100644
|
|||
--- a/src/util/virnetdevbandwidth.c
|
|||
+++ b/src/util/virnetdevbandwidth.c
|
|||
@@ -805,12 +805,35 @@ int
|
|||
virNetDevBandWidthAddTxFilterParentQdisc(const char *ifname, |
|||
bool hierarchical_class) |
|||
{ |
|||
- g_autoptr(virCommand) cmd = NULL;
|
|||
+ g_autoptr(virCommand) testCmd = NULL;
|
|||
+ g_autofree char *testResult = NULL;
|
|||
|
|||
- cmd = virCommandNew(TC);
|
|||
- virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "root",
|
|||
- "handle", "1:", "htb", "default",
|
|||
- hierarchical_class ? "2" : "1", NULL);
|
|||
+ /* first check it the qdisc with handle 1: was already added for
|
|||
+ * this interface by someone else
|
|||
+ */
|
|||
+ testCmd = virCommandNew(TC);
|
|||
+ virCommandAddArgList(testCmd, "qdisc", "show", "dev", ifname,
|
|||
+ "handle", "1:", NULL);
|
|||
+ virCommandSetOutputBuffer(testCmd, &testResult);
|
|||
|
|||
- return virCommandRun(cmd, NULL);
|
|||
+ if (virCommandRun(testCmd, NULL) < 0)
|
|||
+ return -1;
|
|||
+
|
|||
+ /* output will be something like: "qdisc htb 1: root refcnt ..."
|
|||
+ * if the qdisc was already added. We just search for "qdisc" and
|
|||
+ * " 1: " anywhere in the output to allow for tc changing its
|
|||
+ * output format.
|
|||
+ */
|
|||
+ if (!(testResult && strstr(testResult, "qdisc") && strstr(testResult, " 1: "))) {
|
|||
+ /* didn't find qdisc in output, so we need to add one */
|
|||
+ g_autoptr(virCommand) addCmd = virCommandNew(TC);
|
|||
+
|
|||
+ virCommandAddArgList(addCmd, "qdisc", "add", "dev", ifname, "root",
|
|||
+ "handle", "1:", "htb", "default",
|
|||
+ hierarchical_class ? "2" : "1", NULL);
|
|||
+
|
|||
+ return virCommandRun(addCmd, NULL);
|
|||
+ }
|
|||
+
|
|||
+ return 0;
|
|||
} |
|||
diff --git a/tests/virnetdevbandwidthtest.c b/tests/virnetdevbandwidthtest.c
|
|||
index 6d5c847ad7..31aa7f469d 100644
|
|||
--- a/tests/virnetdevbandwidthtest.c
|
|||
+++ b/tests/virnetdevbandwidthtest.c
|
|||
@@ -147,6 +147,7 @@ mymain(void)
|
|||
"</bandwidth>", |
|||
TC " qdisc del dev eth0 root\n" |
|||
TC " qdisc del dev eth0 ingress\n" |
|||
+ TC " qdisc show dev eth0 handle 1:\n"
|
|||
TC " qdisc add dev eth0 root handle 1: htb default 1\n" |
|||
TC " class add dev eth0 parent 1: classid 1:1 htb rate 1024kbps quantum 87\n" |
|||
TC " qdisc add dev eth0 parent 1:1 handle 2: sfq perturb 10\n" |
|||
@@ -177,6 +178,7 @@ mymain(void)
|
|||
"</bandwidth>", |
|||
TC " qdisc del dev eth0 root\n" |
|||
TC " qdisc del dev eth0 ingress\n" |
|||
+ TC " qdisc show dev eth0 handle 1:\n"
|
|||
TC " qdisc add dev eth0 root handle 1: htb default 1\n" |
|||
TC " class add dev eth0 parent 1: classid 1:1 htb rate 1kbps ceil 2kbps burst 4kb quantum 1\n" |
|||
TC " qdisc add dev eth0 parent 1:1 handle 2: sfq perturb 10\n" |
|||
@@ -199,6 +201,7 @@ mymain(void)
|
|||
"</bandwidth>", |
|||
TC " qdisc del dev eth0 root\n" |
|||
TC " qdisc del dev eth0 ingress\n" |
|||
+ TC " qdisc show dev eth0 handle 1:\n"
|
|||
TC " qdisc add dev eth0 root handle 1: htb default 1\n" |
|||
TC " class add dev eth0 parent 1: classid 1:1 htb rate 4294967295kbps quantum 366503875\n" |
|||
TC " qdisc add dev eth0 parent 1:1 handle 2: sfq perturb 10\n" |
|||
--
|
|||
2.47.1 |
|||
|
|||
@ -1,171 +0,0 @@ |
|||
From dac9cb9030ac03d18f59884864a0a253e3c9f8f1 Mon Sep 17 00:00:00 2001 |
|||
From: Laine Stump <laine@redhat.com> |
|||
Date: Mon, 25 Nov 2024 22:24:48 -0500 |
|||
Subject: [PATCH 8/9] util: add new "tc" layer for virFirewallCmd objects |
|||
|
|||
If the layer of a virFirewallCmd is "tc", then the "tc" utility will |
|||
be executed using the arguments that had been added to the |
|||
virFirewallCmd |
|||
|
|||
tc layer doesn't support auto-rollback command creation (any rollback |
|||
needs to be added manually with virFirewallAddRollbackCmd()), and also |
|||
tc layer isn't supported by the iptables backend (it would have been |
|||
straightforward to add, but the iptables backend doesn't need it, and |
|||
I didn't want to take the chance of causing a regression in that |
|||
code for no good reason). |
|||
|
|||
Signed-off-by: Laine Stump <laine@redhat.com> |
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> |
|||
---
|
|||
src/network/network_nftables.c | 1 + |
|||
src/util/virfirewall.c | 66 +++++++++++++++++++++------------- |
|||
src/util/virfirewall.h | 1 + |
|||
src/util/virfirewalld.c | 1 + |
|||
4 files changed, 44 insertions(+), 25 deletions(-) |
|||
|
|||
diff --git a/src/network/network_nftables.c b/src/network/network_nftables.c
|
|||
index 268d1f12ca..cc184105c3 100644
|
|||
--- a/src/network/network_nftables.c
|
|||
+++ b/src/network/network_nftables.c
|
|||
@@ -73,6 +73,7 @@ VIR_ENUM_IMPL(nftablesLayer,
|
|||
"", |
|||
"ip", |
|||
"ip6", |
|||
+ "",
|
|||
); |
|||
|
|||
|
|||
diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
|
|||
index 811b787ecc..9389bcf541 100644
|
|||
--- a/src/util/virfirewall.c
|
|||
+++ b/src/util/virfirewall.c
|
|||
@@ -47,6 +47,7 @@ VIR_ENUM_IMPL(virFirewallLayer,
|
|||
"ethernet", |
|||
"ipv4", |
|||
"ipv6", |
|||
+ "tc",
|
|||
); |
|||
|
|||
typedef struct _virFirewallGroup virFirewallGroup; |
|||
@@ -57,6 +58,7 @@ VIR_ENUM_IMPL(virFirewallLayerCommand,
|
|||
EBTABLES, |
|||
IPTABLES, |
|||
IP6TABLES, |
|||
+ TC,
|
|||
); |
|||
|
|||
struct _virFirewallCmd { |
|||
@@ -591,6 +593,7 @@ virFirewallCmdIptablesApply(virFirewall *firewall,
|
|||
case VIR_FIREWALL_LAYER_IPV6: |
|||
virCommandAddArg(cmd, "-w"); |
|||
break; |
|||
+ case VIR_FIREWALL_LAYER_TC:
|
|||
case VIR_FIREWALL_LAYER_LAST: |
|||
break; |
|||
} |
|||
@@ -672,39 +675,52 @@ virFirewallCmdNftablesApply(virFirewall *firewall G_GNUC_UNUSED,
|
|||
size_t i; |
|||
int status; |
|||
|
|||
- cmd = virCommandNew(NFT);
|
|||
+ if (fwCmd->layer == VIR_FIREWALL_LAYER_TC) {
|
|||
|
|||
- if ((virFirewallTransactionGetFlags(firewall) & VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK) &&
|
|||
- fwCmd->argsLen > 1) {
|
|||
- /* skip any leading options to get to command verb */
|
|||
- for (i = 0; i < fwCmd->argsLen - 1; i++) {
|
|||
- if (fwCmd->args[i][0] != '-')
|
|||
- break;
|
|||
- }
|
|||
+ /* for VIR_FIREWALL_LAYER_TC, we run the 'tc' (traffic control) command with
|
|||
+ * the supplied args.
|
|||
+ */
|
|||
+ cmd = virCommandNew(TC);
|
|||
|
|||
- if (i + 1 < fwCmd->argsLen &&
|
|||
- VIR_NFTABLES_ARG_IS_CREATE(fwCmd->args[i])) {
|
|||
+ /* NB: RAW commands don't support auto-rollback command creation */
|
|||
|
|||
- cmdIdx = i;
|
|||
- objectType = fwCmd->args[i + 1];
|
|||
+ } else {
|
|||
|
|||
- /* we currently only handle auto-rollback for rules,
|
|||
- * chains, and tables, and those all can be "rolled
|
|||
- * back" by a delete command using the handle that is
|
|||
- * returned when "-ae" is added to the add/insert
|
|||
- * command.
|
|||
- */
|
|||
- if (STREQ_NULLABLE(objectType, "rule") ||
|
|||
- STREQ_NULLABLE(objectType, "chain") ||
|
|||
- STREQ_NULLABLE(objectType, "table")) {
|
|||
+ cmd = virCommandNew(NFT);
|
|||
|
|||
- needRollback = true;
|
|||
- /* this option to nft instructs it to add the
|
|||
- * "handle" of the created object to stdout
|
|||
+ if ((virFirewallTransactionGetFlags(firewall) & VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK) &&
|
|||
+ fwCmd->argsLen > 1) {
|
|||
+ /* skip any leading options to get to command verb */
|
|||
+ for (i = 0; i < fwCmd->argsLen - 1; i++) {
|
|||
+ if (fwCmd->args[i][0] != '-')
|
|||
+ break;
|
|||
+ }
|
|||
+
|
|||
+ if (i + 1 < fwCmd->argsLen &&
|
|||
+ VIR_NFTABLES_ARG_IS_CREATE(fwCmd->args[i])) {
|
|||
+
|
|||
+ cmdIdx = i;
|
|||
+ objectType = fwCmd->args[i + 1];
|
|||
+
|
|||
+ /* we currently only handle auto-rollback for rules,
|
|||
+ * chains, and tables, and those all can be "rolled
|
|||
+ * back" by a delete command using the handle that is
|
|||
+ * returned when "-ae" is added to the add/insert
|
|||
+ * command.
|
|||
*/ |
|||
- virCommandAddArg(cmd, "-ae");
|
|||
+ if (STREQ_NULLABLE(objectType, "rule") ||
|
|||
+ STREQ_NULLABLE(objectType, "chain") ||
|
|||
+ STREQ_NULLABLE(objectType, "table")) {
|
|||
+
|
|||
+ needRollback = true;
|
|||
+ /* this option to nft instructs it to add the
|
|||
+ * "handle" of the created object to stdout
|
|||
+ */
|
|||
+ virCommandAddArg(cmd, "-ae");
|
|||
+ }
|
|||
} |
|||
} |
|||
+
|
|||
} |
|||
|
|||
for (i = 0; i < fwCmd->argsLen; i++) |
|||
diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h
|
|||
index bce51259d2..d42e60884b 100644
|
|||
--- a/src/util/virfirewall.h
|
|||
+++ b/src/util/virfirewall.h
|
|||
@@ -39,6 +39,7 @@ typedef enum {
|
|||
VIR_FIREWALL_LAYER_ETHERNET, |
|||
VIR_FIREWALL_LAYER_IPV4, |
|||
VIR_FIREWALL_LAYER_IPV6, |
|||
+ VIR_FIREWALL_LAYER_TC,
|
|||
|
|||
VIR_FIREWALL_LAYER_LAST, |
|||
} virFirewallLayer; |
|||
diff --git a/src/util/virfirewalld.c b/src/util/virfirewalld.c
|
|||
index 827e201dbb..124523c420 100644
|
|||
--- a/src/util/virfirewalld.c
|
|||
+++ b/src/util/virfirewalld.c
|
|||
@@ -43,6 +43,7 @@ VIR_LOG_INIT("util.firewalld");
|
|||
VIR_ENUM_DECL(virFirewallLayerFirewallD); |
|||
VIR_ENUM_IMPL(virFirewallLayerFirewallD, |
|||
VIR_FIREWALL_LAYER_LAST, |
|||
+ "",
|
|||
"eb", |
|||
"ipv4", |
|||
"ipv6", |
|||
--
|
|||
2.47.1 |
|||
|
|||
@ -1,687 +0,0 @@ |
|||
From b1e2318a0d609fcdff04fcf88953ea87cdd02b95 Mon Sep 17 00:00:00 2001 |
|||
From: Laine Stump <laine@redhat.com> |
|||
Date: Mon, 25 Nov 2024 22:24:49 -0500 |
|||
Subject: [PATCH 9/9] network: add tc filter rule to nftables backend to fix |
|||
checksum of DHCP responses |
|||
|
|||
Please see the commit log for commit v10.9.0-rc1-1-g42ab0148dd for the |
|||
history and explanation of the problem that this patch is fixing. |
|||
|
|||
A shorter explanation is that when a guest is connected to a libvirt |
|||
virtual network using a virtio-net adapter with in-kernel "vhost-net" |
|||
packet processing enabled, it will fail to acquire an IP address from |
|||
a DHCP seever running on the host. |
|||
|
|||
In commit v10.9.0-rc1-1-g42ab0148dd we tried fixing this by *zeroing |
|||
out* the checksums of these packets with an nftables rule (nftables |
|||
can't recompute the checksum, but it can set it to 0) . This |
|||
*appeared* to work initially, but it turned out that zeroing the |
|||
checksum ends up breaking dhcp packets on *non* virtio/vhost-net guest |
|||
interfaces. That attempt was reverted in commit v10.9.0-rc2. |
|||
|
|||
Fortunately, there is an existing way to recompute the checksum of a |
|||
packet as it leaves an interface - the "tc" (traffic control) utility |
|||
that libvirt already uses for bandwidth management. This patch uses a |
|||
tc filter rule to match dhcp response packets on the bridge and |
|||
recompute their checksum. |
|||
|
|||
The filter rule must be attached to a tc qdisc, which may also have a |
|||
filter attached for bandwidth management (in the <bandwidth> element |
|||
of the network config). Not only must we add the qdisc only once |
|||
(which was already handled by the patch two prior to this one), but |
|||
also the filter rule for checksum fixing and the filter rule for |
|||
bandwidth management must be different priorities so they don't clash; |
|||
this is solved by adding the checksum-fix filter with "priority 2", |
|||
while the bandwidth management filter remains "priority 1" (both will |
|||
always be evaluated anyway, it's just a matter of which is evaluated |
|||
first). |
|||
|
|||
So far this method has worked with every different guest we could |
|||
throw at it, including several that failed with the previous method. |
|||
|
|||
Fixes: b89c4991daa0ee9371f10937fab3b03c5ffdabc6 |
|||
Reported-by: Rich Jones <rjones@redhat.com> |
|||
Reported-by: Andrea Bolognani <abologna@redhat.com> |
|||
Fix-Suggested-by: Eric Garver <egarver@redhat.com> |
|||
Fix-Suggested-by: Phil Sutter <psutter@redhat.com> |
|||
Signed-off-by: Laine Stump <laine@redhat.com> |
|||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> |
|||
---
|
|||
src/network/network_nftables.c | 68 +++++++++++++++++++ |
|||
.../forward-dev-linux.nftables | 40 +++++++++++ |
|||
.../isolated-linux.nftables | 40 +++++++++++ |
|||
.../nat-default-linux.nftables | 40 +++++++++++ |
|||
.../nat-ipv6-linux.nftables | 40 +++++++++++ |
|||
.../nat-ipv6-masquerade-linux.nftables | 40 +++++++++++ |
|||
.../nat-many-ips-linux.nftables | 40 +++++++++++ |
|||
.../nat-no-dhcp-linux.nftables | 40 +++++++++++ |
|||
.../nat-port-range-ipv6-linux.nftables | 40 +++++++++++ |
|||
.../nat-port-range-linux.nftables | 40 +++++++++++ |
|||
.../nat-tftp-linux.nftables | 40 +++++++++++ |
|||
.../route-default-linux.nftables | 40 +++++++++++ |
|||
12 files changed, 508 insertions(+) |
|||
|
|||
diff --git a/src/network/network_nftables.c b/src/network/network_nftables.c
|
|||
index cc184105c3..748edb0273 100644
|
|||
--- a/src/network/network_nftables.c
|
|||
+++ b/src/network/network_nftables.c
|
|||
@@ -29,6 +29,7 @@
|
|||
|
|||
#include "internal.h" |
|||
#include "virfirewalld.h" |
|||
+#include "vircommand.h"
|
|||
#include "virerror.h" |
|||
#include "virlog.h" |
|||
#include "virhash.h" |
|||
@@ -924,6 +925,67 @@ nftablesAddIPSpecificFirewallRules(virFirewall *fw,
|
|||
} |
|||
|
|||
|
|||
+/**
|
|||
+ * nftablesAddUdpChecksumFixWithTC:
|
|||
+ *
|
|||
+ * Add a tc filter rule to @ifname (the bridge device of this network)
|
|||
+ * that will recompute the checksum of udp packets output from @iface with
|
|||
+ * destination port @port.
|
|||
+ *
|
|||
+ * Normally the checksum should be filled by some part of the basic
|
|||
+ * network stack, but there are cases (e.g. DHCP response packets sent
|
|||
+ * from virtualization host to a QEMU guest when the guest NIC uses
|
|||
+ * vhost-net packet processing) when the host (sender) thinks that
|
|||
+ * packet checksums will be computed elsewhere (and so leaves a
|
|||
+ * partially computed checksum in the packet header) while the guest
|
|||
+ * (receiver) thinks that the checksum has already been fully
|
|||
+ * computed; in the meantime none of the code in between has actually
|
|||
+ * finished computing the checksum.
|
|||
+ *
|
|||
+ * An example of this is DHCP response packets from host to guest. If
|
|||
+ * the checksum of each of these packets isn't properly computed, then
|
|||
+ * many guests (e.g. FreeBSD) will drop them with reason BAD CHECKSUM;
|
|||
+ * this tc filter rule will fix the ip and udp checksums, and the
|
|||
+ * FreeBSD dhcp client will happily accept the packet.
|
|||
+ *
|
|||
+ * (NB: if you're wondering how the tc qdisc and filter are removed
|
|||
+ * when the network is destroyed, the answer is that the kernel
|
|||
+ * automatically (and properly) removes them for us, so we don't need
|
|||
+ * to worry about keeping track/deleting as we do with nftables rules)
|
|||
+ */
|
|||
+static int
|
|||
+nftablesAddUdpChecksumFixWithTC(virFirewall *fw,
|
|||
+ const char *iface,
|
|||
+ int port)
|
|||
+{
|
|||
+ g_autofree char *portstr = g_strdup_printf("%d", port);
|
|||
+
|
|||
+ /* this will add the qdisc (that the filter below is attached to)
|
|||
+ * unless it already exists
|
|||
+ */
|
|||
+ if (virNetDevBandWidthAddTxFilterParentQdisc(iface, true) < 0)
|
|||
+ return -1;
|
|||
+
|
|||
+ /* add a filter to catch all udp packets with dst "port" and
|
|||
+ * recompute their checksum
|
|||
+ */
|
|||
+ virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_TC,
|
|||
+ "filter", "add", "dev", iface,
|
|||
+ "prio", "2", "protocol", "ip", "parent", "1:",
|
|||
+ "u32", "match", "ip", "dport", portstr, "ffff",
|
|||
+ "action", "csum", "ip", "and", "udp",
|
|||
+ NULL);
|
|||
+
|
|||
+ virFirewallAddRollbackCmd(fw, VIR_FIREWALL_LAYER_TC,
|
|||
+ "filter", "del", "dev", iface,
|
|||
+ "prio", "2", "protocol", "ip", "parent", "1:",
|
|||
+ "u32", "match", "ip", "dport", portstr, "ffff",
|
|||
+ "action", "csum", "ip", "and", "udp",
|
|||
+ NULL);
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+
|
|||
/* nftablesAddFirewallrules: |
|||
* |
|||
* @def - the network that needs an nftables firewall added |
|||
@@ -944,6 +1006,12 @@ nftablesAddFirewallRules(virNetworkDef *def, virFirewall **fwRemoval)
|
|||
|
|||
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK); |
|||
|
|||
+ /* add the tc filter rule needed to fixup the checksum of dhcp
|
|||
+ * response packets going from host to guest.
|
|||
+ */
|
|||
+ if (nftablesAddUdpChecksumFixWithTC(fw, def->bridge, 68) < 0)
|
|||
+ return -1;
|
|||
+
|
|||
nftablesAddGeneralFirewallRules(fw, def); |
|||
|
|||
for (i = 0; |
|||
diff --git a/tests/networkxml2firewalldata/forward-dev-linux.nftables b/tests/networkxml2firewalldata/forward-dev-linux.nftables
|
|||
index 8badb74beb..6772383b37 100644
|
|||
--- a/tests/networkxml2firewalldata/forward-dev-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/forward-dev-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
diff --git a/tests/networkxml2firewalldata/isolated-linux.nftables b/tests/networkxml2firewalldata/isolated-linux.nftables
|
|||
index d1b4dac178..546a18b75a 100644
|
|||
--- a/tests/networkxml2firewalldata/isolated-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/isolated-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
diff --git a/tests/networkxml2firewalldata/nat-default-linux.nftables b/tests/networkxml2firewalldata/nat-default-linux.nftables
|
|||
index 28508292f9..08623c1381 100644
|
|||
--- a/tests/networkxml2firewalldata/nat-default-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/nat-default-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
diff --git a/tests/networkxml2firewalldata/nat-ipv6-linux.nftables b/tests/networkxml2firewalldata/nat-ipv6-linux.nftables
|
|||
index d8a9ba706d..3fd6b94eef 100644
|
|||
--- a/tests/networkxml2firewalldata/nat-ipv6-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/nat-ipv6-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
diff --git a/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.nftables b/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.nftables
|
|||
index a7f09cda59..2811e098d1 100644
|
|||
--- a/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
diff --git a/tests/networkxml2firewalldata/nat-many-ips-linux.nftables b/tests/networkxml2firewalldata/nat-many-ips-linux.nftables
|
|||
index b826fe6134..5409d5b552 100644
|
|||
--- a/tests/networkxml2firewalldata/nat-many-ips-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/nat-many-ips-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
diff --git a/tests/networkxml2firewalldata/nat-no-dhcp-linux.nftables b/tests/networkxml2firewalldata/nat-no-dhcp-linux.nftables
|
|||
index d8a9ba706d..3fd6b94eef 100644
|
|||
--- a/tests/networkxml2firewalldata/nat-no-dhcp-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/nat-no-dhcp-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
diff --git a/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables b/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables
|
|||
index ceaed6fa40..d74417cdb3 100644
|
|||
--- a/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
diff --git a/tests/networkxml2firewalldata/nat-port-range-linux.nftables b/tests/networkxml2firewalldata/nat-port-range-linux.nftables
|
|||
index 1dc37a26ec..b55bb287a9 100644
|
|||
--- a/tests/networkxml2firewalldata/nat-port-range-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/nat-port-range-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
diff --git a/tests/networkxml2firewalldata/nat-tftp-linux.nftables b/tests/networkxml2firewalldata/nat-tftp-linux.nftables
|
|||
index 28508292f9..08623c1381 100644
|
|||
--- a/tests/networkxml2firewalldata/nat-tftp-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/nat-tftp-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
diff --git a/tests/networkxml2firewalldata/route-default-linux.nftables b/tests/networkxml2firewalldata/route-default-linux.nftables
|
|||
index 282c9542a5..76d6902517 100644
|
|||
--- a/tests/networkxml2firewalldata/route-default-linux.nftables
|
|||
+++ b/tests/networkxml2firewalldata/route-default-linux.nftables
|
|||
@@ -1,3 +1,43 @@
|
|||
+tc \
|
|||
+qdisc \
|
|||
+show \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+handle \
|
|||
+1:
|
|||
+tc \
|
|||
+qdisc \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+root \
|
|||
+handle \
|
|||
+1: \
|
|||
+htb \
|
|||
+default \
|
|||
+2
|
|||
+tc \
|
|||
+filter \
|
|||
+add \
|
|||
+dev \
|
|||
+virbr0 \
|
|||
+prio \
|
|||
+2 \
|
|||
+protocol \
|
|||
+ip \
|
|||
+parent \
|
|||
+1: \
|
|||
+u32 \
|
|||
+match \
|
|||
+ip \
|
|||
+dport \
|
|||
+68 \
|
|||
+ffff \
|
|||
+action \
|
|||
+csum \
|
|||
+ip \
|
|||
+and \
|
|||
+udp
|
|||
nft \ |
|||
-ae insert \ |
|||
rule \ |
|||
--
|
|||
2.47.1 |
|||
|
|||
@ -1,51 +0,0 @@ |
|||
From 114c0ec656e879ab4d67919914bb24cf5993106d Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <114c0ec656e879ab4d67919914bb24cf5993106d.1734201785.git.crobinso@redhat.com> |
|||
From: Laine Stump <laine@redhat.com> |
|||
Date: Mon, 2 Sep 2024 16:13:08 -0400 |
|||
Subject: [PATCH] network: permit <forward mode='open'/> when a network has no |
|||
IP address |
|||
Content-type: text/plain |
|||
|
|||
The whole point of <forward mode='open'/> is to supress libvirt from |
|||
adding any firewall rules for a network, and someone might want to |
|||
create a network with no IP address (i.e. they don't want the guests |
|||
to have connectivity to the host via this interface) and no firewall |
|||
rules (they don't want any, or they want to add their own). So there's |
|||
no reason to fail when a network has <forward mode='open'/> and also |
|||
has no IP address. |
|||
|
|||
Kind-of-Resolves: https://gitlab.com/libvirt/libvirt/-/issues/588 |
|||
Signed-off-by: Laine Stump <laine@redhat.com> |
|||
Reviewed-by: Martin Kletzander <mkletzan@redhat.com> |
|||
Signed-off-by: Cole Robinson <crobinso@redhat.com> |
|||
---
|
|||
src/conf/network_conf.c | 5 +++-- |
|||
1 file changed, 3 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
|
|||
index 5cf419acf1..320e1b089a 100644
|
|||
--- a/src/conf/network_conf.c
|
|||
+++ b/src/conf/network_conf.c
|
|||
@@ -1789,7 +1789,6 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt,
|
|||
|
|||
case VIR_NETWORK_FORWARD_ROUTE: |
|||
case VIR_NETWORK_FORWARD_NAT: |
|||
- case VIR_NETWORK_FORWARD_OPEN:
|
|||
/* It's pointless to specify L3 forwarding without specifying |
|||
* the network we're on. |
|||
*/ |
|||
@@ -1806,8 +1805,10 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt,
|
|||
def->name); |
|||
return NULL; |
|||
} |
|||
+ break;
|
|||
|
|||
- if (def->forward.type == VIR_NETWORK_FORWARD_OPEN && def->forward.nifs) {
|
|||
+ case VIR_NETWORK_FORWARD_OPEN:
|
|||
+ if (def->forward.nifs) {
|
|||
/* an open network by definition can't place any restrictions |
|||
* on what traffic is allowed or where it goes, so specifying |
|||
* a forwarding device is nonsensical. |
|||
--
|
|||
2.47.1 |
|||
|
|||
@ -1,64 +0,0 @@ |
|||
From d51179fa82448f4720f1645f0b7100df80508cc4 Mon Sep 17 00:00:00 2001 |
|||
From: Pavel Hrdina <phrdina@redhat.com> |
|||
Date: Thu, 9 Jan 2025 16:23:44 +0100 |
|||
Subject: [PATCH] qemu: snapshot: delete disk image only if parent snapshot is |
|||
external |
|||
Content-type: text/plain |
|||
|
|||
When we are deleting external snapshot that is not active we only need |
|||
to delete overlay disk image of the parent snapshot. This works |
|||
correctly even if parent snapshot is external and active as it will have |
|||
another overlay created when user reverted to that snapshot. |
|||
|
|||
In case the parent snapshot is internal there are no overlay disk images |
|||
created as everything is stored internally within the disk image. In |
|||
this case we would delete the actual disk image storing internal |
|||
snapshots and most likely the original disk image as well resulting in |
|||
data loss once the VM is shutoff. |
|||
|
|||
Fixes: https://gitlab.com/libvirt/libvirt/-/issues/734 |
|||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
---
|
|||
src/qemu/qemu_snapshot.c | 14 ++++++++------ |
|||
1 file changed, 8 insertions(+), 6 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
|
|||
index 18b2e478f6..80cd54bf33 100644
|
|||
--- a/src/qemu/qemu_snapshot.c
|
|||
+++ b/src/qemu/qemu_snapshot.c
|
|||
@@ -3144,6 +3144,8 @@ qemuSnapshotDeleteExternalPrepareData(virDomainObj *vm,
|
|||
return -1; |
|||
} |
|||
|
|||
+ data->parentSnap = qemuSnapshotFindParentSnapForDisk(snap, data->snapDisk);
|
|||
+
|
|||
if (data->merge) { |
|||
virStorageSource *snapDiskSrc = NULL; |
|||
|
|||
@@ -3185,8 +3187,6 @@ qemuSnapshotDeleteExternalPrepareData(virDomainObj *vm,
|
|||
qemuSnapshotGetDisksWithBackingStore(vm, snap, data); |
|||
} |
|||
|
|||
- data->parentSnap = qemuSnapshotFindParentSnapForDisk(snap, data->snapDisk);
|
|||
-
|
|||
if (data->parentSnap && !virDomainSnapshotIsExternal(data->parentSnap)) { |
|||
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", |
|||
_("deleting external snapshot that has internal snapshot as parent not supported")); |
|||
@@ -3642,10 +3642,12 @@ qemuSnapshotDiscardExternal(virDomainObj *vm,
|
|||
if (!data->job) |
|||
goto error; |
|||
} else { |
|||
- if (virStorageSourceInit(data->parentDomDisk->src) < 0 ||
|
|||
- virStorageSourceUnlink(data->parentDomDisk->src) < 0) {
|
|||
- VIR_WARN("Failed to remove snapshot image '%s'",
|
|||
- data->snapDisk->name);
|
|||
+ if (data->parentSnap && virDomainSnapshotIsExternal(data->parentSnap)) {
|
|||
+ if (virStorageSourceInit(data->parentDomDisk->src) < 0 ||
|
|||
+ virStorageSourceUnlink(data->parentDomDisk->src) < 0) {
|
|||
+ VIR_WARN("Failed to remove snapshot image '%s'",
|
|||
+ data->snapDisk->name);
|
|||
+ }
|
|||
} |
|||
} |
|||
} |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:a495b2a26faca841ac0073c7dd7f60857ca81adac9047dac5f698fd75f1342cd |
|||
size 9481992 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:960dadef24223edf16578de75ab471acdf4119ec8e1402408e8c789577ed305e |
|||
size 34377346 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:931b78933e365c66ec4695cd0899b31fbe0f4f837fb1bb4144ff2ab19dbada8b |
|||
size 34379058 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:aacf01a3f75b3a9835321eace7f3c54c7e866c3df04deafa98084cc5541978f9 |
|||
size 34476233 |
|||
@ -1,31 +0,0 @@ |
|||
From 5629ebcb4234fde10fd9468d5fc5dd4947ed8677 Mon Sep 17 00:00:00 2001 |
|||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com> |
|||
Date: Tue, 29 Apr 2025 15:49:10 +0100 |
|||
Subject: [PATCH] Fix mocking of virQEMUCapsProbeHVF function |
|||
MIME-Version: 1.0 |
|||
Content-Type: text/plain; charset=UTF-8 |
|||
Content-Transfer-Encoding: 8bit |
|||
|
|||
From: Daniel P. Berrangé <berrange@redhat.com> |
|||
|
|||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> |
|||
---
|
|||
src/qemu/qemu_capabilities.h | 2 +- |
|||
1 file changed, 1 insertion(+), 1 deletion(-) |
|||
|
|||
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
|
|||
index ea7c14daa9..488a1a058e 100644
|
|||
--- a/src/qemu/qemu_capabilities.h
|
|||
+++ b/src/qemu/qemu_capabilities.h
|
|||
@@ -943,7 +943,7 @@ bool
|
|||
virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_NO_INLINE; |
|||
|
|||
bool |
|||
-virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps) G_NO_INLINE;
|
|||
+virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps) G_NO_INLINE __attribute__((noipa));
|
|||
|
|||
virArch virQEMUCapsArchFromString(const char *arch); |
|||
const char *virQEMUCapsArchToString(virArch arch); |
|||
--
|
|||
2.49.0 |
|||
|
|||
@ -1,85 +0,0 @@ |
|||
From 63a3d70697dc44ef2f8b40f7c8e9aa869227a7da Mon Sep 17 00:00:00 2001 |
|||
From: Jiang XueQian <jiangxueqian@gmail.com> |
|||
Date: Sat, 18 Jan 2025 16:32:10 +0800 |
|||
Subject: [PATCH] nss: Skip empty files and avoid use of uninitialized value |
|||
Content-type: text/plain |
|||
|
|||
JSON parser isn't called when reading empty files so `jerr` will be used |
|||
uninitialized in the original code. Empty files appear when a network |
|||
has no dhcp clients. |
|||
|
|||
This patch checks for such files and skip them. |
|||
|
|||
Fixes: a8d828c88bbdaf83ae78dc06cdd84d5667fcc424 |
|||
Signed-off-by: Jiang XueQian <jiangxueqian@gmail.com> |
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> |
|||
---
|
|||
tools/nss/libvirt_nss_leases.c | 9 +++++++-- |
|||
tools/nss/libvirt_nss_macs.c | 9 +++++++-- |
|||
2 files changed, 14 insertions(+), 4 deletions(-) |
|||
|
|||
diff --git a/tools/nss/libvirt_nss_leases.c b/tools/nss/libvirt_nss_leases.c
|
|||
index aea81bb56e..25ea6b0ce2 100644
|
|||
--- a/tools/nss/libvirt_nss_leases.c
|
|||
+++ b/tools/nss/libvirt_nss_leases.c
|
|||
@@ -263,7 +263,7 @@ findLeases(const char *file,
|
|||
enum json_tokener_error jerr; |
|||
int jsonflags = JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8; |
|||
char line[1024]; |
|||
- ssize_t nreadTotal = 0;
|
|||
+ size_t nreadTotal = 0;
|
|||
int rv; |
|||
|
|||
if ((fd = open(file, O_RDONLY)) < 0) { |
|||
@@ -290,12 +290,17 @@ findLeases(const char *file,
|
|||
jerr = json_tokener_get_error(tok); |
|||
} while (jerr == json_tokener_continue); |
|||
|
|||
+ if (nreadTotal == 0) {
|
|||
+ ret = 0;
|
|||
+ goto cleanup;
|
|||
+ }
|
|||
+
|
|||
if (jerr == json_tokener_continue) { |
|||
ERROR("Cannot parse %s: incomplete json found", file); |
|||
goto cleanup; |
|||
} |
|||
|
|||
- if (nreadTotal > 0 && jerr != json_tokener_success) {
|
|||
+ if (jerr != json_tokener_success) {
|
|||
ERROR("Cannot parse %s: %s", file, json_tokener_error_desc(jerr)); |
|||
goto cleanup; |
|||
} |
|||
diff --git a/tools/nss/libvirt_nss_macs.c b/tools/nss/libvirt_nss_macs.c
|
|||
index 23229a18f3..bac8c0e1bb 100644
|
|||
--- a/tools/nss/libvirt_nss_macs.c
|
|||
+++ b/tools/nss/libvirt_nss_macs.c
|
|||
@@ -124,7 +124,7 @@ findMACs(const char *file,
|
|||
json_tokener *tok = NULL; |
|||
enum json_tokener_error jerr; |
|||
int jsonflags = JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8; |
|||
- ssize_t nreadTotal = 0;
|
|||
+ size_t nreadTotal = 0;
|
|||
int rv; |
|||
size_t i; |
|||
|
|||
@@ -152,12 +152,17 @@ findMACs(const char *file,
|
|||
jerr = json_tokener_get_error(tok); |
|||
} while (jerr == json_tokener_continue); |
|||
|
|||
+ if (nreadTotal == 0) {
|
|||
+ ret = 0;
|
|||
+ goto cleanup;
|
|||
+ }
|
|||
+
|
|||
if (jerr == json_tokener_continue) { |
|||
ERROR("Cannot parse %s: incomplete json found", file); |
|||
goto cleanup; |
|||
} |
|||
|
|||
- if (nreadTotal > 0 && jerr != json_tokener_success) {
|
|||
+ if (jerr != json_tokener_success) {
|
|||
ERROR("Cannot parse %s: %s", file, json_tokener_error_desc(jerr)); |
|||
goto cleanup; |
|||
} |
|||
@ -1,68 +0,0 @@ |
|||
From cd0de70e05475d5f4aa46e578fbb98033d38c06b Mon Sep 17 00:00:00 2001 |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Mon, 16 Jun 2025 10:28:37 +0200 |
|||
Subject: [PATCH] qemu: Be more forgiving when acquiring QUERY job when |
|||
formatting domain XML |
|||
Content-type: text/plain |
|||
|
|||
In my previous commit of v11.0.0-rc1~115 I've made QEMU driver |
|||
implementation for virDomainGetXMLDesc() (qemuDomainGetXMLDesc()) |
|||
acquire QERY job. See its commit message for more info. But this |
|||
unfortunately broke apps witch fetch domain XML for incoming |
|||
migration (like virt-manager). The reason is that for incoming |
|||
migration the VIR_ASYNC_JOB_MIGRATION_IN async job is set, but |
|||
the mask of allowed synchronous jobs is empty (because QEMU can't |
|||
talk on monitor really). This makes virDomainObjBeginJob() fail |
|||
which in turn makes qemuDomainGetXMLDesc() fail too. |
|||
|
|||
It makes sense for qemuDomainGetXMLDesc() to acquire the job |
|||
(e.g. so that it's coherent with another thread that might be in |
|||
the middle of a MODIFY job). But failure to dump XML may be |
|||
treated as broken daemon (e.g. virt-manager does so). |
|||
|
|||
Therefore, still try to acquire the QUERY job (if job mask |
|||
permits it) but, do not treat failure as an error. |
|||
|
|||
Fixes: 6cc93bf28842526be2fd596a607ebca796b7fb2e |
|||
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2369243 |
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Pavel Hrdina <phrdina@redhat.com> |
|||
---
|
|||
src/qemu/qemu_driver.c | 10 +++++++--- |
|||
1 file changed, 7 insertions(+), 3 deletions(-) |
|||
|
|||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|||
index d2eddbd9ae..6bdeede2e8 100644
|
|||
--- a/src/qemu/qemu_driver.c
|
|||
+++ b/src/qemu/qemu_driver.c
|
|||
@@ -6158,6 +6158,7 @@ static char
|
|||
{ |
|||
virQEMUDriver *driver = dom->conn->privateData; |
|||
virDomainObj *vm; |
|||
+ bool hasJob = false;
|
|||
char *ret = NULL; |
|||
|
|||
virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS | VIR_DOMAIN_XML_UPDATE_CPU, |
|||
@@ -6169,8 +6170,10 @@ static char
|
|||
if (virDomainGetXMLDescEnsureACL(dom->conn, vm->def, flags) < 0) |
|||
goto cleanup; |
|||
|
|||
- if (virDomainObjBeginJob(vm, VIR_JOB_QUERY) < 0)
|
|||
- goto cleanup;
|
|||
+ if (virDomainNestedJobAllowed(vm->job, VIR_JOB_QUERY) &&
|
|||
+ virDomainObjBeginJob(vm, VIR_JOB_QUERY) >= 0) {
|
|||
+ hasJob = true;
|
|||
+ }
|
|||
|
|||
qemuDomainUpdateCurrentMemorySize(vm); |
|||
|
|||
@@ -6186,7 +6189,8 @@ static char
|
|||
|
|||
ret = qemuDomainFormatXML(driver, vm, flags); |
|||
|
|||
- virDomainObjEndJob(vm);
|
|||
+ if (hasJob)
|
|||
+ virDomainObjEndJob(vm);
|
|||
|
|||
cleanup: |
|||
virDomainObjEndAPI(&vm); |
|||
@ -1,94 +0,0 @@ |
|||
From 63e4cbd109374f44e8bd4f8d1af5e2a2c67611bc Mon Sep 17 00:00:00 2001 |
|||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com> |
|||
Date: Mon, 28 Apr 2025 11:42:13 +0100 |
|||
Subject: [PATCH] storage: stop hardcoding paths for mkfs, mount, umount |
|||
MIME-Version: 1.0 |
|||
Content-Type: text/plain; charset=UTF-8 |
|||
Content-Transfer-Encoding: 8bit |
|||
|
|||
From: Daniel P. Berrangé <berrange@redhat.com> |
|||
|
|||
This was always undesirable but now causes problems on Fedora 42 |
|||
where at build time we detect a /sbin path but at runtime this |
|||
will only exist on upgraded machines, not fresh installs. |
|||
|
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> |
|||
---
|
|||
meson.build | 13 ------------- |
|||
src/storage/storage_backend_fs.c | 17 +++-------------- |
|||
2 files changed, 3 insertions(+), 27 deletions(-) |
|||
|
|||
diff --git a/meson.build b/meson.build
|
|||
index 37b1caa566..14c98b49a1 100644
|
|||
--- a/meson.build
|
|||
+++ b/meson.build
|
|||
@@ -1827,23 +1827,10 @@ if conf.has('WITH_LIBVIRTD')
|
|||
endif |
|||
endif |
|||
|
|||
- if fs_enable
|
|||
- mount_prog = find_program('mount', required: get_option('storage_fs'), dirs: libvirt_sbin_path)
|
|||
- umount_prog = find_program('umount', required: get_option('storage_fs'), dirs: libvirt_sbin_path)
|
|||
- mkfs_prog = find_program('mkfs', required: get_option('storage_fs'), dirs: libvirt_sbin_path)
|
|||
-
|
|||
- if not mount_prog.found() or not umount_prog.found() or not mkfs_prog.found()
|
|||
- fs_enable = false
|
|||
- endif
|
|||
- endif
|
|||
-
|
|||
if fs_enable |
|||
use_storage = true |
|||
|
|||
conf.set('WITH_STORAGE_FS', 1) |
|||
- conf.set_quoted('MOUNT', mount_prog.full_path())
|
|||
- conf.set_quoted('UMOUNT', umount_prog.full_path())
|
|||
- conf.set_quoted('MKFS', mkfs_prog.full_path())
|
|||
endif |
|||
endif |
|||
|
|||
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
|
|||
index fce395d60f..6ec359625a 100644
|
|||
--- a/src/storage/storage_backend_fs.c
|
|||
+++ b/src/storage/storage_backend_fs.c
|
|||
@@ -304,7 +304,7 @@ virStorageBackendFileSystemMount(virStoragePoolObj *pool)
|
|||
if (!(src = virStorageBackendFileSystemGetPoolSource(pool))) |
|||
return -1; |
|||
|
|||
- cmd = virStorageBackendFileSystemMountCmd(MOUNT, def, src);
|
|||
+ cmd = virStorageBackendFileSystemMountCmd("mount", def, src);
|
|||
|
|||
/* Mounting a shared FS might take a long time. Don't hold |
|||
* the pool locked meanwhile. */ |
|||
@@ -362,7 +362,7 @@ virStorageBackendFileSystemStop(virStoragePoolObj *pool)
|
|||
if ((rc = virStorageBackendFileSystemIsMounted(pool)) != 1) |
|||
return rc; |
|||
|
|||
- cmd = virCommandNewArgList(UMOUNT, def->target.path, NULL);
|
|||
+ cmd = virCommandNewArgList("umount", def->target.path, NULL);
|
|||
return virCommandRun(cmd, NULL); |
|||
} |
|||
#endif /* WITH_STORAGE_FS */ |
|||
@@ -402,18 +402,7 @@ virStorageBackendExecuteMKFS(const char *device,
|
|||
g_autoptr(virCommand) cmd = NULL; |
|||
g_autofree char *mkfs = NULL; |
|||
|
|||
-#if WITH_STORAGE_FS
|
|||
- mkfs = virFindFileInPath(MKFS);
|
|||
-#endif /* WITH_STORAGE_FS */
|
|||
-
|
|||
- if (!mkfs) {
|
|||
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|||
- _("mkfs is not available on this platform: Failed to make filesystem of type '%1$s' on device '%2$s'"),
|
|||
- format, device);
|
|||
- return -1;
|
|||
- }
|
|||
-
|
|||
- cmd = virCommandNewArgList(mkfs, "-t", format, NULL);
|
|||
+ cmd = virCommandNewArgList("mkfs", "-t", format, NULL);
|
|||
|
|||
/* use the force, otherwise mkfs.xfs won't overwrite existing fs. |
|||
* Similarly mkfs.ext2, mkfs.ext3, and mkfs.ext4 require supplying -F |
|||
--
|
|||
2.49.0 |
|||
|
|||
@ -1,43 +0,0 @@ |
|||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com> |
|||
To: devel@lists.libvirt.org |
|||
Subject: [PATCH] util: avoid overflow in hextable buffer |
|||
Date: Mon, 20 Jan 2025 10:09:24 +0000 |
|||
Message-ID: <20250120100924.3864818-1-berrange@redhat.com> |
|||
MIME-Version: 1.0 |
|||
Content-Type: text/plain; charset=UTF-8 |
|||
Content-Transfer-Encoding: 8bit |
|||
|
|||
The assigned string is 17 chars long once the trailing nul is taken |
|||
into account. This triggers a warning with GCC 15 |
|||
|
|||
src/util/virsystemd.c: In function ‘virSystemdEscapeName’: |
|||
src/util/virsystemd.c:59:38: error: initializer-string for array of ‘char’ is too long [-Werror=unterminated-string-initialization] |
|||
59 | static const char hextable[16] = "0123456789abcdef"; |
|||
| ^~~~~~~~~~~~~~~~~~ |
|||
|
|||
Switch to a dynamically sized array as used in all the other places |
|||
we have a hextable array. |
|||
|
|||
See also: https://gcc.gnu.org/PR115185 |
|||
Reported-by: Yaakov Selkowitz <yselkowi@redhat.com> |
|||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> |
|||
---
|
|||
src/util/virsystemd.c | 2 +- |
|||
1 file changed, 1 insertion(+), 1 deletion(-) |
|||
|
|||
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
|
|||
index 5b772e29dd..d46e5f74fc 100644
|
|||
--- a/src/util/virsystemd.c
|
|||
+++ b/src/util/virsystemd.c
|
|||
@@ -56,7 +56,7 @@ struct _virSystemdActivationEntry {
|
|||
static void virSystemdEscapeName(virBuffer *buf, |
|||
const char *name) |
|||
{ |
|||
- static const char hextable[16] = "0123456789abcdef";
|
|||
+ static const char hextable[] = "0123456789abcdef";
|
|||
|
|||
#define ESCAPE(c) \ |
|||
do { \ |
|||
--
|
|||
2.47.1 |
|||
|
|||
@ -1,58 +0,0 @@ |
|||
From 7ab0f1c2a3fddf46d381f055e49111e3063b4829 Mon Sep 17 00:00:00 2001 |
|||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com> |
|||
Date: Mon, 28 Apr 2025 11:47:34 +0100 |
|||
Subject: [PATCH] util: stop hardcoding numad path |
|||
MIME-Version: 1.0 |
|||
Content-Type: text/plain; charset=UTF-8 |
|||
Content-Transfer-Encoding: 8bit |
|||
|
|||
From: Daniel P. Berrangé <berrange@redhat.com> |
|||
|
|||
Change the meson rules to always enable numad if on a Linux host, unless |
|||
the meson options say not to. |
|||
|
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> |
|||
---
|
|||
meson.build | 10 +++------- |
|||
src/util/virnuma.c | 2 +- |
|||
2 files changed, 4 insertions(+), 8 deletions(-) |
|||
|
|||
diff --git a/meson.build b/meson.build
|
|||
index 14c98b49a1..767205f44b 100644
|
|||
--- a/meson.build
|
|||
+++ b/meson.build
|
|||
@@ -2028,14 +2028,10 @@ if not get_option('nss').disabled()
|
|||
endif |
|||
endif |
|||
|
|||
-if not get_option('numad').disabled() and numactl_dep.found()
|
|||
- numad_prog = find_program('numad', required: get_option('numad'), dirs: libvirt_sbin_path)
|
|||
- if numad_prog.found()
|
|||
- conf.set('WITH_NUMAD', 1)
|
|||
- conf.set_quoted('NUMAD', numad_prog.full_path())
|
|||
- endif
|
|||
+if not get_option('numad').disabled() and numactl_dep.found() and host_machine.system() == 'linux'
|
|||
+ conf.set('WITH_NUMAD', 1)
|
|||
elif get_option('numad').enabled() |
|||
- error('You must have numactl enabled for numad support.')
|
|||
+ error('You must have a Linux host with numactl enabled for numad support.')
|
|||
endif |
|||
|
|||
# nwfilter should only be compiled for linux, and only if the |
|||
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
|
|||
index 9393c20875..67c51630c7 100644
|
|||
--- a/src/util/virnuma.c
|
|||
+++ b/src/util/virnuma.c
|
|||
@@ -61,7 +61,7 @@ virNumaGetAutoPlacementAdvice(unsigned short vcpus,
|
|||
g_autoptr(virCommand) cmd = NULL; |
|||
char *output = NULL; |
|||
|
|||
- cmd = virCommandNewArgList(NUMAD, "-w", NULL);
|
|||
+ cmd = virCommandNewArgList("numad", "-w", NULL);
|
|||
virCommandAddArgFormat(cmd, "%d:%llu", vcpus, |
|||
VIR_DIV_UP(balloon, 1024)); |
|||
|
|||
--
|
|||
2.49.0 |
|||
|
|||
@ -1,36 +0,0 @@ |
|||
From b825bb556bd3967bf5422c243b77bd4038e317e2 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Mon, 13 Oct 2025 10:34:51 +0200 |
|||
Subject: [PATCH 1/8] wireshark: Drop needless declaration of |
|||
proto_register_libvirt() and proto_reg_handoff_libvirt() |
|||
Content-type: text/plain |
|||
|
|||
Both proto_register_libvirt() and proto_reg_handoff_libvirt() are |
|||
declared in packet-libvirt.h which is included from plugin.c. |
|||
There's no need to provide another declaration in plugin.c. |
|||
|
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
Signed-off-by: Cole Robinson <crobinso@redhat.com> |
|||
---
|
|||
tools/wireshark/src/plugin.c | 3 --- |
|||
1 file changed, 3 deletions(-) |
|||
|
|||
diff --git a/tools/wireshark/src/plugin.c b/tools/wireshark/src/plugin.c
|
|||
index 9a83f2ca07..19b25e7b1a 100644
|
|||
--- a/tools/wireshark/src/plugin.c
|
|||
+++ b/tools/wireshark/src/plugin.c
|
|||
@@ -72,9 +72,6 @@ void plugin_register(void)
|
|||
|
|||
#else /* WIRESHARK_VERSION >= 2009000 */ |
|||
|
|||
-void proto_register_libvirt(void);
|
|||
-void proto_reg_handoff_libvirt(void);
|
|||
-
|
|||
WS_DLL_PUBLIC_DEF const gchar plugin_version[] = PLUGIN_VERSION; |
|||
WS_DLL_PUBLIC_DEF const int plugin_want_major = WIRESHARK_VERSION_MAJOR; |
|||
WS_DLL_PUBLIC_DEF const int plugin_want_minor = WIRESHARK_VERSION_MINOR; |
|||
--
|
|||
2.51.0 |
|||
|
|||
@ -1,47 +0,0 @@ |
|||
From 41d3b457972bde85991fa7ed6f282370aca4b2af Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <41d3b457972bde85991fa7ed6f282370aca4b2af.1760476767.git.crobinso@redhat.com> |
|||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Fri, 10 Oct 2025 15:20:05 +0200 |
|||
Subject: [PATCH 2/8] wireshark: Switch header files to #pragma once |
|||
Content-type: text/plain |
|||
|
|||
The genxdrstub.pl script generates some header files. But they |
|||
use the old pattern to guard against multiple inclusion: |
|||
|
|||
#ifndef SOMETHING_H |
|||
#define SOMETHING_H |
|||
... |
|||
#endif |
|||
|
|||
Change the script to generate just '#pragma once' used everywhere |
|||
else in our code. |
|||
|
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
Signed-off-by: Cole Robinson <crobinso@redhat.com> |
|||
---
|
|||
tools/wireshark/util/genxdrstub.pl | 5 +---- |
|||
1 file changed, 1 insertion(+), 4 deletions(-) |
|||
|
|||
diff --git a/tools/wireshark/util/genxdrstub.pl b/tools/wireshark/util/genxdrstub.pl
|
|||
index 8cfda25a27..01b663a88c 100755
|
|||
--- a/tools/wireshark/util/genxdrstub.pl
|
|||
+++ b/tools/wireshark/util/genxdrstub.pl
|
|||
@@ -563,11 +563,8 @@ sub add_header_file {
|
|||
local $self->{header_contents} = []; |
|||
$self->print("/* *DO NOT MODIFY* this file directly.\n"); |
|||
$self->print(" * This file was generated by $0 from libvirt version $libvirt_version */\n"); |
|||
- my $ucname = uc $name;
|
|||
- $self->print("#ifndef _$ucname\_H_\n");
|
|||
- $self->print("#define _$ucname\_H_\n");
|
|||
+ $self->print("#pragma once\n");
|
|||
$block->(); |
|||
- $self->print("#endif /* _$ucname\_H_ */");
|
|||
push @{ $self->{headers} }, [ $name, delete $self->{header_contents} ]; |
|||
} |
|||
|
|||
--
|
|||
2.51.0 |
|||
|
|||
@ -1,81 +0,0 @@ |
|||
From 02a0e78bf54c903da8922c56bade9b3298ade351 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <02a0e78bf54c903da8922c56bade9b3298ade351.1760476767.git.crobinso@redhat.com> |
|||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Mon, 13 Oct 2025 09:04:17 +0200 |
|||
Subject: [PATCH 3/8] wireshark: Move WIRESHARK_VERSION macro definition |
|||
Content-type: text/plain |
|||
|
|||
Soon, other parts of the wireshark code will need to |
|||
differentiate wrt wireshark version. Therefore, move the
|
|||
WIRESHARK_VERSION macro definition among with its deps into |
|||
packet-libvirt.h. |
|||
|
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
Signed-off-by: Cole Robinson <crobinso@redhat.com> |
|||
---
|
|||
tools/wireshark/src/packet-libvirt.h | 14 ++++++++++++++ |
|||
tools/wireshark/src/plugin.c | 14 -------------- |
|||
2 files changed, 14 insertions(+), 14 deletions(-) |
|||
|
|||
diff --git a/tools/wireshark/src/packet-libvirt.h b/tools/wireshark/src/packet-libvirt.h
|
|||
index 14e6e13696..15cfcb0534 100644
|
|||
--- a/tools/wireshark/src/packet-libvirt.h
|
|||
+++ b/tools/wireshark/src/packet-libvirt.h
|
|||
@@ -19,5 +19,19 @@
|
|||
|
|||
#pragma once |
|||
|
|||
+#ifdef WITH_WS_VERSION
|
|||
+# include <wireshark/ws_version.h>
|
|||
+#else
|
|||
+# include <wireshark/config.h>
|
|||
+# define WIRESHARK_VERSION_MAJOR VERSION_MAJOR
|
|||
+# define WIRESHARK_VERSION_MINOR VERSION_MINOR
|
|||
+# define WIRESHARK_VERSION_MICRO VERSION_MICRO
|
|||
+#endif
|
|||
+
|
|||
+#define WIRESHARK_VERSION \
|
|||
+ ((WIRESHARK_VERSION_MAJOR * 1000 * 1000) + \
|
|||
+ (WIRESHARK_VERSION_MINOR * 1000) + \
|
|||
+ (WIRESHARK_VERSION_MICRO))
|
|||
+
|
|||
void proto_register_libvirt(void); |
|||
void proto_reg_handoff_libvirt(void); |
|||
diff --git a/tools/wireshark/src/plugin.c b/tools/wireshark/src/plugin.c
|
|||
index 19b25e7b1a..64317b5280 100644
|
|||
--- a/tools/wireshark/src/plugin.c
|
|||
+++ b/tools/wireshark/src/plugin.c
|
|||
@@ -12,15 +12,6 @@
|
|||
|
|||
#include <config.h> |
|||
|
|||
-#ifdef WITH_WS_VERSION
|
|||
-# include <wireshark/ws_version.h>
|
|||
-#else
|
|||
-# include <wireshark/config.h>
|
|||
-# define WIRESHARK_VERSION_MAJOR VERSION_MAJOR
|
|||
-# define WIRESHARK_VERSION_MINOR VERSION_MINOR
|
|||
-# define WIRESHARK_VERSION_MICRO VERSION_MICRO
|
|||
-#endif
|
|||
-
|
|||
#define HAVE_PLUGINS 1 |
|||
#include <wireshark/epan/proto.h> |
|||
/* plugins are DLLs */ |
|||
@@ -32,11 +23,6 @@
|
|||
/* Let the plugin version be the version of libvirt */ |
|||
#define PLUGIN_VERSION VERSION |
|||
|
|||
-#define WIRESHARK_VERSION \
|
|||
- ((WIRESHARK_VERSION_MAJOR * 1000 * 1000) + \
|
|||
- (WIRESHARK_VERSION_MINOR * 1000) + \
|
|||
- (WIRESHARK_VERSION_MICRO))
|
|||
-
|
|||
#if WIRESHARK_VERSION < 2005000 |
|||
|
|||
WS_DLL_PUBLIC_DEF const gchar version[] = VERSION; |
|||
--
|
|||
2.51.0 |
|||
|
|||
@ -1,133 +0,0 @@ |
|||
From 7374c4ecbd591b02f7be4b2918addc6d5852aafb Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <7374c4ecbd591b02f7be4b2918addc6d5852aafb.1760476767.git.crobinso@redhat.com> |
|||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Mon, 13 Oct 2025 09:21:30 +0200 |
|||
Subject: [PATCH 4/8] wireshark: Fix int type of some virNetMessageHeader |
|||
members |
|||
Content-type: text/plain |
|||
|
|||
Our virNetMessageHeader is a struct that's declared as follows: |
|||
|
|||
struct virNetMessageHeader { |
|||
unsigned prog; |
|||
unsigned vers; |
|||
int proc; |
|||
virNetMessageType type; |
|||
unsigned serial; |
|||
virNetMessageStatus status; |
|||
}; |
|||
|
|||
Now, per RFC 4506 enums are also encoded as signed integers. This |
|||
means, that only 'prog', 'vers' and 'serial' are really unsigned |
|||
integers. The others ('proc', 'type' and 'status') are encoded as |
|||
signed integers. Fix their type when dissecting. |
|||
|
|||
While at it, also follow latest trend in wireshark and switch |
|||
from guint32 to uint32_t. |
|||
|
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
Signed-off-by: Cole Robinson <crobinso@redhat.com> |
|||
---
|
|||
tools/wireshark/src/packet-libvirt.c | 34 +++++++++++++++++++--------- |
|||
1 file changed, 23 insertions(+), 11 deletions(-) |
|||
|
|||
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
|
|||
index da2aabd98a..af14c6bed7 100644
|
|||
--- a/tools/wireshark/src/packet-libvirt.c
|
|||
+++ b/tools/wireshark/src/packet-libvirt.c
|
|||
@@ -92,7 +92,7 @@ typedef gboolean (*vir_xdr_dissector_t)(tvbuff_t *tvb, proto_tree *tree, XDR *xd
|
|||
|
|||
typedef struct vir_dissector_index vir_dissector_index_t; |
|||
struct vir_dissector_index { |
|||
- guint32 proc;
|
|||
+ int32_t proc;
|
|||
vir_xdr_dissector_t args; |
|||
vir_xdr_dissector_t ret; |
|||
vir_xdr_dissector_t msg; |
|||
@@ -275,8 +275,10 @@ dissect_xdr_array(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
|
|||
} |
|||
|
|||
static vir_xdr_dissector_t |
|||
-find_payload_dissector(guint32 proc, guint32 type,
|
|||
- const vir_dissector_index_t *pds, gsize length)
|
|||
+find_payload_dissector(int32_t proc,
|
|||
+ enum vir_net_message_type type,
|
|||
+ const vir_dissector_index_t *pds,
|
|||
+ gsize length)
|
|||
{ |
|||
const vir_dissector_index_t *pd; |
|||
guint32 first, last, direction; |
|||
@@ -309,6 +311,10 @@ find_payload_dissector(guint32 proc, guint32 type,
|
|||
return pd->ret; |
|||
case VIR_NET_MESSAGE: |
|||
return pd->msg; |
|||
+ case VIR_NET_STREAM:
|
|||
+ case VIR_NET_STREAM_HOLE:
|
|||
+ /* Handled elsewhere */
|
|||
+ return NULL;
|
|||
} |
|||
return NULL; |
|||
} |
|||
@@ -397,8 +403,12 @@ dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
|||
#include "libvirt/protocol.h" |
|||
|
|||
static void |
|||
-dissect_libvirt_payload(tvbuff_t *tvb, proto_tree *tree,
|
|||
- guint32 prog, guint32 proc, guint32 type, guint32 status)
|
|||
+dissect_libvirt_payload(tvbuff_t *tvb,
|
|||
+ proto_tree *tree,
|
|||
+ uint32_t prog,
|
|||
+ int32_t proc,
|
|||
+ int32_t type,
|
|||
+ int32_t status)
|
|||
{ |
|||
gssize payload_length; |
|||
|
|||
@@ -430,7 +440,8 @@ dissect_libvirt_payload(tvbuff_t *tvb, proto_tree *tree,
|
|||
return; |
|||
|
|||
unknown: |
|||
- dbg("Cannot determine payload: Prog=%u, Proc=%u, Type=%u, Status=%u", prog, proc, type, status);
|
|||
+ dbg("Cannot determine payload: Prog=%u, Proc=%d, Type=%d, Status=%d",
|
|||
+ prog, proc, type, status);
|
|||
proto_tree_add_item(tree, hf_libvirt_unknown, tvb, VIR_HEADER_LEN, -1, ENC_NA); |
|||
} |
|||
|
|||
@@ -439,7 +450,8 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
void *opaque G_GNUC_UNUSED) |
|||
{ |
|||
goffset offset; |
|||
- guint32 prog, proc, type, serial, status;
|
|||
+ uint32_t prog, serial;
|
|||
+ int32_t proc, type, status;
|
|||
const value_string *vs; |
|||
|
|||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Libvirt"); |
|||
@@ -448,17 +460,17 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
offset = 4; /* End of length field */ |
|||
prog = tvb_get_ntohl(tvb, offset); offset += 4; |
|||
offset += 4; /* Ignore version header field */ |
|||
- proc = tvb_get_ntohl(tvb, offset); offset += 4;
|
|||
- type = tvb_get_ntohl(tvb, offset); offset += 4;
|
|||
+ proc = tvb_get_ntohil(tvb, offset); offset += 4;
|
|||
+ type = tvb_get_ntohil(tvb, offset); offset += 4;
|
|||
serial = tvb_get_ntohl(tvb, offset); offset += 4; |
|||
- status = tvb_get_ntohl(tvb, offset); offset += 4;
|
|||
+ status = tvb_get_ntohil(tvb, offset); offset += 4;
|
|||
|
|||
col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s", |
|||
val_to_str(prog, program_strings, "%x")); |
|||
|
|||
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS); |
|||
if (vs == NULL) { |
|||
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%u", proc);
|
|||
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%d", proc);
|
|||
} else { |
|||
col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d")); |
|||
} |
|||
--
|
|||
2.51.0 |
|||
|
|||
@ -1,46 +0,0 @@ |
|||
From 1086888f95a322101f8cf53b63c96600ccbeb882 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <1086888f95a322101f8cf53b63c96600ccbeb882.1760476767.git.crobinso@redhat.com> |
|||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Fri, 10 Oct 2025 19:16:54 +0200 |
|||
Subject: [PATCH 5/8] wireshark: Don't special case retval of |
|||
get_program_data() in dissect_libvirt_message() |
|||
Content-type: text/plain |
|||
|
|||
The get_program_data() function returns a pointer (in this |
|||
specific case to an array of procedure strings) which, if |
|||
non-NULL is then passed val_to_str(). Well, if val_to_str() sees |
|||
NULL it is treated gracefully, i.e. like if the numeric value |
|||
'proc' wasn't found in the array. |
|||
|
|||
Therefore, there's no need to special case call to |
|||
col_append_fstr(). Both result into the same behaviour. |
|||
|
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
Signed-off-by: Cole Robinson <crobinso@redhat.com> |
|||
---
|
|||
tools/wireshark/src/packet-libvirt.c | 6 +----- |
|||
1 file changed, 1 insertion(+), 5 deletions(-) |
|||
|
|||
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
|
|||
index af14c6bed7..6c729801d4 100644
|
|||
--- a/tools/wireshark/src/packet-libvirt.c
|
|||
+++ b/tools/wireshark/src/packet-libvirt.c
|
|||
@@ -469,11 +469,7 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
val_to_str(prog, program_strings, "%x")); |
|||
|
|||
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS); |
|||
- if (vs == NULL) {
|
|||
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%d", proc);
|
|||
- } else {
|
|||
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
|
|||
- }
|
|||
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
|
|||
|
|||
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s", |
|||
val_to_str(type, type_strings, "%d"), serial, |
|||
--
|
|||
2.51.0 |
|||
|
|||
@ -1,68 +0,0 @@ |
|||
From ba2c4bdd5cbccd5c0673149cf76802c98b70d2f7 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <ba2c4bdd5cbccd5c0673149cf76802c98b70d2f7.1760476767.git.crobinso@redhat.com> |
|||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Fri, 10 Oct 2025 18:23:18 +0200 |
|||
Subject: [PATCH 6/8] wireshark: Introduce and use vir_val_to_str() |
|||
Content-type: text/plain |
|||
|
|||
Wireshark offers val_to_str() function which converts numeric |
|||
value to string by looking up value ('val') in an array ('vs') of |
|||
<val, string> pairs. If no corresponding string is found, then |
|||
the value is formatted using given 'fmt' string. |
|||
|
|||
Starting from wireshark-4.6.0 not only this function gained |
|||
another argument but also returns a strdup()-ed string. To keep |
|||
our code simple, let's introduce a wrapper so which can be then |
|||
adjusted as needed. |
|||
|
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
Signed-off-by: Cole Robinson <crobinso@redhat.com> |
|||
---
|
|||
tools/wireshark/src/packet-libvirt.c | 17 +++++++++++++---- |
|||
1 file changed, 13 insertions(+), 4 deletions(-) |
|||
|
|||
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
|
|||
index 6c729801d4..f6ad2c4578 100644
|
|||
--- a/tools/wireshark/src/packet-libvirt.c
|
|||
+++ b/tools/wireshark/src/packet-libvirt.c
|
|||
@@ -140,6 +140,15 @@ static const value_string status_strings[] = {
|
|||
{ -1, NULL } |
|||
}; |
|||
|
|||
+static const char *
|
|||
+G_GNUC_PRINTF(3, 0)
|
|||
+vir_val_to_str(const uint32_t val,
|
|||
+ const value_string *vs,
|
|||
+ const char *fmt)
|
|||
+{
|
|||
+ return val_to_str(val, vs, fmt);
|
|||
+}
|
|||
+
|
|||
static gboolean |
|||
dissect_xdr_string(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, |
|||
guint32 maxlen) |
|||
@@ -466,14 +475,14 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
status = tvb_get_ntohil(tvb, offset); offset += 4; |
|||
|
|||
col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s", |
|||
- val_to_str(prog, program_strings, "%x"));
|
|||
+ vir_val_to_str(prog, program_strings, "%x"));
|
|||
|
|||
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS); |
|||
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
|
|||
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", vir_val_to_str(proc, vs, "%d"));
|
|||
|
|||
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s", |
|||
- val_to_str(type, type_strings, "%d"), serial,
|
|||
- val_to_str(status, status_strings, "%d"));
|
|||
+ vir_val_to_str(type, type_strings, "%d"), serial,
|
|||
+ vir_val_to_str(status, status_strings, "%d"));
|
|||
|
|||
if (tree) { |
|||
gint *hf_proc; |
|||
--
|
|||
2.51.0 |
|||
|
|||
@ -1,165 +0,0 @@ |
|||
From 002b9f559d69b92e77ab2d234df6966fecdaf0ec Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <002b9f559d69b92e77ab2d234df6966fecdaf0ec.1760476767.git.crobinso@redhat.com> |
|||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Fri, 10 Oct 2025 19:13:48 +0200 |
|||
Subject: [PATCH 7/8] wireshark: Don't leak column strings |
|||
Content-type: text/plain |
|||
|
|||
One of the problems of using val_to_str() is that it may return a |
|||
const string from given table ('vs'), OR return an allocated one. |
|||
Since the caller has no idea which case it is, it resides to safe |
|||
option and don't free returned string. But that might lead to a |
|||
memleak. This behaviour is fixed with wireshark-4.6.0 and support |
|||
for it will be introduced soon. But first, make vir_val_to_str() |
|||
behave like fixed val_to_str() from newer wireshark: just always |
|||
allocate the string. |
|||
|
|||
Now, if val_to_str() needs to allocate new memory it obtains |
|||
allocator by calling wmem_packet_scope() which is what we may do |
|||
too. |
|||
|
|||
Hand in hand with that, we need to free the memory using the |
|||
correct allocator, hence wmem_free(). But let's put it into a |
|||
wrapper vir_wmem_free() because just like val_to_str(), it'll |
|||
need additional argument when adapting to new wireshark. |
|||
|
|||
Oh, and freeing the memory right after col_add_fstr() is safe as |
|||
it uses vsnprintf() under the hood to format passed args. |
|||
|
|||
One last thing, the wmem.h file used to live under epan/wmem/ but |
|||
then in v3.5.0~240 [1] was moved to wsutil/wmem/. |
|||
|
|||
1: https://gitlab.com/wireshark/wireshark/-/commit/7f9c1f5f92c131354fc8b2b88d473706786064c0 |
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
Signed-off-by: Cole Robinson <crobinso@redhat.com> |
|||
---
|
|||
meson.build | 20 ++++++++++++++++ |
|||
tools/wireshark/src/meson.build | 1 + |
|||
tools/wireshark/src/packet-libvirt.c | 35 ++++++++++++++++++++++------ |
|||
3 files changed, 49 insertions(+), 7 deletions(-) |
|||
|
|||
diff --git a/meson.build b/meson.build
|
|||
index bcc18b20e5..a1e0e5ecd5 100644
|
|||
--- a/meson.build
|
|||
+++ b/meson.build
|
|||
@@ -1365,6 +1365,26 @@ if wireshark_dep.found()
|
|||
if cc.check_header('wireshark/ws_version.h') |
|||
conf.set('WITH_WS_VERSION', 1) |
|||
endif |
|||
+
|
|||
+ # Find wmem.h
|
|||
+ # But it's not as easy as you'd think. Ubuntu 20.04 has split parts of
|
|||
+ # libwireshark.so into libwsutil.so but:
|
|||
+ # a) wireshark.pc never mentions it,
|
|||
+ # b) libwsutil-dev package doesn't install pkg-config file.
|
|||
+ # Fortunately, it's fixed in 24.04.
|
|||
+ if cc.check_header('wireshark/epan/wmem/wmem.h', dependencies: wireshark_dep)
|
|||
+ conf.set('WITH_WS_EPAN_WMEM', 1)
|
|||
+ elif cc.check_header('wireshark/wsutil/wmem/wmem.h', dependencies: wireshark_dep)
|
|||
+ conf.set('WITH_WS_WSUTIL_WMEM', 1)
|
|||
+ else
|
|||
+ error('Unable to locate wmem.h file')
|
|||
+ endif
|
|||
+
|
|||
+ # TODO: drop wsutil dep once support for Ubuntu 20.04 is dropped
|
|||
+ wsutil_dep = dependency('', required: false)
|
|||
+ if not cc.has_function('wmem_free', dependencies: wireshark_dep)
|
|||
+ wsutil_dep = cc.find_library('wsutil', required: true)
|
|||
+ endif
|
|||
endif |
|||
|
|||
# generic build dependencies checks |
|||
diff --git a/tools/wireshark/src/meson.build b/tools/wireshark/src/meson.build
|
|||
index 9b452dc5ca..ba0df913e0 100644
|
|||
--- a/tools/wireshark/src/meson.build
|
|||
+++ b/tools/wireshark/src/meson.build
|
|||
@@ -9,6 +9,7 @@ shared_library(
|
|||
], |
|||
dependencies: [ |
|||
wireshark_dep, |
|||
+ wsutil_dep,
|
|||
xdr_dep, |
|||
tools_dep, |
|||
], |
|||
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
|
|||
index f6ad2c4578..3178ac6f27 100644
|
|||
--- a/tools/wireshark/src/packet-libvirt.c
|
|||
+++ b/tools/wireshark/src/packet-libvirt.c
|
|||
@@ -21,6 +21,11 @@
|
|||
#include <wireshark/epan/proto.h> |
|||
#include <wireshark/epan/packet.h> |
|||
#include <wireshark/epan/dissectors/packet-tcp.h> |
|||
+#ifdef WITH_WS_EPAN_WMEM
|
|||
+# include <wireshark/epan/wmem/wmem.h>
|
|||
+#elif WITH_WS_WSUTIL_WMEM
|
|||
+# include <wireshark/wsutil/wmem/wmem.h>
|
|||
+#endif
|
|||
#include <rpc/types.h> |
|||
#include <rpc/xdr.h> |
|||
#include "packet-libvirt.h" |
|||
@@ -140,13 +145,19 @@ static const value_string status_strings[] = {
|
|||
{ -1, NULL } |
|||
}; |
|||
|
|||
-static const char *
|
|||
+static char *
|
|||
G_GNUC_PRINTF(3, 0) |
|||
vir_val_to_str(const uint32_t val, |
|||
const value_string *vs, |
|||
const char *fmt) |
|||
{ |
|||
- return val_to_str(val, vs, fmt);
|
|||
+ return val_to_str_wmem(wmem_packet_scope(), val, vs, fmt);
|
|||
+}
|
|||
+
|
|||
+static void
|
|||
+vir_wmem_free(void *ptr)
|
|||
+{
|
|||
+ wmem_free(wmem_packet_scope(), ptr);
|
|||
} |
|||
|
|||
static gboolean |
|||
@@ -462,6 +473,10 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
uint32_t prog, serial; |
|||
int32_t proc, type, status; |
|||
const value_string *vs; |
|||
+ char *prog_str = NULL;
|
|||
+ char *proc_str = NULL;
|
|||
+ char *type_str = NULL;
|
|||
+ char *status_str = NULL;
|
|||
|
|||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Libvirt"); |
|||
col_clear(pinfo->cinfo, COL_INFO); |
|||
@@ -474,15 +489,21 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
serial = tvb_get_ntohl(tvb, offset); offset += 4; |
|||
status = tvb_get_ntohil(tvb, offset); offset += 4; |
|||
|
|||
- col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s",
|
|||
- vir_val_to_str(prog, program_strings, "%x"));
|
|||
+ prog_str = vir_val_to_str(prog, program_strings, "%x");
|
|||
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s", prog_str);
|
|||
+ vir_wmem_free(prog_str);
|
|||
|
|||
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS); |
|||
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", vir_val_to_str(proc, vs, "%d"));
|
|||
+ proc_str = vir_val_to_str(proc, vs, "%d");
|
|||
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", proc_str);
|
|||
+ vir_wmem_free(proc_str);
|
|||
|
|||
+ type_str = vir_val_to_str(type, type_strings, "%d");
|
|||
+ status_str = vir_val_to_str(status, status_strings, "%d");
|
|||
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s", |
|||
- vir_val_to_str(type, type_strings, "%d"), serial,
|
|||
- vir_val_to_str(status, status_strings, "%d"));
|
|||
+ type_str, serial, status_str);
|
|||
+ vir_wmem_free(status_str);
|
|||
+ vir_wmem_free(type_str);
|
|||
|
|||
if (tree) { |
|||
gint *hf_proc; |
|||
--
|
|||
2.51.0 |
|||
|
|||
@ -1,493 +0,0 @@ |
|||
From b42a12174c787b99cd6fcb29b44e4b13bd64ee58 Mon Sep 17 00:00:00 2001 |
|||
Message-ID: <b42a12174c787b99cd6fcb29b44e4b13bd64ee58.1760476767.git.crobinso@redhat.com> |
|||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com> |
|||
From: Michal Privoznik <mprivozn@redhat.com> |
|||
Date: Fri, 10 Oct 2025 15:22:34 +0200 |
|||
Subject: [PATCH 8/8] wireshark: Adapt to wireshark-4.6.0 |
|||
Content-type: text/plain |
|||
|
|||
The main difference is that wmem_packet_scope() is gone [1] but |
|||
the packet_info struct has 'pool` member which points to the |
|||
allocator used for given packet. |
|||
|
|||
Unfortunately, while we were given pointer to packet_info at the |
|||
entry level to our dissector (dissect_libvirt() -> |
|||
tcp_dissect_pdus() -> dissect_libvirt_message()) it was never |
|||
propagated to generated/primitive dissectors. |
|||
|
|||
But not all dissectors need to allocate memory, so mark the new |
|||
argument as unused. And while our generator could be rewritten so |
|||
that the argument is annotated as unused iff it's really unused, |
|||
I couldn't bother rewriting it. It's generated code after all. |
|||
Too much work for little gain. |
|||
|
|||
Another significant change is that val_to_str() now requires new |
|||
argument: pointer to allocator to use because it always allocates |
|||
new memory [2][3]. |
|||
|
|||
1: https://gitlab.com/wireshark/wireshark/-/commit/5ca5c9ca372e06881b23ba9f4fdcb6b479886444 |
|||
2: https://gitlab.com/wireshark/wireshark/-/commit/b63599762468e4cf1783419a5556377604d344bb |
|||
3: https://gitlab.com/wireshark/wireshark/-/commit/84799be215313e61b83a3eaf074f89d6ee349b8c |
|||
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/823 |
|||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> |
|||
Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
|||
Signed-off-by: Cole Robinson <crobinso@redhat.com> |
|||
---
|
|||
tools/wireshark/src/packet-libvirt.c | 157 +++++++++++++++++++-------- |
|||
tools/wireshark/util/genxdrstub.pl | 18 +-- |
|||
2 files changed, 119 insertions(+), 56 deletions(-) |
|||
|
|||
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
|
|||
index 3178ac6f27..c5c8fb4756 100644
|
|||
--- a/tools/wireshark/src/packet-libvirt.c
|
|||
+++ b/tools/wireshark/src/packet-libvirt.c
|
|||
@@ -63,7 +63,7 @@ static gint ett_libvirt_stream_hole = -1;
|
|||
|
|||
#define XDR_PRIMITIVE_DISSECTOR(xtype, ctype, ftype) \ |
|||
static gboolean \ |
|||
- dissect_xdr_##xtype(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf) \
|
|||
+ dissect_xdr_##xtype(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf) \
|
|||
{ \ |
|||
goffset start; \ |
|||
ctype val; \ |
|||
@@ -93,7 +93,7 @@ XDR_PRIMITIVE_DISSECTOR(bool, bool_t, boolean)
|
|||
|
|||
VIR_WARNINGS_RESET |
|||
|
|||
-typedef gboolean (*vir_xdr_dissector_t)(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf);
|
|||
+typedef gboolean (*vir_xdr_dissector_t)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, XDR *xdrs, int hf);
|
|||
|
|||
typedef struct vir_dissector_index vir_dissector_index_t; |
|||
struct vir_dissector_index { |
|||
@@ -146,22 +146,32 @@ static const value_string status_strings[] = {
|
|||
}; |
|||
|
|||
static char * |
|||
-G_GNUC_PRINTF(3, 0)
|
|||
-vir_val_to_str(const uint32_t val,
|
|||
+G_GNUC_PRINTF(4, 0)
|
|||
+vir_val_to_str(packet_info *pinfo,
|
|||
+ const uint32_t val,
|
|||
const value_string *vs, |
|||
const char *fmt) |
|||
{ |
|||
- return val_to_str_wmem(wmem_packet_scope(), val, vs, fmt);
|
|||
+#if WIRESHARK_VERSION < 4006000
|
|||
+ return val_to_str_wmem(pinfo->pool, val, vs, fmt);
|
|||
+#else
|
|||
+ return val_to_str(pinfo->pool, val, vs, fmt);
|
|||
+#endif
|
|||
} |
|||
|
|||
static void |
|||
-vir_wmem_free(void *ptr)
|
|||
+vir_wmem_free(packet_info *pinfo,
|
|||
+ void *ptr)
|
|||
{ |
|||
- wmem_free(wmem_packet_scope(), ptr);
|
|||
+ wmem_free(pinfo->pool, ptr);
|
|||
} |
|||
|
|||
static gboolean |
|||
-dissect_xdr_string(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
+dissect_xdr_string(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo G_GNUC_UNUSED,
|
|||
+ proto_tree *tree,
|
|||
+ XDR *xdrs,
|
|||
+ int hf,
|
|||
guint32 maxlen) |
|||
{ |
|||
goffset start; |
|||
@@ -179,7 +189,11 @@ dissect_xdr_string(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
} |
|||
|
|||
static gboolean |
|||
-dissect_xdr_opaque(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
+dissect_xdr_opaque(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo,
|
|||
+ proto_tree *tree,
|
|||
+ XDR *xdrs,
|
|||
+ int hf,
|
|||
guint32 size) |
|||
{ |
|||
goffset start; |
|||
@@ -190,7 +204,7 @@ dissect_xdr_opaque(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
start = xdr_getpos(xdrs); |
|||
if ((rc = xdr_opaque(xdrs, (caddr_t)val, size))) { |
|||
gint len = xdr_getpos(xdrs) - start; |
|||
- const char *s = tvb_bytes_to_str(wmem_packet_scope(), tvb, start, len);
|
|||
+ const char *s = tvb_bytes_to_str(pinfo->pool, tvb, start, len);
|
|||
|
|||
proto_tree_add_bytes_format_value(tree, hf, tvb, start, len, NULL, "%s", s); |
|||
} else { |
|||
@@ -202,7 +216,11 @@ dissect_xdr_opaque(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
} |
|||
|
|||
static gboolean |
|||
-dissect_xdr_bytes(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
+dissect_xdr_bytes(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo,
|
|||
+ proto_tree *tree,
|
|||
+ XDR *xdrs,
|
|||
+ int hf,
|
|||
guint32 maxlen) |
|||
{ |
|||
goffset start; |
|||
@@ -212,7 +230,7 @@ dissect_xdr_bytes(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
start = xdr_getpos(xdrs); |
|||
if (xdr_bytes(xdrs, (char **)&val, &length, maxlen)) { |
|||
gint len = xdr_getpos(xdrs) - start; |
|||
- const char *s = tvb_bytes_to_str(wmem_packet_scope(), tvb, start, len);
|
|||
+ const char *s = tvb_bytes_to_str(pinfo->pool, tvb, start, len);
|
|||
|
|||
proto_tree_add_bytes_format_value(tree, hf, tvb, start, len, NULL, "%s", s); |
|||
free(val); |
|||
@@ -224,7 +242,11 @@ dissect_xdr_bytes(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
} |
|||
|
|||
static gboolean |
|||
-dissect_xdr_pointer(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
+dissect_xdr_pointer(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo,
|
|||
+ proto_tree *tree,
|
|||
+ XDR *xdrs,
|
|||
+ int hf,
|
|||
vir_xdr_dissector_t dissect) |
|||
{ |
|||
goffset start; |
|||
@@ -236,7 +258,7 @@ dissect_xdr_pointer(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
return FALSE; |
|||
} |
|||
if (not_null) { |
|||
- return dissect(tvb, tree, xdrs, hf);
|
|||
+ return dissect(tvb, pinfo, tree, xdrs, hf);
|
|||
} else { |
|||
proto_item *ti; |
|||
ti = proto_tree_add_item(tree, hf, tvb, start, xdr_getpos(xdrs) - start, ENC_NA); |
|||
@@ -246,15 +268,22 @@ dissect_xdr_pointer(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
|||
} |
|||
|
|||
static gboolean |
|||
-dissect_xdr_iterable(tvbuff_t *tvb, proto_item *ti, XDR *xdrs, gint ett, int rhf,
|
|||
- guint32 length, vir_xdr_dissector_t dissect, goffset start)
|
|||
+dissect_xdr_iterable(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo,
|
|||
+ proto_item *ti,
|
|||
+ XDR *xdrs,
|
|||
+ gint ett,
|
|||
+ int rhf,
|
|||
+ guint32 length,
|
|||
+ vir_xdr_dissector_t dissect,
|
|||
+ goffset start)
|
|||
{ |
|||
proto_tree *tree; |
|||
guint32 i; |
|||
|
|||
tree = proto_item_add_subtree(ti, ett); |
|||
for (i = 0; i < length; i++) { |
|||
- if (!dissect(tvb, tree, xdrs, rhf))
|
|||
+ if (!dissect(tvb, pinfo, tree, xdrs, rhf))
|
|||
return FALSE; |
|||
} |
|||
proto_item_set_len(ti, xdr_getpos(xdrs) - start); |
|||
@@ -262,8 +291,16 @@ dissect_xdr_iterable(tvbuff_t *tvb, proto_item *ti, XDR *xdrs, gint ett, int rhf
|
|||
} |
|||
|
|||
static gboolean |
|||
-dissect_xdr_vector(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
|
|||
- int rhf, const gchar *rtype, guint32 size, vir_xdr_dissector_t dissect)
|
|||
+dissect_xdr_vector(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo,
|
|||
+ proto_tree *tree,
|
|||
+ XDR *xdrs,
|
|||
+ int hf,
|
|||
+ gint ett,
|
|||
+ int rhf,
|
|||
+ const gchar *rtype,
|
|||
+ guint32 size,
|
|||
+ vir_xdr_dissector_t dissect)
|
|||
{ |
|||
goffset start; |
|||
proto_item *ti; |
|||
@@ -271,12 +308,20 @@ dissect_xdr_vector(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
|
|||
start = xdr_getpos(xdrs); |
|||
ti = proto_tree_add_item(tree, hf, tvb, start, -1, ENC_NA); |
|||
proto_item_append_text(ti, " :: %s[%u]", rtype, size); |
|||
- return dissect_xdr_iterable(tvb, ti, xdrs, ett, rhf, size, dissect, start);
|
|||
+ return dissect_xdr_iterable(tvb, pinfo, ti, xdrs, ett, rhf, size, dissect, start);
|
|||
} |
|||
|
|||
static gboolean |
|||
-dissect_xdr_array(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
|
|||
- int rhf, const gchar *rtype, guint32 maxlen, vir_xdr_dissector_t dissect)
|
|||
+dissect_xdr_array(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo,
|
|||
+ proto_tree *tree,
|
|||
+ XDR *xdrs,
|
|||
+ int hf,
|
|||
+ gint ett,
|
|||
+ int rhf,
|
|||
+ const gchar *rtype,
|
|||
+ guint32 maxlen,
|
|||
+ vir_xdr_dissector_t dissect)
|
|||
{ |
|||
goffset start; |
|||
proto_item *ti; |
|||
@@ -291,7 +336,7 @@ dissect_xdr_array(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
|
|||
|
|||
ti = proto_tree_add_item(tree, hf, tvb, start, -1, ENC_NA); |
|||
proto_item_append_text(ti, " :: %s<%u>", rtype, length); |
|||
- return dissect_xdr_iterable(tvb, ti, xdrs, ett, rhf, length, dissect, start);
|
|||
+ return dissect_xdr_iterable(tvb, pinfo, ti, xdrs, ett, rhf, length, dissect, start);
|
|||
} |
|||
|
|||
static vir_xdr_dissector_t |
|||
@@ -340,7 +385,10 @@ find_payload_dissector(int32_t proc,
|
|||
} |
|||
|
|||
static void |
|||
-dissect_libvirt_stream(tvbuff_t *tvb, proto_tree *tree, gint payload_length)
|
|||
+dissect_libvirt_stream(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo G_GNUC_UNUSED,
|
|||
+ proto_tree *tree,
|
|||
+ gint payload_length)
|
|||
{ |
|||
proto_tree_add_item(tree, hf_libvirt_stream, tvb, VIR_HEADER_LEN, |
|||
payload_length - VIR_HEADER_LEN, ENC_NA); |
|||
@@ -357,6 +405,7 @@ dissect_libvirt_num_of_fds(tvbuff_t *tvb, proto_tree *tree)
|
|||
|
|||
static void |
|||
dissect_libvirt_fds(tvbuff_t *tvb G_GNUC_UNUSED, |
|||
+ packet_info *pinfo G_GNUC_UNUSED,
|
|||
gint start G_GNUC_UNUSED, |
|||
gint32 nfds G_GNUC_UNUSED) |
|||
{ |
|||
@@ -364,8 +413,12 @@ dissect_libvirt_fds(tvbuff_t *tvb G_GNUC_UNUSED,
|
|||
} |
|||
|
|||
static void |
|||
-dissect_libvirt_payload_xdr_data(tvbuff_t *tvb, proto_tree *tree, gint payload_length,
|
|||
- gint32 status, vir_xdr_dissector_t dissect)
|
|||
+dissect_libvirt_payload_xdr_data(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo,
|
|||
+ proto_tree *tree,
|
|||
+ gint payload_length,
|
|||
+ gint32 status,
|
|||
+ vir_xdr_dissector_t dissect)
|
|||
{ |
|||
gint32 nfds = 0; |
|||
gint start = VIR_HEADER_LEN; |
|||
@@ -384,17 +437,21 @@ dissect_libvirt_payload_xdr_data(tvbuff_t *tvb, proto_tree *tree, gint payload_l
|
|||
payload_data = (caddr_t)tvb_memdup(NULL, payload_tvb, 0, payload_length); |
|||
xdrmem_create(&xdrs, payload_data, payload_length, XDR_DECODE); |
|||
|
|||
- dissect(payload_tvb, tree, &xdrs, -1);
|
|||
+ dissect(payload_tvb, pinfo, tree, &xdrs, -1);
|
|||
|
|||
xdr_destroy(&xdrs); |
|||
g_free(payload_data); |
|||
|
|||
if (nfds != 0) |
|||
- dissect_libvirt_fds(tvb, start + payload_length, nfds);
|
|||
+ dissect_libvirt_fds(tvb, pinfo, start + payload_length, nfds);
|
|||
} |
|||
|
|||
static gboolean |
|||
-dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
|||
+dissect_xdr_stream_hole(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo,
|
|||
+ proto_tree *tree,
|
|||
+ XDR *xdrs,
|
|||
+ int hf)
|
|||
{ |
|||
goffset start; |
|||
proto_item *ti; |
|||
@@ -411,10 +468,10 @@ dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
|||
tree = proto_item_add_subtree(ti, ett_libvirt_stream_hole); |
|||
|
|||
hf = hf_libvirt_stream_hole_length; |
|||
- if (!dissect_xdr_hyper(tvb, tree, xdrs, hf)) return FALSE;
|
|||
+ if (!dissect_xdr_hyper(tvb, pinfo, tree, xdrs, hf)) return FALSE;
|
|||
|
|||
hf = hf_libvirt_stream_hole_flags; |
|||
- if (!dissect_xdr_u_int(tvb, tree, xdrs, hf)) return FALSE;
|
|||
+ if (!dissect_xdr_u_int(tvb, pinfo, tree, xdrs, hf)) return FALSE;
|
|||
|
|||
proto_item_set_len(ti, xdr_getpos(xdrs) - start); |
|||
return TRUE; |
|||
@@ -424,6 +481,7 @@ dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
|||
|
|||
static void |
|||
dissect_libvirt_payload(tvbuff_t *tvb, |
|||
+ packet_info *pinfo,
|
|||
proto_tree *tree, |
|||
uint32_t prog, |
|||
int32_t proc, |
|||
@@ -447,13 +505,13 @@ dissect_libvirt_payload(tvbuff_t *tvb,
|
|||
xd = find_payload_dissector(proc, type, pds, *len); |
|||
if (xd == NULL) |
|||
goto unknown; |
|||
- dissect_libvirt_payload_xdr_data(tvb, tree, payload_length, status, xd);
|
|||
+ dissect_libvirt_payload_xdr_data(tvb, pinfo, tree, payload_length, status, xd);
|
|||
} else if (status == VIR_NET_ERROR) { |
|||
- dissect_libvirt_payload_xdr_data(tvb, tree, payload_length, status, dissect_xdr_remote_error);
|
|||
+ dissect_libvirt_payload_xdr_data(tvb, pinfo, tree, payload_length, status, dissect_xdr_remote_error);
|
|||
} else if (type == VIR_NET_STREAM) { /* implicitly, status == VIR_NET_CONTINUE */ |
|||
- dissect_libvirt_stream(tvb, tree, payload_length);
|
|||
+ dissect_libvirt_stream(tvb, pinfo, tree, payload_length);
|
|||
} else if (type == VIR_NET_STREAM_HOLE) { |
|||
- dissect_libvirt_payload_xdr_data(tvb, tree, payload_length, status, dissect_xdr_stream_hole);
|
|||
+ dissect_libvirt_payload_xdr_data(tvb, pinfo, tree, payload_length, status, dissect_xdr_stream_hole);
|
|||
} else { |
|||
goto unknown; |
|||
} |
|||
@@ -489,21 +547,21 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
serial = tvb_get_ntohl(tvb, offset); offset += 4; |
|||
status = tvb_get_ntohil(tvb, offset); offset += 4; |
|||
|
|||
- prog_str = vir_val_to_str(prog, program_strings, "%x");
|
|||
+ prog_str = vir_val_to_str(pinfo, prog, program_strings, "%x");
|
|||
col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s", prog_str); |
|||
- vir_wmem_free(prog_str);
|
|||
+ vir_wmem_free(pinfo, prog_str);
|
|||
|
|||
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS); |
|||
- proc_str = vir_val_to_str(proc, vs, "%d");
|
|||
+ proc_str = vir_val_to_str(pinfo, proc, vs, "%d");
|
|||
col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", proc_str); |
|||
- vir_wmem_free(proc_str);
|
|||
+ vir_wmem_free(pinfo, proc_str);
|
|||
|
|||
- type_str = vir_val_to_str(type, type_strings, "%d");
|
|||
- status_str = vir_val_to_str(status, status_strings, "%d");
|
|||
+ type_str = vir_val_to_str(pinfo, type, type_strings, "%d");
|
|||
+ status_str = vir_val_to_str(pinfo, status, status_strings, "%d");
|
|||
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s", |
|||
type_str, serial, status_str); |
|||
- vir_wmem_free(status_str);
|
|||
- vir_wmem_free(type_str);
|
|||
+ vir_wmem_free(pinfo, status_str);
|
|||
+ vir_wmem_free(pinfo, type_str);
|
|||
|
|||
if (tree) { |
|||
gint *hf_proc; |
|||
@@ -532,21 +590,26 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
proto_tree_add_item(libvirt_tree, hf_libvirt_status, tvb, offset, 4, ENC_NA); offset += 4; |
|||
|
|||
/* Dissect payload remaining */ |
|||
- dissect_libvirt_payload(tvb, libvirt_tree, prog, proc, type, status);
|
|||
+ dissect_libvirt_payload(tvb, pinfo, libvirt_tree, prog, proc, type, status);
|
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
static guint |
|||
-get_message_len(packet_info *pinfo G_GNUC_UNUSED, tvbuff_t *tvb, int offset, void *data G_GNUC_UNUSED)
|
|||
+get_message_len(packet_info *pinfo G_GNUC_UNUSED,
|
|||
+ tvbuff_t *tvb,
|
|||
+ int offset,
|
|||
+ void *data G_GNUC_UNUSED)
|
|||
{ |
|||
return tvb_get_ntohl(tvb, offset); |
|||
} |
|||
|
|||
static int |
|||
-dissect_libvirt(tvbuff_t *tvb, packet_info *pinfo,
|
|||
- proto_tree *tree, void *data G_GNUC_UNUSED)
|
|||
+dissect_libvirt(tvbuff_t *tvb,
|
|||
+ packet_info *pinfo,
|
|||
+ proto_tree *tree,
|
|||
+ void *data G_GNUC_UNUSED)
|
|||
{ |
|||
/* Another magic const - 4; simply, how much bytes |
|||
* is needed to tell the length of libvirt packet. */ |
|||
diff --git a/tools/wireshark/util/genxdrstub.pl b/tools/wireshark/util/genxdrstub.pl
|
|||
index 01b663a88c..f69695c091 100755
|
|||
--- a/tools/wireshark/util/genxdrstub.pl
|
|||
+++ b/tools/wireshark/util/genxdrstub.pl
|
|||
@@ -250,7 +250,7 @@ sub xdr_type {
|
|||
sub render_caller { |
|||
my ($self, $hfid) = @_; |
|||
my $name = $c->rinc( 'dissect_xdr_'.($self->idstrip || lc($self->xdr_type)) ); |
|||
- "$name(tvb, tree, xdrs, hf)";
|
|||
+ "$name(tvb, pinfo, tree, xdrs, hf)";
|
|||
} |
|||
|
|||
sub ft_type { |
|||
@@ -345,7 +345,7 @@ BEGIN{::register_profile(
|
|||
sub render_caller { |
|||
my ($self) = @_; |
|||
my ($klass) = ref($self) =~ /([^:]+)$/; |
|||
- sprintf '%s(tvb, tree, xdrs, hf, %s)',
|
|||
+ sprintf '%s(tvb, pinfo, tree, xdrs, hf, %s)',
|
|||
$c->rinc('dissect_xdr_'.lc($klass)), |
|||
$c->rinc('dissect_xdr_'.$self->reftype->idstrip); |
|||
} |
|||
@@ -359,7 +359,7 @@ BEGIN{::register_profile(
|
|||
sub render_caller { |
|||
my ($self, $hfid) = @_; |
|||
my ($klass) = ref($self) =~ /([^:]+)$/; |
|||
- sprintf '%s(tvb, tree, xdrs, hf, %s)',
|
|||
+ sprintf '%s(tvb, pinfo, tree, xdrs, hf, %s)',
|
|||
$c->rinc('dissect_xdr_'.lc($klass)), $self->length || '~0'; |
|||
} |
|||
|
|||
@@ -447,7 +447,7 @@ BEGIN{::register_profile(
|
|||
sub render_caller { |
|||
my ($self, $hfid) = @_; |
|||
my ($pname) = reverse split /__/, $hfid; |
|||
- sprintf 'dissect_xdr_array(tvb, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
|
|||
+ sprintf 'dissect_xdr_array(tvb, pinfo, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
|
|||
$c->rinc('ett_'.$self->idstrip), |
|||
$c->rinc("hf_$hfid\__$pname"), |
|||
$self->reftype->idstrip, |
|||
@@ -476,7 +476,7 @@ BEGIN{::register_profile(
|
|||
sub render_caller { |
|||
my ($self, $hfid) = @_; |
|||
my ($pname) = reverse split /__/, $hfid; |
|||
- sprintf 'dissect_xdr_vector(tvb, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
|
|||
+ sprintf 'dissect_xdr_vector(tvb, pinfo, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
|
|||
$c->rinc('ett_'.$self->idstrip), |
|||
$c->rinc("hf_$hfid\__$pname"), |
|||
$self->reftype->idstrip, |
|||
@@ -857,7 +857,7 @@ __END__<<DUMMY # Dummy heredoc to disable perl syntax highlighting
|
|||
my ($self, $ident) = @_; |
|||
return if $self->is_primitive; |
|||
%> |
|||
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
|||
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
|
|||
{ |
|||
return <%= $self->dealias->render_caller($self->ident eq $ident ? undef : $ident) %>; |
|||
} |
|||
@@ -865,7 +865,7 @@ static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *
|
|||
<% my ($self, $ident) = @_; |
|||
my $hfvar = $c->rinc('hf_'.$self->idstrip); |
|||
%> |
|||
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
|||
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
|
|||
{ |
|||
goffset start; |
|||
proto_item *ti; |
|||
@@ -890,7 +890,7 @@ static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *
|
|||
} |
|||
@@ Sym::Type::Enum#render_dissector |
|||
<% my ($self, $ident) = @_; %> |
|||
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
|||
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
|
|||
{ |
|||
goffset start; |
|||
enum { DUMMY } es; |
|||
@@ -914,7 +914,7 @@ static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *
|
|||
my ($self, $ident) = @_; |
|||
my $decl_type = $self->decl->type->idstrip; |
|||
%> |
|||
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
|||
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
|
|||
{ |
|||
gboolean rc = TRUE; |
|||
goffset start; |
|||
--
|
|||
2.51.0 |
|||
|
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:01a176ff4042ad58cf83c09fe0925d6bc8eed0ecce1e0ee19b8ef4c1ffa3806e |
|||
size 9700388 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:70bc4b6b22e5474faf46d4dad5717a6cdd5f85a9830012ae64014abbe52406fc |
|||
size 34387363 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:3b8f64583d114decb8ca5efecffaf233b22827c10ff27c84d79e93b7d363bbf6 |
|||
size 34392768 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:098909c9350707cca9f723a01309e5b4ef80231a0a823a735e6249d93122935b |
|||
size 34483126 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:a9080ce03a91550cb0405c3466a3a1dc6bf29b8a62cf6ea44a1f53a465021991 |
|||
size 34497242 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:5f31def0989a7042d5003089b375f0ded75a5c4246f5935a2c1fd75dd70c4bb5 |
|||
size 34522287 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:89f9dec9a5c25a08bd11e738bdf75e24f81e99d4419551917593d49f4d483e8e |
|||
size 34404729 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:365df77dcc7d371a2c66ed9cce6723f2bd934a57f5743a12416c416c6dbb7624 |
|||
size 34497904 |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue