libvirt-11.10.0-5.el9

- qemublocktest: Iterate all nodenames in 'testQemuDetectBitmaps' (RHEL-145770)
- qemu: monitor: Detect list of bitmaps from 'qcow2' format specific data (RHEL-145770)
- qemuMigrationDstPrepareAnyBlockDirtyBitmaps: Fix check for existing bitmaps (RHEL-145770)
- qemu: migration: Always offer block dirty bitmaps during migration (RHEL-145770)
- qemuMigrationDstPrepareAnyBlockDirtyBitmaps: Always consider offered bitmaps (RHEL-145770)

Resolves: RHEL-145770
This commit is contained in:
Jiri Denemark 2026-02-04 12:08:43 +01:00
parent 83aad8ea81
commit ad543367fd
6 changed files with 674 additions and 1 deletions

View File

@ -0,0 +1,147 @@
From d2c2c9bf6cb12cd1bd02763410744c8322c36bdc Mon Sep 17 00:00:00 2001
Message-ID: <d2c2c9bf6cb12cd1bd02763410744c8322c36bdc.1770203323.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 27 Jan 2026 17:00:10 +0100
Subject: [PATCH] qemu: migration: Always offer block dirty bitmaps during
migration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Until now block dirty bitmaps were offered to destination only if
non-shared storage migration was enabled.
Upcoming patches will want to support it also in cases when storage is
shared but the destination has a qcow2 overlay using the 'data_file'
feature where the qcow2 overlay is not actually shared.
To support that we'll now always offer bitmaps for migration. The
destination can then decide (using existing logic) to pick only the
ones that are not present in the image on destination, which is how
it was supposed to work even now.
The patch removes all the flag checks and simply offers bitmaps in any
case. The overhead incurred by this is one 'query-named-block-nodes'
call to qemu.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit a4f610ff3fe190058f18baea18b095d0bc69441b)
https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8]
---
src/qemu/qemu_migration.c | 28 +++++++---------------------
1 file changed, 7 insertions(+), 21 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 723e131c98..755b9a5e1a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2580,16 +2580,13 @@ qemuMigrationAnyConnectionClosed(virDomainObj *vm,
* qemuMigrationSrcBeginPhaseBlockDirtyBitmaps:
* @mig: migration cookie struct
* @vm: domain object
- * @migrate_disks: disks which are being migrated
- * @nmigrage_disks: number of @migrate_disks
*
* Enumerates block dirty bitmaps on disks which will undergo storage migration
* and fills them into @mig to be offered to the destination.
*/
static int
qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(qemuMigrationCookie *mig,
- virDomainObj *vm,
- const char **migrate_disks)
+ virDomainObj *vm)
{
GSList *disks = NULL;
@@ -2611,9 +2608,6 @@ qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(qemuMigrationCookie *mig,
if (!nodedata)
continue;
- if (!qemuMigrationAnyCopyDisk(diskdef, migrate_disks))
- continue;
-
for (j = 0; j < nodedata->nbitmaps; j++) {
qemuMigrationBlockDirtyBitmapsDiskBitmap *bitmap;
@@ -2680,7 +2674,6 @@ qemuMigrationSrcBeginXML(virDomainObj *vm,
char **cookieout,
int *cookieoutlen,
unsigned int cookieFlags,
- const char **migrate_disks,
unsigned int flags)
{
qemuDomainObjPrivate *priv = vm->privateData;
@@ -2696,8 +2689,7 @@ qemuMigrationSrcBeginXML(virDomainObj *vm,
if (!(mig = qemuMigrationCookieNew(vm->def, priv->origname)))
return NULL;
- if (cookieFlags & QEMU_MIGRATION_COOKIE_NBD &&
- qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm, migrate_disks) < 0)
+ if (qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm) < 0)
return NULL;
if (qemuMigrationCookieFormat(mig, driver, vm,
@@ -2879,8 +2871,7 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver,
return NULL;
return qemuMigrationSrcBeginXML(vm, xmlin,
- cookieout, cookieoutlen, cookieFlags,
- migrate_disks, flags);
+ cookieout, cookieoutlen, cookieFlags, flags);
}
@@ -2969,8 +2960,7 @@ qemuMigrationSrcBeginResume(virDomainObj *vm,
return NULL;
}
- return qemuMigrationSrcBeginXML(vm, xmlin,
- cookieout, cookieoutlen, 0, NULL, flags);
+ return qemuMigrationSrcBeginXML(vm, xmlin, cookieout, cookieoutlen, 0, flags);
}
@@ -4752,7 +4742,6 @@ qemuMigrationSrcRunPrepareBlockDirtyBitmaps(virDomainObj *vm,
/* For VIR_MIGRATE_NON_SHARED_INC we can migrate the bitmaps directly,
* otherwise we must create merged bitmaps from the whole chain */
-
if (!(flags & VIR_MIGRATE_NON_SHARED_INC) &&
qemuMigrationSrcRunPrepareBlockDirtyBitmapsMerge(vm, mig) < 0)
return -1;
@@ -4943,7 +4932,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
VIR_AUTOCLOSE fd = -1;
unsigned long restore_max_bandwidth = priv->migMaxBandwidth;
virErrorPtr orig_err = NULL;
- unsigned int cookieFlags = 0;
+ unsigned int cookieFlags = QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS;
bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
bool storageMigration = flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC);
bool cancel = false;
@@ -4967,10 +4956,8 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
storageMigration = qemuMigrationHasAnyStorageMigrationDisks(vm->def,
migrate_disks);
- if (storageMigration) {
+ if (storageMigration)
cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
- cookieFlags |= QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS;
- }
if (virLockManagerPluginUsesState(driver->lockManager) &&
!cookieout) {
@@ -5004,8 +4991,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
cookiein, cookieinlen,
cookieFlags |
QEMU_MIGRATION_COOKIE_GRAPHICS |
- QEMU_MIGRATION_COOKIE_CAPS |
- QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS);
+ QEMU_MIGRATION_COOKIE_CAPS);
if (!mig)
goto error;
--
2.52.0

View File

@ -0,0 +1,173 @@
From 94768f63a02ec5e9f25cb5db28b38ed6950c1df0 Mon Sep 17 00:00:00 2001
Message-ID: <94768f63a02ec5e9f25cb5db28b38ed6950c1df0.1770203323.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 27 Jan 2026 20:07:32 +0100
Subject: [PATCH] qemu: monitor: Detect list of bitmaps from 'qcow2' format
specific data
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We currently probe dirty block tracking bitmaps by looking at the loaded
ones ('dirty-bitmaps'). Unfortunately those may not yet be populated on
incoming migration when the image was not yet activated, but we need to
know which ones are stored in the image so that we don't migrate those
explicitly, which would fail.
Load the list of bitmaps in a qcow2 image from the format specific data,
which is already loaded at that point.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit b2fe3465de1db033e436f38fdd24648c8c884a3d)
https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8]
---
src/qemu/qemu_monitor.h | 4 ++++
src/qemu/qemu_monitor_json.c | 17 +++++++++++++++++
tests/qemublocktest.c | 11 +++++++++++
tests/qemublocktestdata/bitmap/snapshots.out | 5 +++++
tests/qemublocktestdata/bitmap/synthetic.out | 4 ++++
5 files changed, 41 insertions(+)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d096f474c1..041aa7bc12 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -893,8 +893,12 @@ struct _qemuBlockNamedNodeData {
unsigned long long capacity;
unsigned long long physical;
+ /* Information about change block tracking bitmaps which are active and loaded */
qemuBlockNamedNodeDataBitmap **bitmaps;
size_t nbitmaps;
+ /* With qcow2 we have also a separate list of bitmaps present in the image
+ * but not yet activated, which happens when starting qemu during migration */
+ char **qcow2bitmaps;
/* hash table indexed by snapshot name containing data about snapshots
* (qemuBlockNamedNodeDataSnapshot) */
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 494d7ef515..401a28ff9a 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2730,6 +2730,7 @@ qemuMonitorJSONBlockNamedNodeDataFree(qemuBlockNamedNodeData *data)
qemuMonitorJSONBlockNamedNodeDataBitmapFree(data->bitmaps[i]);
g_clear_pointer(&data->snapshots, g_hash_table_unref);
g_free(data->bitmaps);
+ g_strfreev(data->qcow2bitmaps);
g_free(data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuBlockNamedNodeData, qemuMonitorJSONBlockNamedNodeDataFree);
@@ -2854,6 +2855,9 @@ qemuMonitorJSONBlockGetNamedNodeDataWorker(size_t pos G_GNUC_UNUSED,
virJSONValue *qcow2props = virJSONValueObjectGetObject(format_specific, "data");
if (qcow2props) {
+ virJSONValue *bmp;
+ size_t nbmp;
+
if (STREQ_NULLABLE(virJSONValueObjectGetString(qcow2props, "compat"), "0.10"))
ent->qcow2v2 = true;
@@ -2862,6 +2866,19 @@ qemuMonitorJSONBlockGetNamedNodeDataWorker(size_t pos G_GNUC_UNUSED,
ignore_value(virJSONValueObjectGetBoolean(qcow2props, "data-file-raw",
&ent->qcow2dataFileRaw));
+
+ if ((bmp = virJSONValueObjectGetArray(qcow2props, "bitmaps")) &&
+ ((nbmp = virJSONValueArraySize(bmp)) > 0)) {
+ size_t i;
+
+ ent->qcow2bitmaps = g_new0(char *, nbmp + 1);
+
+ for (i = 0; i < nbmp; i++) {
+ virJSONValue *b = virJSONValueArrayGet(bmp, i);
+
+ ent->qcow2bitmaps[i] = g_strdup(virJSONValueObjectGetString(b, "name"));
+ }
+ }
}
}
diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
index 51d9268cdd..18ec90edf5 100644
--- a/tests/qemublocktest.c
+++ b/tests/qemublocktest.c
@@ -600,6 +600,17 @@ testQemuDetectBitmapsWorker(void *payload,
bitmap->granularity, bitmap->dirtybytes);
}
+ if (data->qcow2bitmaps) {
+ char **b;
+
+ virBufferAddLit(buf, "qcow2 bitmaps:");
+
+ for (b = data->qcow2bitmaps; *b; b++)
+ virBufferAsprintf(buf, " %s", *b);
+
+ virBufferAddLit(buf, "\n");
+ }
+
if (data->snapshots) {
g_autofree virHashKeyValuePair *snaps = virHashGetItems(data->snapshots, NULL, true);
virHashKeyValuePair *n;
diff --git a/tests/qemublocktestdata/bitmap/snapshots.out b/tests/qemublocktestdata/bitmap/snapshots.out
index 29c586be7e..dedd77465c 100644
--- a/tests/qemublocktestdata/bitmap/snapshots.out
+++ b/tests/qemublocktestdata/bitmap/snapshots.out
@@ -4,21 +4,26 @@ libvirt-1-format:
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: current c b a d
libvirt-1-storage:
libvirt-2-format:
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: d a b c
libvirt-2-storage:
libvirt-3-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: c b a
libvirt-3-storage:
libvirt-4-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: a
libvirt-4-storage:
libvirt-5-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: a
libvirt-5-storage:
diff --git a/tests/qemublocktestdata/bitmap/synthetic.out b/tests/qemublocktestdata/bitmap/synthetic.out
index 2f4ae2b217..0a47a90107 100644
--- a/tests/qemublocktestdata/bitmap/synthetic.out
+++ b/tests/qemublocktestdata/bitmap/synthetic.out
@@ -6,17 +6,21 @@ libvirt-1-format:
top-inactive: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
top-transient: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
top-transient-inactive: record:0 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: current
libvirt-1-storage:
libvirt-2-format:
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: d
libvirt-2-storage:
libvirt-3-format:
b: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: c b
libvirt-3-storage:
libvirt-4-format:
libvirt-4-storage:
libvirt-5-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ qcow2 bitmaps: a
libvirt-5-storage:
--
2.52.0

View File

@ -0,0 +1,98 @@
From 73e383336be99821e588ef0fb8a6da8ad9fa7414 Mon Sep 17 00:00:00 2001
Message-ID: <73e383336be99821e588ef0fb8a6da8ad9fa7414.1770203323.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 27 Jan 2026 17:28:48 +0100
Subject: [PATCH] qemuMigrationDstPrepareAnyBlockDirtyBitmaps: Always consider
offered bitmaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Consider bitmaps for incoming migration regardless of non-shared storage
flag.
When bitmaps are offered from the source, consult the local image if the
bitmap is present and if not accept migration. Migration of bitmaps
which exist in the qcow2 metadata is skipped because qemu rejects such
setup (although handles it correctly in case of shared storage setup;
see below).
This allows bitmap propagation for cases when the qcow2 image is not
actually shared between destinations but the data is (using the
data_file feature).
At the same time this preserves existing bitmap handling semantics for
other cases. Specifically qemu, in case of shared storage properly
propagates the bitmap which was already recorded in the qcow2 metadata
on disk even if libvirt doesn't instruct migration, yet tolerates
migration instruction if the file is not yet recorded in the on-disk
metadata. In both cases the contents are preserved correctly.
When storage is not shared (which includes even cases when we migrate
it via NBD) it's expected that the bitmaps don't exist on the
destination and thus all will be picked for migration. We can also
infer that this wasn't ever a problem by the fact that the code skipping
migration of existing bitmaps was broken until recently, and qemu
would refuse such config.
I've tested all the above scenarios including verifying that the
resulting bitmaps capture dirtied regions before and after migration.
For testing this the following command is useful:
virsh qemu-monitor-command --domain DOMNAME --hmp 'qemu-io -d /machine/peripheral/virtio-disk0/virtio-backend "write -P 0xcc 4M 1M"'
Which simulates a write from the guest side without the need to interact
with the guest OS.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit bf34b90bb4e39b3a2fd22a5531f5ea5a95681015)
https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8]
---
src/qemu/qemu_migration.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 755b9a5e1a..2a4df1191d 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3183,7 +3183,6 @@ qemuMigrationDstPrepare(virQEMUDriver *driver,
* @vm: domain object
* @mig: migration cookie
* @migParams: migration parameters
- * @flags: migration flags
*
* Checks whether block dirty bitmaps offered by the migration source are
* to be migrated (e.g. they don't exist, the destination is compatible etc)
@@ -3194,16 +3193,13 @@ qemuMigrationDstPrepare(virQEMUDriver *driver,
static int
qemuMigrationDstPrepareAnyBlockDirtyBitmaps(virDomainObj *vm,
qemuMigrationCookie *mig,
- qemuMigrationParams *migParams,
- unsigned int flags)
+ qemuMigrationParams *migParams)
{
g_autoptr(virJSONValue) mapping = NULL;
g_autoptr(GHashTable) blockNamedNodeData = NULL;
GSList *nextdisk;
- if (!mig->nbd ||
- !mig->blockDirtyBitmaps ||
- !(flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)))
+ if (!mig->blockDirtyBitmaps)
return 0;
if (qemuMigrationCookieBlockDirtyBitmapsMatchDisks(vm->def, mig->blockDirtyBitmaps) < 0)
@@ -3350,7 +3346,7 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver,
goto error;
}
- if (qemuMigrationDstPrepareAnyBlockDirtyBitmaps(vm, mig, migParams, flags) < 0)
+ if (qemuMigrationDstPrepareAnyBlockDirtyBitmaps(vm, mig, migParams) < 0)
goto error;
if (qemuMigrationParamsCheck(vm, VIR_ASYNC_JOB_MIGRATION_IN, migParams,
--
2.52.0

View File

@ -0,0 +1,68 @@
From eb094db2b8112409813105d4dcc313e8ea45ee1e Mon Sep 17 00:00:00 2001
Message-ID: <eb094db2b8112409813105d4dcc313e8ea45ee1e.1770203323.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 27 Jan 2026 19:22:08 +0100
Subject: [PATCH] qemuMigrationDstPrepareAnyBlockDirtyBitmaps: Fix check for
existing bitmaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On incoming migration qemu doesn't load bitmaps into memory (which makes
them available under the 'dirty-bitmaps' field which we parse as the
'bitmaps' array in 'qemuBlockNamedNodeData') until after actually
resuming CPUs, thus the check for existing bitmaps never actually
worked.
We need to check the 'qcow2bitmaps' field instead which is populated
from the qcow2 headers prior to activating the image.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 0c75fc1747f039bf878ceab69cf12482ebb14095)
https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8]
---
src/qemu/qemu_migration.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 9059f9aa3a..723e131c98 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3227,6 +3227,8 @@ qemuMigrationDstPrepareAnyBlockDirtyBitmaps(virDomainObj *vm,
qemuBlockNamedNodeData *nodedata;
GSList *nextbitmap;
+ VIR_DEBUG("offer migrate bitmaps for '%s'", disk->target);
+
if (!(nodedata = virHashLookup(blockNamedNodeData, disk->nodename))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to find data for block node '%1$s'"),
@@ -3243,18 +3245,14 @@ qemuMigrationDstPrepareAnyBlockDirtyBitmaps(virDomainObj *vm,
for (nextbitmap = disk->bitmaps; nextbitmap; nextbitmap = nextbitmap->next) {
qemuMigrationBlockDirtyBitmapsDiskBitmap *bitmap = nextbitmap->data;
- size_t k;
/* don't migrate into existing bitmaps */
- for (k = 0; k < nodedata->nbitmaps; k++) {
- if (STREQ(bitmap->bitmapname, nodedata->bitmaps[k]->name)) {
- bitmap->skip = true;
- break;
- }
- }
+ if (nodedata->qcow2bitmaps)
+ bitmap->skip = g_strv_contains((const char **) nodedata->qcow2bitmaps, bitmap->bitmapname);
+
+ VIR_DEBUG("offer migrate bitmap '%s' disk '%s' -> skip: '%d'",
+ bitmap->bitmapname, disk->target, bitmap->skip);
- if (bitmap->skip)
- continue;
}
}
--
2.52.0

View File

@ -0,0 +1,175 @@
From 4930e34b488c6253e8cbb5ceb2988864f7b981a0 Mon Sep 17 00:00:00 2001
Message-ID: <4930e34b488c6253e8cbb5ceb2988864f7b981a0.1770203323.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 27 Jan 2026 22:49:09 +0100
Subject: [PATCH] qemublocktest: Iterate all nodenames in
'testQemuDetectBitmaps'
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Rather than looking for 30 specific nodenames (via a loop) iterate
everything in the hash table (in a sorted order). This simplifies the
code and provides more test outputs on previously-ignored nodenames.
The listing of internal snapshots in the output was also missing a
newline, which would now cause problems with multiple images reproted.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 71643c197e86a3adc792c0b2a378a245ae6c5756)
https://issues.redhat.com/browse/RHEL-145769 [rhel-10.2]
https://issues.redhat.com/browse/RHEL-145770 [rhel-9.8]
---
tests/qemublocktest.c | 24 +++++++------------
tests/qemublocktestdata/bitmap/basic.out | 1 +
tests/qemublocktestdata/bitmap/empty.out | 1 +
.../bitmap/snapshots-internal.out | 7 ++++++
tests/qemublocktestdata/bitmap/snapshots.out | 5 ++++
tests/qemublocktestdata/bitmap/synthetic.out | 5 ++++
6 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
index 47746207cc..51d9268cdd 100644
--- a/tests/qemublocktest.c
+++ b/tests/qemublocktest.c
@@ -575,17 +575,15 @@ testQemuImageCreate(const void *opaque)
static const char *bitmapDetectPrefix = "qemublocktestdata/bitmap/";
-static void
-testQemuDetectBitmapsWorker(GHashTable *nodedata,
+static int
+testQemuDetectBitmapsWorker(void *payload,
const char *nodename,
- virBuffer *buf)
+ void *opaque)
{
- qemuBlockNamedNodeData *data;
+ qemuBlockNamedNodeData *data = payload;
+ virBuffer *buf = opaque;
size_t i;
- if (!(data = virHashLookup(nodedata, nodename)))
- return;
-
virBufferAsprintf(buf, "%s:\n", nodename);
if (data->qcow2v2)
virBufferAddLit(buf, " qcow2 v2\n");
@@ -617,9 +615,12 @@ testQemuDetectBitmapsWorker(GHashTable *nodedata,
virBufferAsprintf(buf, " '%s'%s", (const char *) n->key, vms);
}
+
+ virBufferAddLit(buf, "\n");
}
virBufferAdjustIndent(buf, -1);
+ return 0;
}
@@ -632,7 +633,6 @@ testQemuDetectBitmaps(const void *opaque)
g_autofree char *actual = NULL;
g_autofree char *expectpath = NULL;
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
- size_t i;
expectpath = g_strdup_printf("%s/%s%s.out", abs_srcdir,
bitmapDetectPrefix, name);
@@ -646,13 +646,7 @@ testQemuDetectBitmaps(const void *opaque)
return -1;
}
- /* we detect for the first 30 nodenames for simplicity */
- for (i = 0; i < 30; i++) {
- g_autofree char *nodename = g_strdup_printf("libvirt-%zu-format", i);
-
- testQemuDetectBitmapsWorker(nodedata, nodename, &buf);
- }
-
+ virHashForEachSorted(nodedata, testQemuDetectBitmapsWorker, &buf);
actual = virBufferContentAndReset(&buf);
return virTestCompareToFile(actual, expectpath);
diff --git a/tests/qemublocktestdata/bitmap/basic.out b/tests/qemublocktestdata/bitmap/basic.out
index 5c4c35b3f0..b96ffe3d39 100644
--- a/tests/qemublocktestdata/bitmap/basic.out
+++ b/tests/qemublocktestdata/bitmap/basic.out
@@ -4,3 +4,4 @@ libvirt-1-format:
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-1-storage:
diff --git a/tests/qemublocktestdata/bitmap/empty.out b/tests/qemublocktestdata/bitmap/empty.out
index 3787cbd354..c9a5be4f07 100644
--- a/tests/qemublocktestdata/bitmap/empty.out
+++ b/tests/qemublocktestdata/bitmap/empty.out
@@ -1 +1,2 @@
libvirt-1-format:
+libvirt-1-storage:
diff --git a/tests/qemublocktestdata/bitmap/snapshots-internal.out b/tests/qemublocktestdata/bitmap/snapshots-internal.out
index dbb3cfded4..cf7bde96a5 100644
--- a/tests/qemublocktestdata/bitmap/snapshots-internal.out
+++ b/tests/qemublocktestdata/bitmap/snapshots-internal.out
@@ -1,2 +1,9 @@
libvirt-1-format:
internal snapshots: '1727868651'(*) '1727872064'(*)
+libvirt-1-storage:
+libvirt-2-storage:
+libvirt-pflash0-format:
+libvirt-pflash0-storage:
+libvirt-pflash1-format:
+ internal snapshots: '1727868651' '1727872064'
+libvirt-pflash1-storage:
diff --git a/tests/qemublocktestdata/bitmap/snapshots.out b/tests/qemublocktestdata/bitmap/snapshots.out
index 24ca27e4d8..29c586be7e 100644
--- a/tests/qemublocktestdata/bitmap/snapshots.out
+++ b/tests/qemublocktestdata/bitmap/snapshots.out
@@ -4,16 +4,21 @@ libvirt-1-format:
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-1-storage:
libvirt-2-format:
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-2-storage:
libvirt-3-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
c: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-3-storage:
libvirt-4-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-4-storage:
libvirt-5-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-5-storage:
diff --git a/tests/qemublocktestdata/bitmap/synthetic.out b/tests/qemublocktestdata/bitmap/synthetic.out
index 45423903a0..2f4ae2b217 100644
--- a/tests/qemublocktestdata/bitmap/synthetic.out
+++ b/tests/qemublocktestdata/bitmap/synthetic.out
@@ -6,12 +6,17 @@ libvirt-1-format:
top-inactive: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
top-transient: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
top-transient-inactive: record:0 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
+libvirt-1-storage:
libvirt-2-format:
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-2-storage:
libvirt-3-format:
b: record:1 busy:0 persist:0 inconsist:0 gran:65536 dirty:0
c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-3-storage:
libvirt-4-format:
+libvirt-4-storage:
libvirt-5-format:
a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+libvirt-5-storage:
--
2.52.0

