forked from rpms/libvirt
import libvirt-8.0.0-7.el9_0
This commit is contained in:
parent
17901b066e
commit
398258cdbc
89
SOURCES/libvirt-Make-systemd-unit-ordering-more-robust.patch
Normal file
89
SOURCES/libvirt-Make-systemd-unit-ordering-more-robust.patch
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
From ee1ce580f5373070e4b6a50d1ae4a3218c737a72 Mon Sep 17 00:00:00 2001
|
||||||
|
Message-Id: <ee1ce580f5373070e4b6a50d1ae4a3218c737a72@dist-git>
|
||||||
|
From: Martin Kletzander <mkletzan@redhat.com>
|
||||||
|
Date: Mon, 14 Feb 2022 12:37:37 +0100
|
||||||
|
Subject: [PATCH] Make systemd unit ordering more robust
|
||||||
|
|
||||||
|
Since libvirt-guests script/service can operate on various URIs and we do
|
||||||
|
support both socket activation and traditional services, the ordering should be
|
||||||
|
specified for all the possible sockets and services.
|
||||||
|
|
||||||
|
Also remove the Wants= dependency since do not want to start any service. We
|
||||||
|
cannot know which one libvirt-guests is configured, so we'd have to start all
|
||||||
|
the daemons which would break if unused colliding services are not
|
||||||
|
masked (libvirtd.service in the modular case and all the modular daemon service
|
||||||
|
units in the monolithic scenario). Fortunately we can assume that the system is
|
||||||
|
configured properly to start services/sockets that are of interest to the user.
|
||||||
|
That also works with the setup described in https://libvirt.org/daemons.html .
|
||||||
|
|
||||||
|
To make it even more robust we add the daemon service into the machine units
|
||||||
|
created for individual domains as it was missing there.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1868537
|
||||||
|
|
||||||
|
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||||
|
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||||
|
(cherry picked from commit 4e42686adef8b9e9266f0099ddcd25bc95c4ed43)
|
||||||
|
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||||
|
---
|
||||||
|
src/util/virsystemd.c | 8 ++++++--
|
||||||
|
tools/libvirt-guests.service.in | 12 +++++++++++-
|
||||||
|
2 files changed, 17 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
|
||||||
|
index a86d4c6bb9..f156c2f39a 100644
|
||||||
|
--- a/src/util/virsystemd.c
|
||||||
|
+++ b/src/util/virsystemd.c
|
||||||
|
@@ -441,8 +441,10 @@ int virSystemdCreateMachine(const char *name,
|
||||||
|
nicindexes, nnicindexes, sizeof(int));
|
||||||
|
gprops = g_variant_new_parsed("[('Slice', <%s>),"
|
||||||
|
" ('After', <['libvirtd.service']>),"
|
||||||
|
+ " ('After', <['virt%sd.service']>),"
|
||||||
|
" ('Before', <['virt-guest-shutdown.target']>)]",
|
||||||
|
- slicename);
|
||||||
|
+ slicename,
|
||||||
|
+ drivername);
|
||||||
|
message = g_variant_new("(s@ayssus@ai@a(sv))",
|
||||||
|
name,
|
||||||
|
guuid,
|
||||||
|
@@ -489,8 +491,10 @@ int virSystemdCreateMachine(const char *name,
|
||||||
|
uuid, 16, sizeof(unsigned char));
|
||||||
|
gprops = g_variant_new_parsed("[('Slice', <%s>),"
|
||||||
|
" ('After', <['libvirtd.service']>),"
|
||||||
|
+ " ('After', <['virt%sd.service']>),"
|
||||||
|
" ('Before', <['virt-guest-shutdown.target']>)]",
|
||||||
|
- slicename);
|
||||||
|
+ slicename,
|
||||||
|
+ drivername);
|
||||||
|
message = g_variant_new("(s@ayssus@a(sv))",
|
||||||
|
name,
|
||||||
|
guuid,
|
||||||
|
diff --git a/tools/libvirt-guests.service.in b/tools/libvirt-guests.service.in
|
||||||
|
index 1a9b233e11..3cf6476196 100644
|
||||||
|
--- a/tools/libvirt-guests.service.in
|
||||||
|
+++ b/tools/libvirt-guests.service.in
|
||||||
|
@@ -1,10 +1,20 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Suspend/Resume Running libvirt Guests
|
||||||
|
-Wants=libvirtd.service
|
||||||
|
Requires=virt-guest-shutdown.target
|
||||||
|
After=network.target
|
||||||
|
After=time-sync.target
|
||||||
|
+After=libvirtd.socket
|
||||||
|
+After=virtqemud.socket
|
||||||
|
+After=virtlxcd.socket
|
||||||
|
+After=virtvboxd.socket
|
||||||
|
+After=virtvzd.socket
|
||||||
|
+After=virtxend.socket
|
||||||
|
After=libvirtd.service
|
||||||
|
+After=virtqemud.service
|
||||||
|
+After=virtlxcd.service
|
||||||
|
+After=virtvboxd.service
|
||||||
|
+After=virtvzd.service
|
||||||
|
+After=virtxend.service
|
||||||
|
After=virt-guest-shutdown.target
|
||||||
|
Documentation=man:libvirt-guests(8)
|
||||||
|
Documentation=https://libvirt.org
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -0,0 +1,77 @@
|
|||||||
|
From bbab997f4307da65856dedd3f319037ce442d17e Mon Sep 17 00:00:00 2001
|
||||||
|
Message-Id: <bbab997f4307da65856dedd3f319037ce442d17e@dist-git>
|
||||||
|
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||||
|
Date: Thu, 24 Feb 2022 18:41:29 +0000
|
||||||
|
Subject: [PATCH] nwfilter: hold filter update lock when creating/deleting
|
||||||
|
bindings
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The nwfilter update lock is historically acquired by the virt
|
||||||
|
drivers in order to achieve serialization between nwfilter
|
||||||
|
define/undefine, and instantiation/teardown of filters.
|
||||||
|
|
||||||
|
When running in the modular daemons, however, the mutex that
|
||||||
|
the virt drivers are locking is in a completely different
|
||||||
|
process from the mutex that the nwfilter driver is locking.
|
||||||
|
|
||||||
|
Serialization is lost and thus call from the virt driver to
|
||||||
|
virNWFilterBindingCreateXML can deadlock with a concurrent
|
||||||
|
call to the virNWFilterDefineXML method.
|
||||||
|
|
||||||
|
The solution is surprisingly easy, the update lock simply
|
||||||
|
needs acquiring in the virNWFilterBindingCreateXML method
|
||||||
|
and virNWFilterBindingUndefine method instead of in the
|
||||||
|
virt drivers.
|
||||||
|
|
||||||
|
The only semantic difference here is that when a virtual
|
||||||
|
machine has multiple NICs, the instantiation and teardown
|
||||||
|
of filters is no longer serialized for the whole VM, but
|
||||||
|
rather for each NIC. This should not be a problem since
|
||||||
|
the virt drivers already need to cope with tearing down
|
||||||
|
a partially created VM where only some of the NICs are
|
||||||
|
setup.
|
||||||
|
|
||||||
|
Reviewed-by: Laine Stump <laine@redhat.com>
|
||||||
|
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||||
|
(cherry picked from commit 65dc79f50b96b34b2253601b8972d5ca90658f33)
|
||||||
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2044379
|
||||||
|
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||||
|
---
|
||||||
|
src/nwfilter/nwfilter_driver.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
|
||||||
|
index 200451d6b1..a4479fc9fe 100644
|
||||||
|
--- a/src/nwfilter/nwfilter_driver.c
|
||||||
|
+++ b/src/nwfilter/nwfilter_driver.c
|
||||||
|
@@ -760,12 +760,15 @@ nwfilterBindingCreateXML(virConnectPtr conn,
|
||||||
|
if (!(ret = virGetNWFilterBinding(conn, def->portdevname, def->filter)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
+ virNWFilterReadLockFilterUpdates();
|
||||||
|
if (virNWFilterInstantiateFilter(driver, def) < 0) {
|
||||||
|
+ virNWFilterUnlockFilterUpdates();
|
||||||
|
virNWFilterBindingObjListRemove(driver->bindings, obj);
|
||||||
|
virObjectUnref(ret);
|
||||||
|
ret = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
+ virNWFilterUnlockFilterUpdates();
|
||||||
|
virNWFilterBindingObjSave(obj, driver->bindingDir);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
@@ -802,7 +805,9 @@ nwfilterBindingDelete(virNWFilterBindingPtr binding)
|
||||||
|
if (virNWFilterBindingDeleteEnsureACL(binding->conn, def) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
+ virNWFilterReadLockFilterUpdates();
|
||||||
|
virNWFilterTeardownFilter(def);
|
||||||
|
+ virNWFilterUnlockFilterUpdates();
|
||||||
|
virNWFilterBindingObjDelete(obj, driver->bindingDir);
|
||||||
|
virNWFilterBindingObjListRemove(driver->bindings, obj);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -0,0 +1,222 @@
|
|||||||
|
From 7bcd75ca73d8eda05fafa8342309a8fd058cd326 Mon Sep 17 00:00:00 2001
|
||||||
|
Message-Id: <7bcd75ca73d8eda05fafa8342309a8fd058cd326@dist-git>
|
||||||
|
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||||
|
Date: Thu, 24 Feb 2022 19:02:32 +0000
|
||||||
|
Subject: [PATCH] qemu,lxc: remove use to nwfilter update lock
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Now that the virNWFilterBinding APIs are using the nwfilter
|
||||||
|
update lock directly, there is no need for the virt drivers
|
||||||
|
to do it themselves.
|
||||||
|
|
||||||
|
Reviewed-by: Laine Stump <laine@redhat.com>
|
||||||
|
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||||
|
(cherry picked from commit 5f8b090f421cd6a6c46f44905431491e2d3cf8f5)
|
||||||
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2044379
|
||||||
|
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||||
|
---
|
||||||
|
src/lxc/lxc_driver.c | 6 ------
|
||||||
|
src/qemu/qemu_driver.c | 18 ------------------
|
||||||
|
src/qemu/qemu_migration.c | 3 ---
|
||||||
|
src/qemu/qemu_process.c | 4 ----
|
||||||
|
4 files changed, 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
|
||||||
|
index 7bc39120ee..e581c62668 100644
|
||||||
|
--- a/src/lxc/lxc_driver.c
|
||||||
|
+++ b/src/lxc/lxc_driver.c
|
||||||
|
@@ -971,8 +971,6 @@ static int lxcDomainCreateWithFiles(virDomainPtr dom,
|
||||||
|
|
||||||
|
virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, -1);
|
||||||
|
|
||||||
|
- virNWFilterReadLockFilterUpdates();
|
||||||
|
-
|
||||||
|
if (!(vm = lxcDomObjFromDomain(dom)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
@@ -1014,7 +1012,6 @@ static int lxcDomainCreateWithFiles(virDomainPtr dom,
|
||||||
|
cleanup:
|
||||||
|
virDomainObjEndAPI(&vm);
|
||||||
|
virObjectEventStateQueue(driver->domainEventState, event);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1080,8 +1077,6 @@ lxcDomainCreateXMLWithFiles(virConnectPtr conn,
|
||||||
|
if (flags & VIR_DOMAIN_START_VALIDATE)
|
||||||
|
parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA;
|
||||||
|
|
||||||
|
- virNWFilterReadLockFilterUpdates();
|
||||||
|
-
|
||||||
|
if (!(caps = virLXCDriverGetCapabilities(driver, false)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
@@ -1138,7 +1133,6 @@ lxcDomainCreateXMLWithFiles(virConnectPtr conn,
|
||||||
|
cleanup:
|
||||||
|
virDomainObjEndAPI(&vm);
|
||||||
|
virObjectEventStateQueue(driver->domainEventState, event);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
return dom;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||||
|
index d3d76c003f..00a86b6c7c 100644
|
||||||
|
--- a/src/qemu/qemu_driver.c
|
||||||
|
+++ b/src/qemu/qemu_driver.c
|
||||||
|
@@ -1603,8 +1603,6 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
|
||||||
|
if (flags & VIR_DOMAIN_START_AUTODESTROY)
|
||||||
|
start_flags |= VIR_QEMU_PROCESS_START_AUTODESTROY;
|
||||||
|
|
||||||
|
- virNWFilterReadLockFilterUpdates();
|
||||||
|
-
|
||||||
|
if (!(def = virDomainDefParseString(xml, driver->xmlopt,
|
||||||
|
NULL, parse_flags)))
|
||||||
|
goto cleanup;
|
||||||
|
@@ -1658,7 +1656,6 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
|
||||||
|
virDomainObjEndAPI(&vm);
|
||||||
|
virObjectEventStateQueue(driver->domainEventState, event);
|
||||||
|
virObjectEventStateQueue(driver->domainEventState, event2);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
return dom;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -5773,8 +5770,6 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
||||||
|
VIR_DOMAIN_SAVE_PAUSED, -1);
|
||||||
|
|
||||||
|
|
||||||
|
- virNWFilterReadLockFilterUpdates();
|
||||||
|
-
|
||||||
|
fd = qemuSaveImageOpen(driver, NULL, path, &def, &data,
|
||||||
|
(flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
|
||||||
|
&wrapperFd, false, false);
|
||||||
|
@@ -5846,7 +5841,6 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
||||||
|
if (vm && ret < 0)
|
||||||
|
qemuDomainRemoveInactiveJob(driver, vm);
|
||||||
|
virDomainObjEndAPI(&vm);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -6395,8 +6389,6 @@ qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
|
||||||
|
VIR_DOMAIN_START_BYPASS_CACHE |
|
||||||
|
VIR_DOMAIN_START_FORCE_BOOT, -1);
|
||||||
|
|
||||||
|
- virNWFilterReadLockFilterUpdates();
|
||||||
|
-
|
||||||
|
if (!(vm = qemuDomainObjFromDomain(dom)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
@@ -6425,7 +6417,6 @@ qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virDomainObjEndAPI(&vm);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -7811,8 +7802,6 @@ qemuDomainAttachDeviceFlags(virDomainPtr dom,
|
||||||
|
virDomainObj *vm = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
- virNWFilterReadLockFilterUpdates();
|
||||||
|
-
|
||||||
|
if (!(vm = qemuDomainObjFromDomain(dom)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
@@ -7835,7 +7824,6 @@ qemuDomainAttachDeviceFlags(virDomainPtr dom,
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virDomainObjEndAPI(&vm);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -7865,8 +7853,6 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
|
||||||
|
VIR_DOMAIN_AFFECT_CONFIG |
|
||||||
|
VIR_DOMAIN_DEVICE_MODIFY_FORCE, -1);
|
||||||
|
|
||||||
|
- virNWFilterReadLockFilterUpdates();
|
||||||
|
-
|
||||||
|
cfg = virQEMUDriverGetConfig(driver);
|
||||||
|
|
||||||
|
if (!(vm = qemuDomainObjFromDomain(dom)))
|
||||||
|
@@ -7943,7 +7929,6 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
|
||||||
|
if (dev != dev_copy)
|
||||||
|
virDomainDeviceDefFree(dev_copy);
|
||||||
|
virDomainObjEndAPI(&vm);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -13644,8 +13629,6 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
|
||||||
|
virDomainObj *vm = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
- virNWFilterReadLockFilterUpdates();
|
||||||
|
-
|
||||||
|
if (!(vm = qemuDomObjFromSnapshot(snapshot)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
@@ -13656,7 +13639,6 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virDomainObjEndAPI(&vm);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
|
||||||
|
index 2635ef1162..358cb9c3b5 100644
|
||||||
|
--- a/src/qemu/qemu_migration.c
|
||||||
|
+++ b/src/qemu/qemu_migration.c
|
||||||
|
@@ -2779,8 +2779,6 @@ qemuMigrationDstPrepareAny(virQEMUDriver *driver,
|
||||||
|
int rv;
|
||||||
|
g_autofree char *tlsAlias = NULL;
|
||||||
|
|
||||||
|
- virNWFilterReadLockFilterUpdates();
|
||||||
|
-
|
||||||
|
if (flags & VIR_MIGRATE_OFFLINE) {
|
||||||
|
if (flags & (VIR_MIGRATE_NON_SHARED_DISK |
|
||||||
|
VIR_MIGRATE_NON_SHARED_INC)) {
|
||||||
|
@@ -3101,7 +3099,6 @@ qemuMigrationDstPrepareAny(virQEMUDriver *driver,
|
||||||
|
virDomainObjEndAPI(&vm);
|
||||||
|
virObjectEventStateQueue(driver->domainEventState, event);
|
||||||
|
qemuMigrationCookieFree(mig);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
virErrorRestore(&origErr);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
||||||
|
index 5c6657a876..914f9bef8b 100644
|
||||||
|
--- a/src/qemu/qemu_process.c
|
||||||
|
+++ b/src/qemu/qemu_process.c
|
||||||
|
@@ -8986,7 +8986,6 @@ qemuProcessReconnect(void *opaque)
|
||||||
|
qemuDomainRemoveInactiveJob(driver, obj);
|
||||||
|
}
|
||||||
|
virDomainObjEndAPI(&obj);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
virIdentitySetCurrent(NULL);
|
||||||
|
return;
|
||||||
|
|
||||||
|
@@ -9038,8 +9037,6 @@ qemuProcessReconnectHelper(virDomainObj *obj,
|
||||||
|
data->obj = obj;
|
||||||
|
data->identity = virIdentityGetCurrent();
|
||||||
|
|
||||||
|
- virNWFilterReadLockFilterUpdates();
|
||||||
|
-
|
||||||
|
/* this lock and reference will be eventually transferred to the thread
|
||||||
|
* that handles the reconnect */
|
||||||
|
virObjectLock(obj);
|
||||||
|
@@ -9062,7 +9059,6 @@ qemuProcessReconnectHelper(virDomainObj *obj,
|
||||||
|
qemuDomainRemoveInactiveJobLocked(src->driver, obj);
|
||||||
|
|
||||||
|
virDomainObjEndAPI(&obj);
|
||||||
|
- virNWFilterUnlockFilterUpdates();
|
||||||
|
g_clear_object(&data->identity);
|
||||||
|
VIR_FREE(data);
|
||||||
|
return -1;
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -0,0 +1,471 @@
|
|||||||
|
From 3cde498c98be902fc8fe87c895dfeaaa95352b38 Mon Sep 17 00:00:00 2001
|
||||||
|
Message-Id: <3cde498c98be902fc8fe87c895dfeaaa95352b38@dist-git>
|
||||||
|
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||||
|
Date: Thu, 3 Feb 2022 13:43:18 +0000
|
||||||
|
Subject: [PATCH] qemu: support firmware descriptor flash 'mode' for optional
|
||||||
|
NVRAM
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Currently the 'nvram_template' entry is mandatory when parsing the
|
||||||
|
firmware descriptor based on flash. QEMU is extending the firmware
|
||||||
|
descriptor spec to make the 'nvram_template' optional, depending
|
||||||
|
on the value of a new 'mode' field:
|
||||||
|
|
||||||
|
- "split"
|
||||||
|
* "executable" contains read-only CODE
|
||||||
|
* "nvram_template" contains read-write VARS
|
||||||
|
|
||||||
|
- "combined"
|
||||||
|
* "executable" contains read-write CODE and VARs
|
||||||
|
* "nvram_template" not present
|
||||||
|
|
||||||
|
- "stateless"
|
||||||
|
* "executable" contains read-only CODE and VARs
|
||||||
|
* "nvram_template" not present
|
||||||
|
|
||||||
|
In the latter case, the guest OS can write vars but the
|
||||||
|
firmware will make no attempt to persist them, so any changes
|
||||||
|
will be lost at poweroff.
|
||||||
|
|
||||||
|
For now we parse this new 'mode' but discard any firmware
|
||||||
|
which is not 'mode=split' when matching for a domain.
|
||||||
|
|
||||||
|
In the tests we have a mixture of files with and without the
|
||||||
|
mode attribute.
|
||||||
|
|
||||||
|
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||||
|
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||||
|
(cherry picked from commit 32b9d8b0ae00669555f01f91ee11612a636c4b69)
|
||||||
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2057769
|
||||||
|
---
|
||||||
|
src/qemu/qemu_firmware.c | 79 ++++++++++++++++---
|
||||||
|
.../share/qemu/firmware/50-ovmf-sb-keys.json | 33 ++++++++
|
||||||
|
.../out/usr/share/qemu/firmware/61-ovmf.json | 31 ++++++++
|
||||||
|
.../out/usr/share/qemu/firmware/70-aavmf.json | 28 +++++++
|
||||||
|
.../qemu/firmware/45-ovmf-sev-stateless.json | 31 ++++++++
|
||||||
|
.../qemu/firmware/55-ovmf-sb-combined.json | 33 ++++++++
|
||||||
|
.../usr/share/qemu/firmware/60-ovmf-sb.json | 1 +
|
||||||
|
tests/qemufirmwaretest.c | 31 ++++++--
|
||||||
|
8 files changed, 246 insertions(+), 21 deletions(-)
|
||||||
|
create mode 100644 tests/qemufirmwaredata/out/usr/share/qemu/firmware/50-ovmf-sb-keys.json
|
||||||
|
create mode 100644 tests/qemufirmwaredata/out/usr/share/qemu/firmware/61-ovmf.json
|
||||||
|
create mode 100644 tests/qemufirmwaredata/out/usr/share/qemu/firmware/70-aavmf.json
|
||||||
|
create mode 100644 tests/qemufirmwaredata/usr/share/qemu/firmware/45-ovmf-sev-stateless.json
|
||||||
|
create mode 100644 tests/qemufirmwaredata/usr/share/qemu/firmware/55-ovmf-sb-combined.json
|
||||||
|
|
||||||
|
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
|
||||||
|
index 529ab8d68e..7911d45aa0 100644
|
||||||
|
--- a/src/qemu/qemu_firmware.c
|
||||||
|
+++ b/src/qemu/qemu_firmware.c
|
||||||
|
@@ -59,6 +59,22 @@ VIR_ENUM_IMPL(qemuFirmwareOSInterface,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
+typedef enum {
|
||||||
|
+ QEMU_FIRMWARE_FLASH_MODE_SPLIT,
|
||||||
|
+ QEMU_FIRMWARE_FLASH_MODE_COMBINED,
|
||||||
|
+ QEMU_FIRMWARE_FLASH_MODE_STATELESS,
|
||||||
|
+
|
||||||
|
+ QEMU_FIRMWARE_FLASH_MODE_LAST,
|
||||||
|
+} qemuFirmwareFlashMode;
|
||||||
|
+
|
||||||
|
+VIR_ENUM_DECL(qemuFirmwareFlashMode);
|
||||||
|
+VIR_ENUM_IMPL(qemuFirmwareFlashMode,
|
||||||
|
+ QEMU_FIRMWARE_FLASH_MODE_LAST,
|
||||||
|
+ "split",
|
||||||
|
+ "combined",
|
||||||
|
+ "stateless",
|
||||||
|
+);
|
||||||
|
+
|
||||||
|
typedef struct _qemuFirmwareFlashFile qemuFirmwareFlashFile;
|
||||||
|
struct _qemuFirmwareFlashFile {
|
||||||
|
char *filename;
|
||||||
|
@@ -68,6 +84,7 @@ struct _qemuFirmwareFlashFile {
|
||||||
|
|
||||||
|
typedef struct _qemuFirmwareMappingFlash qemuFirmwareMappingFlash;
|
||||||
|
struct _qemuFirmwareMappingFlash {
|
||||||
|
+ qemuFirmwareFlashMode mode;
|
||||||
|
qemuFirmwareFlashFile executable;
|
||||||
|
qemuFirmwareFlashFile nvram_template;
|
||||||
|
};
|
||||||
|
@@ -359,9 +376,31 @@ qemuFirmwareMappingFlashParse(const char *path,
|
||||||
|
virJSONValue *doc,
|
||||||
|
qemuFirmwareMappingFlash *flash)
|
||||||
|
{
|
||||||
|
+ virJSONValue *mode;
|
||||||
|
virJSONValue *executable;
|
||||||
|
virJSONValue *nvram_template;
|
||||||
|
|
||||||
|
+ if (!(mode = virJSONValueObjectGet(doc, "mode"))) {
|
||||||
|
+ /* Historical default */
|
||||||
|
+ flash->mode = QEMU_FIRMWARE_FLASH_MODE_SPLIT;
|
||||||
|
+ } else {
|
||||||
|
+ const char *modestr = virJSONValueGetString(mode);
|
||||||
|
+ int modeval;
|
||||||
|
+ if (!modestr) {
|
||||||
|
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
+ _("Firmware flash mode value was malformed"));
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ modeval = qemuFirmwareFlashModeTypeFromString(modestr);
|
||||||
|
+ if (modeval < 0) {
|
||||||
|
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
+ _("Firmware flash mode value '%s' unexpected"),
|
||||||
|
+ modestr);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ flash->mode = modeval;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!(executable = virJSONValueObjectGet(doc, "executable"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("missing 'executable' in '%s'"),
|
||||||
|
@@ -372,15 +411,17 @@ qemuFirmwareMappingFlashParse(const char *path,
|
||||||
|
if (qemuFirmwareFlashFileParse(path, executable, &flash->executable) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
- if (!(nvram_template = virJSONValueObjectGet(doc, "nvram-template"))) {
|
||||||
|
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
- _("missing 'nvram-template' in '%s'"),
|
||||||
|
- path);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
+ if (flash->mode == QEMU_FIRMWARE_FLASH_MODE_SPLIT) {
|
||||||
|
+ if (!(nvram_template = virJSONValueObjectGet(doc, "nvram-template"))) {
|
||||||
|
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
+ _("missing 'nvram-template' in '%s'"),
|
||||||
|
+ path);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (qemuFirmwareFlashFileParse(path, nvram_template, &flash->nvram_template) < 0)
|
||||||
|
- return -1;
|
||||||
|
+ if (qemuFirmwareFlashFileParse(path, nvram_template, &flash->nvram_template) < 0)
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -693,10 +734,12 @@ qemuFirmwareMappingFlashFormat(virJSONValue *mapping,
|
||||||
|
g_autoptr(virJSONValue) executable = NULL;
|
||||||
|
g_autoptr(virJSONValue) nvram_template = NULL;
|
||||||
|
|
||||||
|
- if (!(executable = qemuFirmwareFlashFileFormat(flash->executable)))
|
||||||
|
+ if (virJSONValueObjectAppendString(mapping,
|
||||||
|
+ "mode",
|
||||||
|
+ qemuFirmwareFlashModeTypeToString(flash->mode)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
- if (!(nvram_template = qemuFirmwareFlashFileFormat(flash->nvram_template)))
|
||||||
|
+ if (!(executable = qemuFirmwareFlashFileFormat(flash->executable)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (virJSONValueObjectAppend(mapping,
|
||||||
|
@@ -704,11 +747,15 @@ qemuFirmwareMappingFlashFormat(virJSONValue *mapping,
|
||||||
|
&executable) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
+ if (flash->mode == QEMU_FIRMWARE_FLASH_MODE_SPLIT) {
|
||||||
|
+ if (!(nvram_template = qemuFirmwareFlashFileFormat(flash->nvram_template)))
|
||||||
|
+ return -1;
|
||||||
|
|
||||||
|
- if (virJSONValueObjectAppend(mapping,
|
||||||
|
+ if (virJSONValueObjectAppend(mapping,
|
||||||
|
"nvram-template",
|
||||||
|
- &nvram_template) < 0)
|
||||||
|
- return -1;
|
||||||
|
+ &nvram_template) < 0)
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -1053,6 +1100,12 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (fw->mapping.device == QEMU_FIRMWARE_DEVICE_FLASH &&
|
||||||
|
+ fw->mapping.data.flash.mode != QEMU_FIRMWARE_FLASH_MODE_SPLIT) {
|
||||||
|
+ VIR_DEBUG("Discarding loader without split flash");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (def->sec) {
|
||||||
|
switch ((virDomainLaunchSecurity) def->sec->sectype) {
|
||||||
|
case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
|
||||||
|
diff --git a/tests/qemufirmwaredata/out/usr/share/qemu/firmware/50-ovmf-sb-keys.json b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/50-ovmf-sb-keys.json
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..c251682cd9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/50-ovmf-sb-keys.json
|
||||||
|
@@ -0,0 +1,33 @@
|
||||||
|
+{
|
||||||
|
+ "interface-types": [
|
||||||
|
+ "uefi"
|
||||||
|
+ ],
|
||||||
|
+ "mapping": {
|
||||||
|
+ "device": "flash",
|
||||||
|
+ "mode": "split",
|
||||||
|
+ "executable": {
|
||||||
|
+ "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
|
||||||
|
+ "format": "raw"
|
||||||
|
+ },
|
||||||
|
+ "nvram-template": {
|
||||||
|
+ "filename": "/usr/share/OVMF/OVMF_VARS.secboot.fd",
|
||||||
|
+ "format": "raw"
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ "targets": [
|
||||||
|
+ {
|
||||||
|
+ "architecture": "x86_64",
|
||||||
|
+ "machines": [
|
||||||
|
+ "pc-q35-*"
|
||||||
|
+ ]
|
||||||
|
+ }
|
||||||
|
+ ],
|
||||||
|
+ "features": [
|
||||||
|
+ "acpi-s3",
|
||||||
|
+ "amd-sev",
|
||||||
|
+ "enrolled-keys",
|
||||||
|
+ "requires-smm",
|
||||||
|
+ "secure-boot",
|
||||||
|
+ "verbose-dynamic"
|
||||||
|
+ ]
|
||||||
|
+}
|
||||||
|
diff --git a/tests/qemufirmwaredata/out/usr/share/qemu/firmware/61-ovmf.json b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/61-ovmf.json
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..2a9aa23efb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/61-ovmf.json
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+{
|
||||||
|
+ "interface-types": [
|
||||||
|
+ "uefi"
|
||||||
|
+ ],
|
||||||
|
+ "mapping": {
|
||||||
|
+ "device": "flash",
|
||||||
|
+ "mode": "split",
|
||||||
|
+ "executable": {
|
||||||
|
+ "filename": "/usr/share/OVMF/OVMF_CODE.fd",
|
||||||
|
+ "format": "raw"
|
||||||
|
+ },
|
||||||
|
+ "nvram-template": {
|
||||||
|
+ "filename": "/usr/share/OVMF/OVMF_VARS.fd",
|
||||||
|
+ "format": "raw"
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ "targets": [
|
||||||
|
+ {
|
||||||
|
+ "architecture": "x86_64",
|
||||||
|
+ "machines": [
|
||||||
|
+ "pc-i440fx-*",
|
||||||
|
+ "pc-q35-*"
|
||||||
|
+ ]
|
||||||
|
+ }
|
||||||
|
+ ],
|
||||||
|
+ "features": [
|
||||||
|
+ "acpi-s3",
|
||||||
|
+ "amd-sev",
|
||||||
|
+ "verbose-dynamic"
|
||||||
|
+ ]
|
||||||
|
+}
|
||||||
|
diff --git a/tests/qemufirmwaredata/out/usr/share/qemu/firmware/70-aavmf.json b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/70-aavmf.json
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..9bd5ac2868
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/qemufirmwaredata/out/usr/share/qemu/firmware/70-aavmf.json
|
||||||
|
@@ -0,0 +1,28 @@
|
||||||
|
+{
|
||||||
|
+ "interface-types": [
|
||||||
|
+ "uefi"
|
||||||
|
+ ],
|
||||||
|
+ "mapping": {
|
||||||
|
+ "device": "flash",
|
||||||
|
+ "mode": "split",
|
||||||
|
+ "executable": {
|
||||||
|
+ "filename": "/usr/share/AAVMF/AAVMF_CODE.fd",
|
||||||
|
+ "format": "raw"
|
||||||
|
+ },
|
||||||
|
+ "nvram-template": {
|
||||||
|
+ "filename": "/usr/share/AAVMF/AAVMF_VARS.fd",
|
||||||
|
+ "format": "raw"
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ "targets": [
|
||||||
|
+ {
|
||||||
|
+ "architecture": "aarch64",
|
||||||
|
+ "machines": [
|
||||||
|
+ "virt-*"
|
||||||
|
+ ]
|
||||||
|
+ }
|
||||||
|
+ ],
|
||||||
|
+ "features": [
|
||||||
|
+
|
||||||
|
+ ]
|
||||||
|
+}
|
||||||
|
diff --git a/tests/qemufirmwaredata/usr/share/qemu/firmware/45-ovmf-sev-stateless.json b/tests/qemufirmwaredata/usr/share/qemu/firmware/45-ovmf-sev-stateless.json
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..5a619f3ab0
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/qemufirmwaredata/usr/share/qemu/firmware/45-ovmf-sev-stateless.json
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+{
|
||||||
|
+ "description": "OVMF for x86_64, with SEV, without SB, without SMM, with NO varstore",
|
||||||
|
+ "interface-types": [
|
||||||
|
+ "uefi"
|
||||||
|
+ ],
|
||||||
|
+ "mapping": {
|
||||||
|
+ "device": "flash",
|
||||||
|
+ "mode": "stateless",
|
||||||
|
+ "executable": {
|
||||||
|
+ "filename": "/usr/share/OVMF/OVMF.sev.fd",
|
||||||
|
+ "format": "raw"
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ "targets": [
|
||||||
|
+ {
|
||||||
|
+ "architecture": "x86_64",
|
||||||
|
+ "machines": [
|
||||||
|
+ "pc-q35-*"
|
||||||
|
+ ]
|
||||||
|
+ }
|
||||||
|
+ ],
|
||||||
|
+ "features": [
|
||||||
|
+ "acpi-s3",
|
||||||
|
+ "amd-sev",
|
||||||
|
+ "amd-sev-es",
|
||||||
|
+ "verbose-dynamic"
|
||||||
|
+ ],
|
||||||
|
+ "tags": [
|
||||||
|
+
|
||||||
|
+ ]
|
||||||
|
+}
|
||||||
|
diff --git a/tests/qemufirmwaredata/usr/share/qemu/firmware/55-ovmf-sb-combined.json b/tests/qemufirmwaredata/usr/share/qemu/firmware/55-ovmf-sb-combined.json
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..eb3332e4ab
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/qemufirmwaredata/usr/share/qemu/firmware/55-ovmf-sb-combined.json
|
||||||
|
@@ -0,0 +1,33 @@
|
||||||
|
+{
|
||||||
|
+ "description": "OVMF with SB+SMM, SB enabled, MS certs enrolled",
|
||||||
|
+ "interface-types": [
|
||||||
|
+ "uefi"
|
||||||
|
+ ],
|
||||||
|
+ "mapping": {
|
||||||
|
+ "device": "flash",
|
||||||
|
+ "mode": "combined",
|
||||||
|
+ "executable": {
|
||||||
|
+ "filename": "/usr/share/OVMF/OVMF.secboot.fd",
|
||||||
|
+ "format": "raw"
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ "targets": [
|
||||||
|
+ {
|
||||||
|
+ "architecture": "x86_64",
|
||||||
|
+ "machines": [
|
||||||
|
+ "pc-q35-*"
|
||||||
|
+ ]
|
||||||
|
+ }
|
||||||
|
+ ],
|
||||||
|
+ "features": [
|
||||||
|
+ "acpi-s3",
|
||||||
|
+ "amd-sev",
|
||||||
|
+ "enrolled-keys",
|
||||||
|
+ "requires-smm",
|
||||||
|
+ "secure-boot",
|
||||||
|
+ "verbose-dynamic"
|
||||||
|
+ ],
|
||||||
|
+ "tags": [
|
||||||
|
+
|
||||||
|
+ ]
|
||||||
|
+}
|
||||||
|
diff --git a/tests/qemufirmwaredata/usr/share/qemu/firmware/60-ovmf-sb.json b/tests/qemufirmwaredata/usr/share/qemu/firmware/60-ovmf-sb.json
|
||||||
|
index 5e8a94ae78..a5273a5e8b 100644
|
||||||
|
--- a/tests/qemufirmwaredata/usr/share/qemu/firmware/60-ovmf-sb.json
|
||||||
|
+++ b/tests/qemufirmwaredata/usr/share/qemu/firmware/60-ovmf-sb.json
|
||||||
|
@@ -5,6 +5,7 @@
|
||||||
|
],
|
||||||
|
"mapping": {
|
||||||
|
"device": "flash",
|
||||||
|
+ "mode": "split",
|
||||||
|
"executable": {
|
||||||
|
"filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
|
||||||
|
"format": "raw"
|
||||||
|
diff --git a/tests/qemufirmwaretest.c b/tests/qemufirmwaretest.c
|
||||||
|
index cad4b6d383..fc3416b2ae 100644
|
||||||
|
--- a/tests/qemufirmwaretest.c
|
||||||
|
+++ b/tests/qemufirmwaretest.c
|
||||||
|
@@ -17,22 +17,31 @@ static int
|
||||||
|
testParseFormatFW(const void *opaque)
|
||||||
|
{
|
||||||
|
const char *filename = opaque;
|
||||||
|
- g_autofree char *path = NULL;
|
||||||
|
+ g_autofree char *inpath = NULL;
|
||||||
|
+ g_autofree char *outpath = NULL;
|
||||||
|
g_autoptr(qemuFirmware) fw = NULL;
|
||||||
|
- g_autofree char *buf = NULL;
|
||||||
|
g_autoptr(virJSONValue) json = NULL;
|
||||||
|
g_autofree char *expected = NULL;
|
||||||
|
g_autofree char *actual = NULL;
|
||||||
|
+ g_autofree char *buf = NULL;
|
||||||
|
|
||||||
|
- path = g_strdup_printf("%s/qemufirmwaredata/%s", abs_srcdir, filename);
|
||||||
|
+ inpath = g_strdup_printf("%s/qemufirmwaredata/%s", abs_srcdir, filename);
|
||||||
|
+ outpath = g_strdup_printf("%s/qemufirmwaredata/out/%s", abs_srcdir, filename);
|
||||||
|
|
||||||
|
- if (!(fw = qemuFirmwareParse(path)))
|
||||||
|
+ if (!(fw = qemuFirmwareParse(inpath)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
- if (virFileReadAll(path,
|
||||||
|
- 1024 * 1024, /* 1MiB */
|
||||||
|
- &buf) < 0)
|
||||||
|
- return -1;
|
||||||
|
+ if (virFileExists(outpath)) {
|
||||||
|
+ if (virFileReadAll(outpath,
|
||||||
|
+ 1024 * 1024, /* 1MiB */
|
||||||
|
+ &buf) < 0)
|
||||||
|
+ return -1;
|
||||||
|
+ } else {
|
||||||
|
+ if (virFileReadAll(inpath,
|
||||||
|
+ 1024 * 1024, /* 1MiB */
|
||||||
|
+ &buf) < 0)
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!(json = virJSONValueFromString(buf)))
|
||||||
|
return -1;
|
||||||
|
@@ -60,7 +69,9 @@ testFWPrecedence(const void *opaque G_GNUC_UNUSED)
|
||||||
|
const char *expected[] = {
|
||||||
|
PREFIX "/share/qemu/firmware/40-bios.json",
|
||||||
|
SYSCONFDIR "/qemu/firmware/40-ovmf-sb-keys.json",
|
||||||
|
+ PREFIX "/share/qemu/firmware/45-ovmf-sev-stateless.json",
|
||||||
|
PREFIX "/share/qemu/firmware/50-ovmf-sb-keys.json",
|
||||||
|
+ PREFIX "/share/qemu/firmware/55-ovmf-sb-combined.json",
|
||||||
|
PREFIX "/share/qemu/firmware/61-ovmf.json",
|
||||||
|
PREFIX "/share/qemu/firmware/70-aavmf.json",
|
||||||
|
NULL
|
||||||
|
@@ -218,7 +229,9 @@ mymain(void)
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
DO_PARSE_TEST("usr/share/qemu/firmware/40-bios.json");
|
||||||
|
+ DO_PARSE_TEST("usr/share/qemu/firmware/45-ovmf-sev-stateless.json");
|
||||||
|
DO_PARSE_TEST("usr/share/qemu/firmware/50-ovmf-sb-keys.json");
|
||||||
|
+ DO_PARSE_TEST("usr/share/qemu/firmware/55-ovmf-sb-combined.json");
|
||||||
|
DO_PARSE_TEST("usr/share/qemu/firmware/60-ovmf-sb.json");
|
||||||
|
DO_PARSE_TEST("usr/share/qemu/firmware/61-ovmf.json");
|
||||||
|
DO_PARSE_TEST("usr/share/qemu/firmware/70-aavmf.json");
|
||||||
|
@@ -250,6 +263,8 @@ mymain(void)
|
||||||
|
DO_SUPPORTED_TEST("pc-q35-3.1", VIR_ARCH_X86_64, true,
|
||||||
|
"/usr/share/seabios/bios-256k.bin:NULL:"
|
||||||
|
"/usr/share/OVMF/OVMF_CODE.secboot.fd:/usr/share/OVMF/OVMF_VARS.secboot.fd:"
|
||||||
|
+ "/usr/share/OVMF/OVMF.sev.fd:NULL:"
|
||||||
|
+ "/usr/share/OVMF/OVMF.secboot.fd:NULL:"
|
||||||
|
"/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd",
|
||||||
|
VIR_DOMAIN_OS_DEF_FIRMWARE_BIOS,
|
||||||
|
VIR_DOMAIN_OS_DEF_FIRMWARE_EFI);
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -0,0 +1,186 @@
|
|||||||
|
From 563e17f59f088d4ba76e7a95ea8958792ae165e2 Mon Sep 17 00:00:00 2001
|
||||||
|
Message-Id: <563e17f59f088d4ba76e7a95ea8958792ae165e2@dist-git>
|
||||||
|
From: Jonathon Jongsma <jjongsma@redhat.com>
|
||||||
|
Date: Tue, 1 Mar 2022 16:55:21 -0600
|
||||||
|
Subject: [PATCH] qemu: support multiqueue for vdpa net device
|
||||||
|
|
||||||
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2024406
|
||||||
|
|
||||||
|
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
|
||||||
|
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
|
||||||
|
|
||||||
|
(cherry picked from commit a5e659f071ae5f5fc9aadb46ad7c31736425f8cf)
|
||||||
|
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
|
||||||
|
---
|
||||||
|
src/qemu/qemu_domain.c | 3 +-
|
||||||
|
.../net-vdpa-multiqueue.x86_64-latest.args | 36 +++++++++++++++++++
|
||||||
|
.../qemuxml2argvdata/net-vdpa-multiqueue.xml | 30 ++++++++++++++++
|
||||||
|
tests/qemuxml2argvtest.c | 1 +
|
||||||
|
.../net-vdpa-multiqueue.xml | 36 +++++++++++++++++++
|
||||||
|
tests/qemuxml2xmltest.c | 1 +
|
||||||
|
6 files changed, 106 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 tests/qemuxml2argvdata/net-vdpa-multiqueue.x86_64-latest.args
|
||||||
|
create mode 100644 tests/qemuxml2argvdata/net-vdpa-multiqueue.xml
|
||||||
|
create mode 100644 tests/qemuxml2xmloutdata/net-vdpa-multiqueue.xml
|
||||||
|
|
||||||
|
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
||||||
|
index a8401bac30..68052769af 100644
|
||||||
|
--- a/src/qemu/qemu_domain.c
|
||||||
|
+++ b/src/qemu/qemu_domain.c
|
||||||
|
@@ -4511,7 +4511,8 @@ qemuDomainValidateActualNetDef(const virDomainNetDef *net,
|
||||||
|
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
|
||||||
|
actualType == VIR_DOMAIN_NET_TYPE_DIRECT ||
|
||||||
|
actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
|
||||||
|
- actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)) {
|
||||||
|
+ actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER ||
|
||||||
|
+ actualType == VIR_DOMAIN_NET_TYPE_VDPA)) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("interface %s - multiqueue is not supported for network interfaces of type %s"),
|
||||||
|
macstr, virDomainNetTypeToString(actualType));
|
||||||
|
diff --git a/tests/qemuxml2argvdata/net-vdpa-multiqueue.x86_64-latest.args b/tests/qemuxml2argvdata/net-vdpa-multiqueue.x86_64-latest.args
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..61ba85a847
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/qemuxml2argvdata/net-vdpa-multiqueue.x86_64-latest.args
|
||||||
|
@@ -0,0 +1,36 @@
|
||||||
|
+LC_ALL=C \
|
||||||
|
+PATH=/bin \
|
||||||
|
+HOME=/tmp/lib/domain--1-QEMUGuest1 \
|
||||||
|
+USER=test \
|
||||||
|
+LOGNAME=test \
|
||||||
|
+XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
|
||||||
|
+XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
|
||||||
|
+XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
|
||||||
|
+/usr/bin/qemu-system-x86_64 \
|
||||||
|
+-name guest=QEMUGuest1,debug-threads=on \
|
||||||
|
+-S \
|
||||||
|
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \
|
||||||
|
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram \
|
||||||
|
+-accel tcg \
|
||||||
|
+-cpu qemu64 \
|
||||||
|
+-m 214 \
|
||||||
|
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
|
||||||
|
+-overcommit mem-lock=off \
|
||||||
|
+-smp 1,sockets=1,cores=1,threads=1 \
|
||||||
|
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
|
||||||
|
+-display none \
|
||||||
|
+-no-user-config \
|
||||||
|
+-nodefaults \
|
||||||
|
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
|
||||||
|
+-mon chardev=charmonitor,id=monitor,mode=control \
|
||||||
|
+-rtc base=utc \
|
||||||
|
+-no-shutdown \
|
||||||
|
+-no-acpi \
|
||||||
|
+-boot strict=on \
|
||||||
|
+-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
|
||||||
|
+-add-fd set=0,fd=1732,opaque=/dev/vhost-vdpa-0 \
|
||||||
|
+-netdev vhost-vdpa,vhostdev=/dev/fdset/0,id=hostnet0 \
|
||||||
|
+-device virtio-net-pci,mq=on,vectors=6,netdev=hostnet0,id=net0,mac=52:54:00:95:db:c0,bus=pci.0,addr=0x2 \
|
||||||
|
+-audiodev '{"id":"audio1","driver":"none"}' \
|
||||||
|
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
|
||||||
|
+-msg timestamp=on
|
||||||
|
diff --git a/tests/qemuxml2argvdata/net-vdpa-multiqueue.xml b/tests/qemuxml2argvdata/net-vdpa-multiqueue.xml
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..6e369c1916
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/qemuxml2argvdata/net-vdpa-multiqueue.xml
|
||||||
|
@@ -0,0 +1,30 @@
|
||||||
|
+<domain type='qemu'>
|
||||||
|
+ <name>QEMUGuest1</name>
|
||||||
|
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
+ <memory unit='KiB'>219136</memory>
|
||||||
|
+ <currentMemory unit='KiB'>219136</currentMemory>
|
||||||
|
+ <vcpu placement='static'>1</vcpu>
|
||||||
|
+ <os>
|
||||||
|
+ <type arch='x86_64' machine='pc'>hvm</type>
|
||||||
|
+ <boot dev='hd'/>
|
||||||
|
+ </os>
|
||||||
|
+ <clock offset='utc'/>
|
||||||
|
+ <on_poweroff>destroy</on_poweroff>
|
||||||
|
+ <on_reboot>restart</on_reboot>
|
||||||
|
+ <on_crash>destroy</on_crash>
|
||||||
|
+ <devices>
|
||||||
|
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||||
|
+ <controller type='usb' index='0'/>
|
||||||
|
+ <controller type='ide' index='0'/>
|
||||||
|
+ <controller type='pci' index='0' model='pci-root'/>
|
||||||
|
+ <interface type='vdpa'>
|
||||||
|
+ <mac address='52:54:00:95:db:c0'/>
|
||||||
|
+ <source dev='/dev/vhost-vdpa-0'/>
|
||||||
|
+ <model type='virtio'/>
|
||||||
|
+ <driver queues='2'/>
|
||||||
|
+ </interface>
|
||||||
|
+ <input type='mouse' bus='ps2'/>
|
||||||
|
+ <input type='keyboard' bus='ps2'/>
|
||||||
|
+ <memballoon model='none'/>
|
||||||
|
+ </devices>
|
||||||
|
+</domain>
|
||||||
|
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
|
||||||
|
index cc67d806e4..1abb5d0124 100644
|
||||||
|
--- a/tests/qemuxml2argvtest.c
|
||||||
|
+++ b/tests/qemuxml2argvtest.c
|
||||||
|
@@ -1652,6 +1652,7 @@ mymain(void)
|
||||||
|
DO_TEST_FAILURE("net-hostdev-fail",
|
||||||
|
QEMU_CAPS_DEVICE_VFIO_PCI);
|
||||||
|
DO_TEST_CAPS_LATEST("net-vdpa");
|
||||||
|
+ DO_TEST_CAPS_LATEST("net-vdpa-multiqueue");
|
||||||
|
|
||||||
|
DO_TEST("hostdev-pci-multifunction",
|
||||||
|
QEMU_CAPS_KVM,
|
||||||
|
diff --git a/tests/qemuxml2xmloutdata/net-vdpa-multiqueue.xml b/tests/qemuxml2xmloutdata/net-vdpa-multiqueue.xml
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..0876d5df62
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/qemuxml2xmloutdata/net-vdpa-multiqueue.xml
|
||||||
|
@@ -0,0 +1,36 @@
|
||||||
|
+<domain type='qemu'>
|
||||||
|
+ <name>QEMUGuest1</name>
|
||||||
|
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
+ <memory unit='KiB'>219136</memory>
|
||||||
|
+ <currentMemory unit='KiB'>219136</currentMemory>
|
||||||
|
+ <vcpu placement='static'>1</vcpu>
|
||||||
|
+ <os>
|
||||||
|
+ <type arch='x86_64' machine='pc'>hvm</type>
|
||||||
|
+ <boot dev='hd'/>
|
||||||
|
+ </os>
|
||||||
|
+ <clock offset='utc'/>
|
||||||
|
+ <on_poweroff>destroy</on_poweroff>
|
||||||
|
+ <on_reboot>restart</on_reboot>
|
||||||
|
+ <on_crash>destroy</on_crash>
|
||||||
|
+ <devices>
|
||||||
|
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||||
|
+ <controller type='usb' index='0'>
|
||||||
|
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
|
||||||
|
+ </controller>
|
||||||
|
+ <controller type='ide' index='0'>
|
||||||
|
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
|
||||||
|
+ </controller>
|
||||||
|
+ <controller type='pci' index='0' model='pci-root'/>
|
||||||
|
+ <interface type='vdpa'>
|
||||||
|
+ <mac address='52:54:00:95:db:c0'/>
|
||||||
|
+ <source dev='/dev/vhost-vdpa-0'/>
|
||||||
|
+ <model type='virtio'/>
|
||||||
|
+ <driver queues='2'/>
|
||||||
|
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||||
|
+ </interface>
|
||||||
|
+ <input type='mouse' bus='ps2'/>
|
||||||
|
+ <input type='keyboard' bus='ps2'/>
|
||||||
|
+ <audio id='1' type='none'/>
|
||||||
|
+ <memballoon model='none'/>
|
||||||
|
+ </devices>
|
||||||
|
+</domain>
|
||||||
|
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
|
||||||
|
index fb438269b9..772586cf19 100644
|
||||||
|
--- a/tests/qemuxml2xmltest.c
|
||||||
|
+++ b/tests/qemuxml2xmltest.c
|
||||||
|
@@ -461,6 +461,7 @@ mymain(void)
|
||||||
|
DO_TEST_NOCAPS("net-coalesce");
|
||||||
|
DO_TEST_NOCAPS("net-many-models");
|
||||||
|
DO_TEST("net-vdpa", QEMU_CAPS_NETDEV_VHOST_VDPA);
|
||||||
|
+ DO_TEST("net-vdpa-multiqueue", QEMU_CAPS_NETDEV_VHOST_VDPA);
|
||||||
|
|
||||||
|
DO_TEST_NOCAPS("serial-tcp-tlsx509-chardev");
|
||||||
|
DO_TEST_NOCAPS("serial-tcp-tlsx509-chardev-notls");
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
71
SOURCES/libvirt-util-Fix-machined-servicename.patch
Normal file
71
SOURCES/libvirt-util-Fix-machined-servicename.patch
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
From f38b129e38b73cb20a2d858de7b593d09380e548 Mon Sep 17 00:00:00 2001
|
||||||
|
Message-Id: <f38b129e38b73cb20a2d858de7b593d09380e548@dist-git>
|
||||||
|
From: Martin Kletzander <mkletzan@redhat.com>
|
||||||
|
Date: Wed, 23 Feb 2022 10:45:28 +0100
|
||||||
|
Subject: [PATCH] util: Fix machined servicename
|
||||||
|
|
||||||
|
Commit 4e42686adef8 wrongly assumed how g_variant_new_parsed() works and broke
|
||||||
|
starting of domains on systems with systemd (machined).
|
||||||
|
|
||||||
|
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||||
|
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
||||||
|
(cherry picked from commit a64e666a112d4d6299d1b73704d176283bc42b19)
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1868537
|
||||||
|
|
||||||
|
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||||
|
---
|
||||||
|
src/util/virsystemd.c | 12 ++++++------
|
||||||
|
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
|
||||||
|
index f156c2f39a..a8af80c495 100644
|
||||||
|
--- a/src/util/virsystemd.c
|
||||||
|
+++ b/src/util/virsystemd.c
|
||||||
|
@@ -360,6 +360,7 @@ int virSystemdCreateMachine(const char *name,
|
||||||
|
g_autofree char *creatorname = NULL;
|
||||||
|
g_autofree char *slicename = NULL;
|
||||||
|
g_autofree char *scopename = NULL;
|
||||||
|
+ g_autofree char *servicename = NULL;
|
||||||
|
static int hasCreateWithNetwork = 1;
|
||||||
|
|
||||||
|
if ((rc = virSystemdHasMachined()) < 0)
|
||||||
|
@@ -369,6 +370,7 @@ int virSystemdCreateMachine(const char *name,
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
creatorname = g_strdup_printf("libvirt-%s", drivername);
|
||||||
|
+ servicename = g_strdup_printf("virt%sd.service", drivername);
|
||||||
|
|
||||||
|
if (partition) {
|
||||||
|
if (!(slicename = virSystemdMakeSliceName(partition)))
|
||||||
|
@@ -440,11 +442,10 @@ int virSystemdCreateMachine(const char *name,
|
||||||
|
gnicindexes = g_variant_new_fixed_array(G_VARIANT_TYPE("i"),
|
||||||
|
nicindexes, nnicindexes, sizeof(int));
|
||||||
|
gprops = g_variant_new_parsed("[('Slice', <%s>),"
|
||||||
|
- " ('After', <['libvirtd.service']>),"
|
||||||
|
- " ('After', <['virt%sd.service']>),"
|
||||||
|
+ " ('After', <['libvirtd.service', %s]>),"
|
||||||
|
" ('Before', <['virt-guest-shutdown.target']>)]",
|
||||||
|
slicename,
|
||||||
|
- drivername);
|
||||||
|
+ servicename);
|
||||||
|
message = g_variant_new("(s@ayssus@ai@a(sv))",
|
||||||
|
name,
|
||||||
|
guuid,
|
||||||
|
@@ -490,11 +491,10 @@ int virSystemdCreateMachine(const char *name,
|
||||||
|
guuid = g_variant_new_fixed_array(G_VARIANT_TYPE("y"),
|
||||||
|
uuid, 16, sizeof(unsigned char));
|
||||||
|
gprops = g_variant_new_parsed("[('Slice', <%s>),"
|
||||||
|
- " ('After', <['libvirtd.service']>),"
|
||||||
|
- " ('After', <['virt%sd.service']>),"
|
||||||
|
+ " ('After', <['libvirtd.service', %s]>),"
|
||||||
|
" ('Before', <['virt-guest-shutdown.target']>)]",
|
||||||
|
slicename,
|
||||||
|
- drivername);
|
||||||
|
+ servicename);
|
||||||
|
message = g_variant_new("(s@ayssus@a(sv))",
|
||||||
|
name,
|
||||||
|
guuid,
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -228,7 +228,7 @@
|
|||||||
Summary: Library providing a simple virtualization API
|
Summary: Library providing a simple virtualization API
|
||||||
Name: libvirt
|
Name: libvirt
|
||||||
Version: 8.0.0
|
Version: 8.0.0
|
||||||
Release: 4%{?dist}%{?extra_release}
|
Release: 7%{?dist}%{?extra_release}
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
URL: https://libvirt.org/
|
URL: https://libvirt.org/
|
||||||
|
|
||||||
@ -247,6 +247,12 @@ Patch6: libvirt-Revert-report-error-when-virProcessGetStatInfo-is-unable-to-pars
|
|||||||
Patch7: libvirt-qemuDomainSetupDisk-Initialize-targetPaths.patch
|
Patch7: libvirt-qemuDomainSetupDisk-Initialize-targetPaths.patch
|
||||||
Patch8: libvirt-qemu_command-Generate-memory-only-after-controllers.patch
|
Patch8: libvirt-qemu_command-Generate-memory-only-after-controllers.patch
|
||||||
Patch9: libvirt-qemu-Validate-domain-definition-even-on-migration.patch
|
Patch9: libvirt-qemu-Validate-domain-definition-even-on-migration.patch
|
||||||
|
Patch10: libvirt-Make-systemd-unit-ordering-more-robust.patch
|
||||||
|
Patch11: libvirt-util-Fix-machined-servicename.patch
|
||||||
|
Patch12: libvirt-qemu-support-firmware-descriptor-flash-mode-for-optional-NVRAM.patch
|
||||||
|
Patch13: libvirt-nwfilter-hold-filter-update-lock-when-creating-deleting-bindings.patch
|
||||||
|
Patch14: libvirt-qemu-lxc-remove-use-to-nwfilter-update-lock.patch
|
||||||
|
Patch15: libvirt-qemu-support-multiqueue-for-vdpa-net-device.patch
|
||||||
|
|
||||||
Requires: libvirt-daemon = %{version}-%{release}
|
Requires: libvirt-daemon = %{version}-%{release}
|
||||||
Requires: libvirt-daemon-config-network = %{version}-%{release}
|
Requires: libvirt-daemon-config-network = %{version}-%{release}
|
||||||
@ -2138,6 +2144,18 @@ exit 0
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Mar 18 2022 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-7
|
||||||
|
- nwfilter: hold filter update lock when creating/deleting bindings (rhbz#2044379)
|
||||||
|
- qemu,lxc: remove use to nwfilter update lock (rhbz#2044379)
|
||||||
|
- qemu: support multiqueue for vdpa net device (rhbz#2024406)
|
||||||
|
|
||||||
|
* Thu Mar 3 2022 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-6
|
||||||
|
- qemu: support firmware descriptor flash 'mode' for optional NVRAM (rhbz#2057769)
|
||||||
|
|
||||||
|
* Thu Feb 24 2022 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-5
|
||||||
|
- Make systemd unit ordering more robust (rhbz#1868537)
|
||||||
|
- util: Fix machined servicename (rhbz#1868537)
|
||||||
|
|
||||||
* Thu Feb 10 2022 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-4
|
* Thu Feb 10 2022 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-4
|
||||||
- qemu_command: Generate memory only after controllers (rhbz#2047271)
|
- qemu_command: Generate memory only after controllers (rhbz#2047271)
|
||||||
- qemu: Validate domain definition even on migration (rhbz#2048435)
|
- qemu: Validate domain definition even on migration (rhbz#2048435)
|
||||||
|
Loading…
Reference in New Issue
Block a user