View File

@ -294,7 +294,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 11.10.0
Release: 4%{?dist}%{?extra_release}
Release: 5%{?dist}%{?extra_release}
License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1
URL: https://libvirt.org/
@ -323,6 +323,11 @@ Patch18: libvirt-qemuSnapshotUpdateBackingStore-Remove-stale-comment.patch
Patch19: libvirt-qemuSnapshotDiskHasBackingDisk-Use-proper-max_depth-when-calling-virStorageSourceGetMetadata.patch
Patch20: libvirt-virDomainSnapshotDefAssignExternalNames-Improve-error-message.patch
Patch21: libvirt-qemuSnapshotUpdateBackingStore-Retry-as-curent-user-if-qemu-img-fails.patch
Patch22: libvirt-qemublocktest-Iterate-all-nodenames-in-testQemuDetectBitmaps.patch
Patch23: libvirt-qemu-monitor-Detect-list-of-bitmaps-from-qcow2-format-specific-data.patch
Patch24: libvirt-qemuMigrationDstPrepareAnyBlockDirtyBitmaps-Fix-check-for-existing-bitmaps.patch
Patch25: libvirt-qemu-migration-Always-offer-block-dirty-bitmaps-during-migration.patch
Patch26: libvirt-qemuMigrationDstPrepareAnyBlockDirtyBitmaps-Always-consider-offered-bitmaps.patch
Requires: libvirt-daemon = %{version}-%{release}
@ -2714,6 +2719,13 @@ exit 0
%endif
%changelog
* Wed Feb 4 2026 Jiri Denemark <jdenemar@redhat.com> - 11.10.0-5
- qemublocktest: Iterate all nodenames in 'testQemuDetectBitmaps' (RHEL-145770)
- qemu: monitor: Detect list of bitmaps from 'qcow2' format specific data (RHEL-145770)
- qemuMigrationDstPrepareAnyBlockDirtyBitmaps: Fix check for existing bitmaps (RHEL-145770)
- qemu: migration: Always offer block dirty bitmaps during migration (RHEL-145770)
- qemuMigrationDstPrepareAnyBlockDirtyBitmaps: Always consider offered bitmaps (RHEL-145770)
* Thu Jan 29 2026 Jiri Denemark <jdenemar@redhat.com> - 11.10.0-4
- qemuSecurityMoveImageMetadata: Move seclabels only to virStorageSource of same type (RHEL-140624)
- qemuDomainSetThrottleGroup: Enforce non-zero 'groupname' string length (RHEL-144010)