[RFC PATCH 00/41] qemu: Rewrite checkpoint code for 'block-dirty-bitmap-populate'

Use 'block-dirty-bitmap-populate' and change how we create bitmaps corresponding to checkpoints to simplify the code and also properly integrate with backing chain images created outside of libvirt. This patchset changes how we approach checkpoints by keeping one bitmap per checkpoint and disk and not propagating the bitmaps into overlays on snapshots. This massively simplifies the code handling all the operations during blockjobs and backups. While the change isn't compatible with checkpoints created previously, we didn't yet enable the support for checkpoints/backups. Note that 'block-dirty-bitmap-populate' is _not_ in finished state in qemu yet, so I'm posting this as RFC and as reference for qemu developers of the usefulnes of it. The changes can be fetched by: git fetch https://gitlab.com/pipo.sk/libvirt.git checkpoint-bitmap-populate Note that the above branch also contains a commit enabling incremental backup for simpler testing. I've pushed the appropriate qemu patches for convenience here: git fetch https://gitlab.com/pipo.sk/qemu.git block-dirty-bitmap-populate Peter Krempa (41): virErrorPreserveLast: Return the saved error object in addition to storing it util: error: Introduce VIR_ERROR_AUTOPRESERVE_LAST macro qemuBackupDiskDataCleanup: Use VIR_ERROR_AUTO_PRESERVE_LAST qemu: backup: Split up code traversing checkpoint list looking for bitmaps qemu: backup: Fix backup of disk skipped in an intermediate checkpoint conf: backup: Store incremental backup checkpoint name per-disk qemu: backup: Move fetching of checkpoint list for incremental backup qemublocktest: Add 'empty' test case for bitmaps qemublocktest: Add 'empty' case for incremental backup test qemublocktest: Add 'empty' case for checkpoint deletion qemublocktest: Add 'empty' case for blockcopy bitmap handling test qemublocktest: Add 'empty' case for checkpoint bitmap handling qemublocktest: Disable testcases for all bitmap handling qemublocktest: Delete 'synthetic' bitmap test cases qemublocktest: Extract printing of nodename list qemu: checkpoint: Don't chain bitmaps for checkpoints qemublocktest: Replace 'basic' bitmap detection test case data qemu: snapshot: Don't propagate bitmaps to upper layers qemublocktest: Replace 'snapshots' bitmap detection test case data qemuBlockBitmapChainIsValid: Adjust to new semantics of bitmaps qemublocktest: Re-add bitmap validation for 'basic' and 'snapshots' cases qemublocktest: Add new 'synthetic' bitmap detection and validation test case qemu: checkpoint: Don't merge checkpoints during deletion qemublocktest: Rename TEST_CHECKPOINT_DELETE_MERGE to TEST_CHECKPOINT_DELETE qemublocktest: Re-introduce testing of checkpoint deletion qemucapabilitiestest: Bump qemu-5.1 caps on x86_64 for 'dirty-bitmap-populate' qemu: monitor: Add support for 'block-dirty-bitmap-populate' transaction member qemuDomainStorageSourcePrivate: Add per-source private blockjob qemu: blockjob: Introduce 'populate' blockjob qemu: domain: Introduce helper for always fetching virStorageSource private data qemu: block: Add helper to add temporary block bitmaps from allocation maps qemu: block: Add universal helper for merging dirty bitmaps for all scenarios qemu: backup: Rewrite backup bitmap handling to the new bitmap semantics qemublocktest: Add 'basic' tests for backup bitmap handling qemublocktest: Add 'snapshots' tests for backup bitmap handling qemu: Rewrite bitmap handling for block commit qemublocktest: Add 'basic' tests for commit bitmap handling qemublocktest: Add 'snapshots' tests for block commit bitmap handling qemu: blockjob: Remove 'disabledBitmapsBase' field from commit job private data qemu: Rewrite bitmap handling for block copy qemublocktest: Add test cases for handling bitmaps during block-copy src/conf/backup_conf.c | 8 + src/conf/backup_conf.h | 1 + src/qemu/qemu_backup.c | 221 +- src/qemu/qemu_backup.h | 13 +- src/qemu/qemu_block.c | 674 ++-- src/qemu/qemu_block.h | 35 +- src/qemu/qemu_blockjob.c | 182 +- src/qemu/qemu_blockjob.h | 16 +- src/qemu/qemu_checkpoint.c | 174 +- src/qemu/qemu_checkpoint.h | 1 - src/qemu/qemu_domain.c | 46 +- src/qemu/qemu_domain.h | 6 + src/qemu/qemu_driver.c | 112 +- src/qemu/qemu_monitor.c | 11 + src/qemu/qemu_monitor.h | 7 + src/qemu/qemu_monitor_json.c | 18 + src/qemu/qemu_monitor_json.h | 6 + src/util/virerror.c | 18 +- src/util/virerror.h | 12 +- tests/qemublocktest.c | 267 +- .../backupmerge/basic-deep-out.json | 35 +- .../backupmerge/basic-flat-out.json | 23 +- .../backupmerge/basic-intermediate-out.json | 23 +- .../backupmerge/empty-out.json | 3 + .../backupmerge/snapshot-deep-out.json | 38 - .../backupmerge/snapshot-flat-out.json | 6 - .../snapshot-intermediate-out.json | 14 - .../backupmerge/snapshots-deep-out.json | 46 + .../backupmerge/snapshots-flat-out.json | 25 + .../snapshots-intermediate-out.json | 31 + tests/qemublocktestdata/bitmap/basic.json | 229 +- tests/qemublocktestdata/bitmap/basic.out | 8 +- tests/qemublocktestdata/bitmap/empty.json | 70 + tests/qemublocktestdata/bitmap/empty.out | 1 + .../bitmap/snapshots-synthetic-broken.json | 837 ----- .../bitmap/snapshots-synthetic-broken.out | 14 - .../snapshots-synthetic-checkpoint.json | 827 ----- .../bitmap/snapshots-synthetic-checkpoint.out | 13 - tests/qemublocktestdata/bitmap/snapshots.json | 1254 +++----- tests/qemublocktestdata/bitmap/snapshots.out | 6 +- tests/qemublocktestdata/bitmap/synthetic.json | 606 +++- tests/qemublocktestdata/bitmap/synthetic.out | 19 +- .../bitmapblockcommit/basic-1-2 | 66 +- .../bitmapblockcommit/basic-1-3 | 66 +- .../bitmapblockcommit/basic-2-3 | 1 - .../qemublocktestdata/bitmapblockcommit/empty | 1 + .../bitmapblockcommit/snapshots-1-2 | 24 +- .../bitmapblockcommit/snapshots-1-3 | 42 +- .../bitmapblockcommit/snapshots-1-4 | 97 +- .../bitmapblockcommit/snapshots-1-5 | 99 +- .../bitmapblockcommit/snapshots-2-3 | 23 - .../bitmapblockcommit/snapshots-2-4 | 55 +- .../bitmapblockcommit/snapshots-2-5 | 59 +- .../bitmapblockcommit/snapshots-3-4 | 25 +- .../bitmapblockcommit/snapshots-3-5 | 29 +- .../bitmapblockcommit/snapshots-4-5 | 32 - .../snapshots-synthetic-broken-1-2 | 57 - .../snapshots-synthetic-broken-1-3 | 112 - .../snapshots-synthetic-broken-1-4 | 119 - .../snapshots-synthetic-broken-1-5 | 119 - .../snapshots-synthetic-broken-2-3 | 89 - .../snapshots-synthetic-broken-2-4 | 96 - .../snapshots-synthetic-broken-2-5 | 96 - .../snapshots-synthetic-broken-3-4 | 27 - .../snapshots-synthetic-broken-3-5 | 27 - .../snapshots-synthetic-broken-4-5 | 20 - .../bitmapblockcopy/basic-deep-out.json | 65 +- .../bitmapblockcopy/basic-shallow-out.json | 65 +- .../bitmapblockcopy/empty-deep-out.json | 0 .../bitmapblockcopy/empty-shallow-out.json | 0 .../bitmapblockcopy/snapshots-deep-out.json | 104 +- .../snapshots-shallow-out.json | 24 +- .../checkpointdelete/basic-current-out.json | 20 - .../basic-intermediate1-out.json | 13 - .../basic-intermediate2-out.json | 13 - .../basic-intermediate3-out.json | 13 - .../checkpointdelete/empty-out.json | 1 + .../snapshots-current-out.json | 20 - .../snapshots-intermediate1-out.json | 13 - .../snapshots-intermediate2-out.json | 51 - .../snapshots-intermediate3-out.json | 50 - .../snapshots-noparent-out.json | 16 - ...hots-synthetic-checkpoint-current-out.json | 29 - ...ynthetic-checkpoint-intermediate1-out.json | 31 - ...ynthetic-checkpoint-intermediate2-out.json | 34 - ...ynthetic-checkpoint-intermediate3-out.json | 61 - ...ots-synthetic-checkpoint-noparent-out.json | 27 - .../synthetic-current-out.json | 9 + .../synthetic-intermediate1-out.json | 11 + .../synthetic-intermediate2-out.json | 11 + .../synthetic-intermediate3-out.json | 19 + .../synthetic-noparent-out.json | 11 + .../caps_5.1.0.x86_64.replies | 2737 +++++++++-------- .../caps_5.1.0.x86_64.xml | 2 +- tests/qemumonitorjsontest.c | 3 +- .../blockjob-blockdev-in.xml | 4 - 96 files changed, 4077 insertions(+), 6717 deletions(-) create mode 100644 tests/qemublocktestdata/backupmerge/empty-out.json delete mode 100644 tests/qemublocktestdata/backupmerge/snapshot-deep-out.json delete mode 100644 tests/qemublocktestdata/backupmerge/snapshot-flat-out.json delete mode 100644 tests/qemublocktestdata/backupmerge/snapshot-intermediate-out.json create mode 100644 tests/qemublocktestdata/backupmerge/snapshots-deep-out.json create mode 100644 tests/qemublocktestdata/backupmerge/snapshots-flat-out.json create mode 100644 tests/qemublocktestdata/backupmerge/snapshots-intermediate-out.json create mode 100644 tests/qemublocktestdata/bitmap/empty.json create mode 100644 tests/qemublocktestdata/bitmap/empty.out delete mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json delete mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out delete mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.json delete mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.out create mode 100644 tests/qemublocktestdata/bitmapblockcommit/empty delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-4 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-4-5 create mode 100644 tests/qemublocktestdata/bitmapblockcopy/empty-deep-out.json create mode 100644 tests/qemublocktestdata/bitmapblockcopy/empty-shallow-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/empty-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-current-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/synthetic-current-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/synthetic-intermediate1-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/synthetic-intermediate2-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/synthetic-intermediate3-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/synthetic-noparent-out.json -- 2.26.2

In some cases it's easier to use the returned value rather than passing the variable pointer in via argument. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/util/virerror.c | 18 ++++++++++++------ src/util/virerror.h | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/util/virerror.c b/src/util/virerror.c index 774c36bca3..1277a0bdfc 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -417,22 +417,28 @@ virSaveLastError(void) * virErrorPreserveLast: * @saveerr: pointer to virErrorPtr for storing last error object * - * Preserves the currently set last error (for the thread) into @saveerr so that - * it can be restored via virErrorRestore(). @saveerr must be passed to + * Preserves the currently set last error (for the thread) into @saveerr (if + * non-NULL) and in the return value so that it can be restored via + * virErrorRestore(). @saveerr or the return value must be passed to * virErrorRestore() + * + * Returns the last error object or NULL if there is no error. */ -void +virErrorPtr virErrorPreserveLast(virErrorPtr *saveerr) { int saved_errno = errno; virErrorPtr lasterr = virGetLastError(); - - *saveerr = NULL; + virErrorPtr copy = NULL; if (lasterr) - *saveerr = virErrorCopyNew(lasterr); + copy = virErrorCopyNew(lasterr); + + if (saveerr) + *saveerr = copy; errno = saved_errno; + return copy; } diff --git a/src/util/virerror.h b/src/util/virerror.h index 9d3e40d65a..42f2835a85 100644 --- a/src/util/virerror.h +++ b/src/util/virerror.h @@ -200,7 +200,7 @@ void virErrorSetErrnoFromLastError(void); bool virLastErrorIsSystemErrno(int errnum); -void virErrorPreserveLast(virErrorPtr *saveerr); +virErrorPtr virErrorPreserveLast(virErrorPtr *saveerr); void virErrorRestore(virErrorPtr *savederr); void virLastErrorPrefixMessage(const char *fmt, ...) -- 2.26.2

The macro is used to automatically preserve the last error object on cleanup paths which might override. Note that the 'ignore_value' is required to silence clang's unused variable checker. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/util/virerror.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/util/virerror.h b/src/util/virerror.h index 42f2835a85..ce0b48b3ad 100644 --- a/src/util/virerror.h +++ b/src/util/virerror.h @@ -207,3 +207,13 @@ void virLastErrorPrefixMessage(const char *fmt, ...) G_GNUC_PRINTF(1, 2); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virError, virFreeError); + +/** + * VIR_ERROR_AUTO_PRESERVE_LAST: + * + * This macro ensures that the last error object is restored to the state it was + * at the point where the macro was expanded when the scope ends. + */ +#define VIR_ERROR_AUTOPRESERVE_LAST \ + __attribute__((cleanup(virErrorRestore))) virErrorPtr orig_err_preserve = virErrorPreserveLast(NULL); \ + ignore_value(&orig_err_preserve) -- 2.26.2

Example usage of the new macro. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_backup.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index b317b841cd..ac7fa5def3 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -157,19 +157,16 @@ qemuBackupDiskDataCleanup(virDomainObjPtr vm, struct qemuBackupDiskData *dd, size_t ndd) { - virErrorPtr orig_err; + VIR_ERROR_AUTOPRESERVE_LAST; size_t i; if (!dd) return; - virErrorPreserveLast(&orig_err); - for (i = 0; i < ndd; i++) qemuBackupDiskDataCleanupOne(vm, dd + i); g_free(dd); - virErrorRestore(&orig_err); } -- 2.26.2

The algorithm is getting quite complex. Split out the lookup of range of backing chain storage sources and bitmaps contained in them which correspond to one checkpoint. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_backup.c | 111 ++++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 50 deletions(-) diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index ac7fa5def3..0a4c08e01e 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -170,72 +170,83 @@ qemuBackupDiskDataCleanup(virDomainObjPtr vm, } +static int +qemuBackupGetBitmapMergeRange(virStorageSourcePtr from, + const char *bitmapname, + virJSONValuePtr *actions, + virStorageSourcePtr *to, + const char *diskdst, + virHashTablePtr blockNamedNodeData) +{ + g_autoptr(virJSONValue) ret = virJSONValueNewArray(); + virStorageSourcePtr tmpsrc = NULL; + virStorageSourcePtr n; + bool foundbitmap = false; + + for (n = from; virStorageSourceIsBacking(n); n = n->backingStore) { + qemuBlockNamedNodeDataBitmapPtr bitmap = NULL; + + if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, + n, + bitmapname))) + break; + + foundbitmap = true; + + if (bitmap->inconsistent) { + virReportError(VIR_ERR_INVALID_ARG, + _("bitmap '%s' for image '%s%u' is inconsistent"), + bitmap->name, diskdst, n->id); + return -1; + } + + if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(ret, + n->nodeformat, + bitmapname) < 0) + return -1; + + tmpsrc = n; + } + + if (!foundbitmap) { + virReportError(VIR_ERR_INVALID_ARG, + _("failed to find bitmap '%s' in image '%s%u'"), + bitmapname, diskdst, from->id); + return -1; + } + + *actions = g_steal_pointer(&ret); + *to = tmpsrc; + + return 0; +} + + virJSONValuePtr qemuBackupDiskPrepareOneBitmapsChain(virDomainMomentDefPtr *incremental, virStorageSourcePtr backingChain, virHashTablePtr blockNamedNodeData, const char *diskdst) { - qemuBlockNamedNodeDataBitmapPtr bitmap; g_autoptr(virJSONValue) ret = NULL; size_t incridx = 0; + virStorageSourcePtr n = backingChain; ret = virJSONValueNewArray(); - if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, - backingChain, - incremental[0]->name))) { - virReportError(VIR_ERR_INVALID_ARG, - _("failed to find bitmap '%s' in image '%s%u'"), - incremental[0]->name, diskdst, backingChain->id); - return NULL; - } + for (incridx = 0; incremental[incridx]; incridx++) { + g_autoptr(virJSONValue) tmp = virJSONValueNewArray(); + virStorageSourcePtr tmpsrc = NULL; - while (bitmap) { - if (bitmap->inconsistent) { - virReportError(VIR_ERR_INVALID_ARG, - _("bitmap '%s' for image '%s%u' is inconsistent"), - bitmap->name, diskdst, backingChain->id); + if (qemuBackupGetBitmapMergeRange(n, incremental[incridx]->name, + &tmp, &tmpsrc, diskdst, + blockNamedNodeData) < 0) return NULL; - } - if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(ret, - backingChain->nodeformat, - bitmap->name) < 0) + if (virJSONValueArrayConcat(ret, tmp) < 0) return NULL; - if (backingChain->backingStore && - (bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, - backingChain->backingStore, - incremental[incridx]->name))) { - backingChain = backingChain->backingStore; - continue; - } - - if (incremental[incridx + 1]) { - if ((bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, - backingChain, - incremental[incridx + 1]->name))) { - incridx++; - continue; - } - - if (backingChain->backingStore && - (bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, - backingChain->backingStore, - incremental[incridx + 1]->name))) { - incridx++; - backingChain = backingChain->backingStore; - continue; - } - - virReportError(VIR_ERR_INVALID_ARG, - _("failed to find bitmap '%s' in image '%s%u'"), - incremental[incridx]->name, diskdst, backingChain->id); - return NULL; - } else { - break; - } + n = tmpsrc; } return g_steal_pointer(&ret); -- 2.26.2

If a disk is not captured by one of the intermediate checkpoints the code would fail, but we can easily calculate the bitmaps to merge correctly by skipping over checkpoints which don't describe the disk. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_backup.c | 24 ++++++++++++++++++++++++ tests/qemublocktest.c | 6 ++++++ 2 files changed, 30 insertions(+) diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index 0a4c08e01e..cb1df9ffae 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -237,6 +237,30 @@ qemuBackupDiskPrepareOneBitmapsChain(virDomainMomentDefPtr *incremental, for (incridx = 0; incremental[incridx]; incridx++) { g_autoptr(virJSONValue) tmp = virJSONValueNewArray(); virStorageSourcePtr tmpsrc = NULL; + virDomainCheckpointDefPtr chkdef = (virDomainCheckpointDefPtr) incremental[incridx]; + bool checkpoint_has_disk = false; + size_t i; + + for (i = 0; i < chkdef->ndisks; i++) { + if (STRNEQ_NULLABLE(diskdst, chkdef->disks[i].name)) + continue; + + if (chkdef->disks[i].type == VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP) + checkpoint_has_disk = true; + + break; + } + + if (!checkpoint_has_disk) { + if (!incremental[incridx + 1]) { + virReportError(VIR_ERR_INVALID_ARG, + _("disk '%s' not found in checkpoint '%s'"), + diskdst, incremental[incridx]->name); + return NULL; + } + + continue; + } if (qemuBackupGetBitmapMergeRange(n, incremental[incridx]->name, &tmp, &tmpsrc, diskdst, diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 0cdedb9ad4..f00d2ff129 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -727,6 +727,12 @@ testQemuBackupGetIncrementalMoment(const char *name) if (!(checkpoint = virDomainCheckpointDefNew())) abort(); + checkpoint->disks = g_new0(virDomainCheckpointDiskDef, 1); + checkpoint->ndisks = 1; + + checkpoint->disks[0].name = g_strdup("testdisk"); + checkpoint->disks[0].type = VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP; + checkpoint->parent.name = g_strdup(name); return (virDomainMomentDefPtr) checkpoint; -- 2.26.2

In preparation to allow heterogenous backups store the 'incremental' field per-disk and fill it by default from the per-backup field. Having this will be important once we'll want to allow incremental backup working while hotplugging a new disk. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/backup_conf.c | 8 ++++++++ src/conf/backup_conf.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/conf/backup_conf.c b/src/conf/backup_conf.c index c0c6f25d10..92106d8aaa 100644 --- a/src/conf/backup_conf.c +++ b/src/conf/backup_conf.c @@ -72,6 +72,7 @@ virDomainBackupDefFree(virDomainBackupDefPtr def) virDomainBackupDiskDefPtr disk = def->disks + i; g_free(disk->name); + g_free(disk->incremental); g_free(disk->exportname); g_free(disk->exportbitmap); virObjectUnref(disk->store); @@ -505,5 +506,12 @@ virDomainBackupAlignDisks(virDomainBackupDefPtr def, } } + for (i = 0; i < def->ndisks; i++) { + virDomainBackupDiskDefPtr backupdisk = &def->disks[i]; + + if (def->incremental && !backupdisk->incremental) + backupdisk->incremental = g_strdup(def->incremental); + } + return 0; } diff --git a/src/conf/backup_conf.h b/src/conf/backup_conf.h index b5685317c5..172eb1cf1c 100644 --- a/src/conf/backup_conf.h +++ b/src/conf/backup_conf.h @@ -51,6 +51,7 @@ typedef virDomainBackupDiskDef *virDomainBackupDiskDefPtr; struct _virDomainBackupDiskDef { char *name; /* name matching the <target dev='...' of the domain */ virTristateBool backup; /* whether backup is requested */ + char *incremental; /* name of the starting point checkpoint of an incremental backup */ char *exportname; /* name of the NBD export for pull mode backup */ char *exportbitmap; /* name of the bitmap exposed in NBD for pull mode backup */ -- 2.26.2

Fetch the checkpoint list for every disk specifically based on the new per-disk 'incremental' field. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_backup.c | 108 ++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 56 deletions(-) diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index cb1df9ffae..5729aac858 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -170,6 +170,50 @@ qemuBackupDiskDataCleanup(virDomainObjPtr vm, } +/** + * qemuBackupBeginCollectIncrementalCheckpoints: + * @vm: domain object + * @incrFrom: name of checkpoint representing starting point of incremental backup + * + * Returns a NULL terminated list of pointers to checkpoint definitions in + * chronological order starting from the 'current' checkpoint until reaching + * @incrFrom. + */ +static virDomainMomentDefPtr * +qemuBackupBeginCollectIncrementalCheckpoints(virDomainObjPtr vm, + const char *incrFrom) +{ + virDomainMomentObjPtr n = virDomainCheckpointGetCurrent(vm->checkpoints); + g_autofree virDomainMomentDefPtr *incr = NULL; + size_t nincr = 0; + + while (n) { + virDomainMomentDefPtr def = n->def; + + if (VIR_APPEND_ELEMENT_COPY(incr, nincr, def) < 0) + return NULL; + + if (STREQ(def->name, incrFrom)) { + def = NULL; + if (VIR_APPEND_ELEMENT_COPY(incr, nincr, def) < 0) + return NULL; + + return g_steal_pointer(&incr); + } + + if (!n->def->parent_name) + break; + + n = virDomainCheckpointFindByName(vm->checkpoints, n->def->parent_name); + } + + virReportError(VIR_ERR_OPERATION_INVALID, + _("could not locate checkpoint '%s' for incremental backup"), + incrFrom); + return NULL; +} + + static int qemuBackupGetBitmapMergeRange(virStorageSourcePtr from, const char *bitmapname, @@ -331,11 +375,11 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm, struct qemuBackupDiskData *dd, virJSONValuePtr actions, bool pull, - virDomainMomentDefPtr *incremental, virHashTablePtr blockNamedNodeData, virQEMUDriverConfigPtr cfg) { qemuDomainObjPrivatePtr priv = vm->privateData; + g_autofree virDomainMomentDefPtr *incremental = NULL; /* set data structure */ dd->backupdisk = backupdisk; @@ -360,7 +404,7 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm, * pull mode: * both: original disk */ - if (pull || (incremental && dd->store->format >= VIR_STORAGE_FILE_BACKING)) { + if (pull || (dd->backupdisk->incremental && dd->store->format >= VIR_STORAGE_FILE_BACKING)) { dd->backingStore = dd->domdisk->src; } else { dd->backingStore = dd->terminator = virStorageSourceNew(); @@ -372,7 +416,10 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm, if (qemuDomainPrepareStorageSourceBlockdev(NULL, dd->store, priv, cfg) < 0) return -1; - if (incremental) { + if (dd->backupdisk->incremental) { + if (!(incremental = qemuBackupBeginCollectIncrementalCheckpoints(vm, dd->backupdisk->incremental))) + return -1; + if (dd->backupdisk->exportbitmap) dd->incrementalBitmap = g_strdup(dd->backupdisk->exportbitmap); else @@ -441,7 +488,6 @@ qemuBackupDiskPrepareDataOnePull(virJSONValuePtr actions, static ssize_t qemuBackupDiskPrepareData(virDomainObjPtr vm, virDomainBackupDefPtr def, - virDomainMomentDefPtr *incremental, virHashTablePtr blockNamedNodeData, virJSONValuePtr actions, virQEMUDriverConfigPtr cfg, @@ -464,8 +510,7 @@ qemuBackupDiskPrepareData(virDomainObjPtr vm, ndisks++; if (qemuBackupDiskPrepareDataOne(vm, backupdisk, dd, actions, pull, - incremental, blockNamedNodeData, - cfg) < 0) + blockNamedNodeData, cfg) < 0) goto error; if (pull) { @@ -622,50 +667,6 @@ qemuBackupBeginPullExportDisks(virDomainObjPtr vm, } -/** - * qemuBackupBeginCollectIncrementalCheckpoints: - * @vm: domain object - * @incrFrom: name of checkpoint representing starting point of incremental backup - * - * Returns a NULL terminated list of pointers to checkpoint definitions in - * chronological order starting from the 'current' checkpoint until reaching - * @incrFrom. - */ -static virDomainMomentDefPtr * -qemuBackupBeginCollectIncrementalCheckpoints(virDomainObjPtr vm, - const char *incrFrom) -{ - virDomainMomentObjPtr n = virDomainCheckpointGetCurrent(vm->checkpoints); - g_autofree virDomainMomentDefPtr *incr = NULL; - size_t nincr = 0; - - while (n) { - virDomainMomentDefPtr def = n->def; - - if (VIR_APPEND_ELEMENT_COPY(incr, nincr, def) < 0) - return NULL; - - if (STREQ(def->name, incrFrom)) { - def = NULL; - if (VIR_APPEND_ELEMENT_COPY(incr, nincr, def) < 0) - return NULL; - - return g_steal_pointer(&incr); - } - - if (!n->def->parent_name) - break; - - n = virDomainCheckpointFindByName(vm->checkpoints, n->def->parent_name); - } - - virReportError(VIR_ERR_OPERATION_INVALID, - _("could not locate checkpoint '%s' for incremental backup"), - incrFrom); - return NULL; -} - - void qemuBackupJobTerminate(virDomainObjPtr vm, qemuDomainJobStatus jobstatus) @@ -799,7 +800,6 @@ qemuBackupBegin(virDomainObjPtr vm, bool pull = false; virDomainMomentObjPtr chk = NULL; g_autoptr(virDomainCheckpointDef) chkdef = NULL; - g_autofree virDomainMomentDefPtr *incremental = NULL; g_autoptr(virJSONValue) actions = NULL; struct qemuBackupDiskData *dd = NULL; ssize_t ndd = 0; @@ -867,10 +867,6 @@ qemuBackupBegin(virDomainObjPtr vm, if (virDomainBackupAlignDisks(def, vm->def, suffix) < 0) goto endjob; - if (def->incremental && - !(incremental = qemuBackupBeginCollectIncrementalCheckpoints(vm, def->incremental))) - goto endjob; - actions = virJSONValueNewArray(); /* The 'chk' checkpoint must be rolled back if the transaction command @@ -884,7 +880,7 @@ qemuBackupBegin(virDomainObjPtr vm, if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_BACKUP))) goto endjob; - if ((ndd = qemuBackupDiskPrepareData(vm, def, incremental, blockNamedNodeData, + if ((ndd = qemuBackupDiskPrepareData(vm, def, blockNamedNodeData, actions, cfg, &dd)) <= 0) { if (ndd == 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", -- 2.26.2

Add test data for an image without bitmaps. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 4 ++ tests/qemublocktestdata/bitmap/empty.json | 70 +++++++++++++++++++++++ tests/qemublocktestdata/bitmap/empty.out | 1 + 3 files changed, 75 insertions(+) create mode 100644 tests/qemublocktestdata/bitmap/empty.json create mode 100644 tests/qemublocktestdata/bitmap/empty.out diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index f00d2ff129..8d613d7cac 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1292,6 +1292,8 @@ mymain(void) ret = -1; \ } while (0) + TEST_BITMAP_DETECT("empty"); + TEST_BITMAP_DETECT("basic"); TEST_BITMAP_DETECT("synthetic"); TEST_BITMAP_DETECT("snapshots"); @@ -1360,6 +1362,8 @@ mymain(void) ret = -1; \ } while (0) + TEST_BITMAP_VALIDATE("empty", "a", false); + TEST_BITMAP_VALIDATE("basic", "a", true); TEST_BITMAP_VALIDATE("basic", "b", true); TEST_BITMAP_VALIDATE("basic", "c", true); diff --git a/tests/qemublocktestdata/bitmap/empty.json b/tests/qemublocktestdata/bitmap/empty.json new file mode 100644 index 0000000000..ec43b25f0d --- /dev/null +++ b/tests/qemublocktestdata/bitmap/empty.json @@ -0,0 +1,70 @@ +[ + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 10485760, + "filename": "/tmp/pull4.qcow2", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 200704, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false + } + }, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-1-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/pull4.qcow2", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 197120, + "filename": "/tmp/pull4.qcow2", + "format": "file", + "actual-size": 200704, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-1-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/pull4.qcow2", + "encryption_key_missing": false + } +] diff --git a/tests/qemublocktestdata/bitmap/empty.out b/tests/qemublocktestdata/bitmap/empty.out new file mode 100644 index 0000000000..3787cbd354 --- /dev/null +++ b/tests/qemublocktestdata/bitmap/empty.out @@ -0,0 +1 @@ +libvirt-1-format: -- 2.26.2

Use the new test data when calculating incremental backup operations. As incremental backup fails with no bitmap the test code is modified to allow testing this case too. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 19 ++++++++++--------- .../backupmerge/empty-out.json | 1 + 2 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 tests/qemublocktestdata/backupmerge/empty-out.json diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 8d613d7cac..9e54c254e8 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -793,17 +793,16 @@ testQemuBackupIncrementalBitmapCalculate(const void *opaque) incremental = testQemuBackupGetIncremental(data->incremental); - if (!(mergebitmaps = qemuBackupDiskPrepareOneBitmapsChain(incremental, - data->chain, - nodedata, - "testdisk"))) { - VIR_TEST_VERBOSE("failed to calculate merged bitmaps"); - return -1; + if ((mergebitmaps = qemuBackupDiskPrepareOneBitmapsChain(incremental, + data->chain, + nodedata, + "testdisk"))) { + if (!(actual = virJSONValueToString(mergebitmaps, true))) + return -1; + } else { + actual = g_strdup("NULL\n"); } - if (!(actual = virJSONValueToString(mergebitmaps, true))) - return -1; - return virTestCompareToFile(actual, expectpath); } @@ -1312,6 +1311,8 @@ mymain(void) ret = -1; \ } while (0) + TEST_BACKUP_BITMAP_CALCULATE("empty", bitmapSourceChain, "a", "empty"); + TEST_BACKUP_BITMAP_CALCULATE("basic-flat", bitmapSourceChain, "current", "basic"); TEST_BACKUP_BITMAP_CALCULATE("basic-intermediate", bitmapSourceChain, "d", "basic"); TEST_BACKUP_BITMAP_CALCULATE("basic-deep", bitmapSourceChain, "a", "basic"); diff --git a/tests/qemublocktestdata/backupmerge/empty-out.json b/tests/qemublocktestdata/backupmerge/empty-out.json new file mode 100644 index 0000000000..7951defec1 --- /dev/null +++ b/tests/qemublocktestdata/backupmerge/empty-out.json @@ -0,0 +1 @@ +NULL -- 2.26.2

Use the new test data for checkpoint deletion testing. This test also requires modification of the internals to allow checking for test failure. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 13 +++++++------ .../checkpointdelete/empty-out.json | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 tests/qemublocktestdata/checkpointdelete/empty-out.json diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 9e54c254e8..1821c227d5 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -851,14 +851,13 @@ testQemuCheckpointDeleteMerge(const void *opaque) data->parentbitmap, actions, "testdisk", - &reopenimages) < 0) { - VIR_TEST_VERBOSE("failed to generate checkpoint delete transaction\n"); - return -1; + &reopenimages) >= 0) { + if (virJSONValueToBuffer(actions, &buf, true) < 0) + return -1; + } else { + virBufferAddLit(&buf, "NULL\n"); } - if (virJSONValueToBuffer(actions, &buf, true) < 0) - return -1; - if (reopenimages) { virBufferAddLit(&buf, "reopen nodes:\n"); @@ -1333,6 +1332,8 @@ mymain(void) ret = -1; \ } while (0) + TEST_CHECKPOINT_DELETE_MERGE("empty", "a", NULL, "empty"); + TEST_CHECKPOINT_DELETE_MERGE("basic-noparent", "a", NULL, "basic"); TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate1", "b", "a", "basic"); TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate2", "c", "b", "basic"); diff --git a/tests/qemublocktestdata/checkpointdelete/empty-out.json b/tests/qemublocktestdata/checkpointdelete/empty-out.json new file mode 100644 index 0000000000..7951defec1 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/empty-out.json @@ -0,0 +1 @@ +NULL -- 2.26.2

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 3 +++ tests/qemublocktestdata/bitmapblockcopy/empty-deep-out.json | 0 tests/qemublocktestdata/bitmapblockcopy/empty-shallow-out.json | 0 3 files changed, 3 insertions(+) create mode 100644 tests/qemublocktestdata/bitmapblockcopy/empty-deep-out.json create mode 100644 tests/qemublocktestdata/bitmapblockcopy/empty-shallow-out.json diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 1821c227d5..2ddfab72eb 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1408,6 +1408,9 @@ mymain(void) ret = -1; \ } while (0) + TEST_BITMAP_BLOCKCOPY("empty-shallow", true, "empty"); + TEST_BITMAP_BLOCKCOPY("empty-deep", false, "empty"); + TEST_BITMAP_BLOCKCOPY("basic-shallow", true, "basic"); TEST_BITMAP_BLOCKCOPY("basic-deep", false, "basic"); diff --git a/tests/qemublocktestdata/bitmapblockcopy/empty-deep-out.json b/tests/qemublocktestdata/bitmapblockcopy/empty-deep-out.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qemublocktestdata/bitmapblockcopy/empty-shallow-out.json b/tests/qemublocktestdata/bitmapblockcopy/empty-shallow-out.json new file mode 100644 index 0000000000..e69de29bb2 -- 2.26.2

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 2 ++ tests/qemublocktestdata/bitmapblockcommit/empty | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 tests/qemublocktestdata/bitmapblockcommit/empty diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 2ddfab72eb..d66e169fd8 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1430,6 +1430,8 @@ mymain(void) ret = -1; \ } while (0) + TEST_BITMAP_BLOCKCOMMIT("empty", 1, 2, "empty"); + TEST_BITMAP_BLOCKCOMMIT("basic-1-2", 1, 2, "basic"); TEST_BITMAP_BLOCKCOMMIT("basic-1-3", 1, 3, "basic"); TEST_BITMAP_BLOCKCOMMIT("basic-2-3", 2, 3, "basic"); diff --git a/tests/qemublocktestdata/bitmapblockcommit/empty b/tests/qemublocktestdata/bitmapblockcommit/empty new file mode 100644 index 0000000000..bfc58f994e --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/empty @@ -0,0 +1,2 @@ +pre job bitmap disable: +merge bitmpas: -- 2.26.2

Upcoming patches are going to rewrite and semantically modify how bitmaps are handled during blockjobs. This is possible as incremental backup is not yet fully enabled. As the changes are going to be incompatible with any current test data remove all test cases for bitmap handling during checkpoint deletion, incremental backups, block commit, block copy, and bitmap validation operations. The tests will be gradually added back later after the code and test-data is refactored. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 94 ------------- .../backupmerge/basic-deep-out.json | 22 --- .../backupmerge/basic-flat-out.json | 6 - .../backupmerge/basic-intermediate-out.json | 10 -- .../backupmerge/snapshot-deep-out.json | 38 ----- .../backupmerge/snapshot-flat-out.json | 6 - .../snapshot-intermediate-out.json | 14 -- .../bitmapblockcommit/basic-1-2 | 119 ---------------- .../bitmapblockcommit/basic-1-3 | 119 ---------------- .../bitmapblockcommit/basic-2-3 | 2 - .../bitmapblockcommit/snapshots-1-2 | 49 ------- .../bitmapblockcommit/snapshots-1-3 | 76 ---------- .../bitmapblockcommit/snapshots-1-4 | 126 ----------------- .../bitmapblockcommit/snapshots-1-5 | 130 ----------------- .../bitmapblockcommit/snapshots-2-3 | 49 ------- .../bitmapblockcommit/snapshots-2-4 | 99 ------------- .../bitmapblockcommit/snapshots-2-5 | 103 -------------- .../bitmapblockcommit/snapshots-3-4 | 72 ---------- .../bitmapblockcommit/snapshots-3-5 | 76 ---------- .../bitmapblockcommit/snapshots-4-5 | 33 ----- .../snapshots-synthetic-broken-1-2 | 57 -------- .../snapshots-synthetic-broken-1-3 | 112 --------------- .../snapshots-synthetic-broken-1-4 | 119 ---------------- .../snapshots-synthetic-broken-1-5 | 119 ---------------- .../snapshots-synthetic-broken-2-3 | 89 ------------ .../snapshots-synthetic-broken-2-4 | 96 ------------- .../snapshots-synthetic-broken-2-5 | 96 ------------- .../snapshots-synthetic-broken-3-4 | 27 ---- .../snapshots-synthetic-broken-3-5 | 27 ---- .../snapshots-synthetic-broken-4-5 | 20 --- .../bitmapblockcopy/basic-deep-out.json | 117 --------------- .../bitmapblockcopy/basic-shallow-out.json | 117 --------------- .../bitmapblockcopy/snapshots-deep-out.json | 133 ------------------ .../snapshots-shallow-out.json | 48 ------- .../checkpointdelete/basic-current-out.json | 29 ---- .../basic-intermediate1-out.json | 22 --- .../basic-intermediate2-out.json | 22 --- .../basic-intermediate3-out.json | 22 --- .../checkpointdelete/basic-noparent-out.json | 9 -- .../snapshots-current-out.json | 29 ---- .../snapshots-intermediate1-out.json | 24 ---- .../snapshots-intermediate2-out.json | 62 -------- .../snapshots-intermediate3-out.json | 61 -------- .../snapshots-noparent-out.json | 27 ---- ...hots-synthetic-checkpoint-current-out.json | 29 ---- ...ynthetic-checkpoint-intermediate1-out.json | 31 ---- ...ynthetic-checkpoint-intermediate2-out.json | 34 ----- ...ynthetic-checkpoint-intermediate3-out.json | 61 -------- ...ots-synthetic-checkpoint-noparent-out.json | 27 ---- 49 files changed, 2909 deletions(-) delete mode 100644 tests/qemublocktestdata/backupmerge/basic-deep-out.json delete mode 100644 tests/qemublocktestdata/backupmerge/basic-flat-out.json delete mode 100644 tests/qemublocktestdata/backupmerge/basic-intermediate-out.json delete mode 100644 tests/qemublocktestdata/backupmerge/snapshot-deep-out.json delete mode 100644 tests/qemublocktestdata/backupmerge/snapshot-flat-out.json delete mode 100644 tests/qemublocktestdata/backupmerge/snapshot-intermediate-out.json delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/basic-1-2 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/basic-1-3 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/basic-2-3 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-4 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-4-5 delete mode 100644 tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json delete mode 100644 tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json delete mode 100644 tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json delete mode 100644 tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/basic-current-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-current-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json delete mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index d66e169fd8..d2f105486e 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1312,14 +1312,6 @@ mymain(void) TEST_BACKUP_BITMAP_CALCULATE("empty", bitmapSourceChain, "a", "empty"); - TEST_BACKUP_BITMAP_CALCULATE("basic-flat", bitmapSourceChain, "current", "basic"); - TEST_BACKUP_BITMAP_CALCULATE("basic-intermediate", bitmapSourceChain, "d", "basic"); - TEST_BACKUP_BITMAP_CALCULATE("basic-deep", bitmapSourceChain, "a", "basic"); - - TEST_BACKUP_BITMAP_CALCULATE("snapshot-flat", bitmapSourceChain, "current", "snapshots"); - TEST_BACKUP_BITMAP_CALCULATE("snapshot-intermediate", bitmapSourceChain, "d", "snapshots"); - TEST_BACKUP_BITMAP_CALCULATE("snapshot-deep", bitmapSourceChain, "a", "snapshots"); - #define TEST_CHECKPOINT_DELETE_MERGE(testname, delbmp, parbmp, named) \ do { \ checkpointdeletedata.name = testname; \ @@ -1334,24 +1326,6 @@ mymain(void) TEST_CHECKPOINT_DELETE_MERGE("empty", "a", NULL, "empty"); - TEST_CHECKPOINT_DELETE_MERGE("basic-noparent", "a", NULL, "basic"); - TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate1", "b", "a", "basic"); - TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate2", "c", "b", "basic"); - TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate3", "d", "c", "basic"); - TEST_CHECKPOINT_DELETE_MERGE("basic-current", "current", "d", "basic"); - - TEST_CHECKPOINT_DELETE_MERGE("snapshots-noparent", "a", NULL, "snapshots"); - TEST_CHECKPOINT_DELETE_MERGE("snapshots-intermediate1", "b", "a", "snapshots"); - TEST_CHECKPOINT_DELETE_MERGE("snapshots-intermediate2", "c", "b", "snapshots"); - TEST_CHECKPOINT_DELETE_MERGE("snapshots-intermediate3", "d", "c", "snapshots"); - TEST_CHECKPOINT_DELETE_MERGE("snapshots-current", "current", "d", "snapshots"); - - TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-noparent", "a", NULL, "snapshots-synthetic-checkpoint"); - TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-intermediate1", "b", "a", "snapshots-synthetic-checkpoint"); - TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-intermediate2", "c", "b", "snapshots-synthetic-checkpoint"); - TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-intermediate3", "d", "c", "snapshots-synthetic-checkpoint"); - TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-current", "current", "d", "snapshots-synthetic-checkpoint"); - #define TEST_BITMAP_VALIDATE(testname, bitmap, rc) \ do { \ blockbitmapvalidatedata.name = testname; \ @@ -1366,36 +1340,6 @@ mymain(void) TEST_BITMAP_VALIDATE("empty", "a", false); - TEST_BITMAP_VALIDATE("basic", "a", true); - TEST_BITMAP_VALIDATE("basic", "b", true); - TEST_BITMAP_VALIDATE("basic", "c", true); - TEST_BITMAP_VALIDATE("basic", "d", true); - TEST_BITMAP_VALIDATE("basic", "current", true); - - TEST_BITMAP_VALIDATE("snapshots", "a", true); - TEST_BITMAP_VALIDATE("snapshots", "b", true); - TEST_BITMAP_VALIDATE("snapshots", "c", true); - TEST_BITMAP_VALIDATE("snapshots", "d", true); - TEST_BITMAP_VALIDATE("snapshots", "current", true); - - TEST_BITMAP_VALIDATE("synthetic", "a", false); - TEST_BITMAP_VALIDATE("synthetic", "b", true); - TEST_BITMAP_VALIDATE("synthetic", "c", true); - TEST_BITMAP_VALIDATE("synthetic", "d", true); - TEST_BITMAP_VALIDATE("synthetic", "current", true); - - TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "a", true); - TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "b", true); - TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "c", true); - TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "d", true); - TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "current", true); - - TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "a", false); - TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "b", true); - TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "c", true); - TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "d", false); - TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "current", true); - #define TEST_BITMAP_BLOCKCOPY(testname, shllw, ndf) \ do { \ blockbitmapblockcopydata.name = testname; \ @@ -1411,12 +1355,6 @@ mymain(void) TEST_BITMAP_BLOCKCOPY("empty-shallow", true, "empty"); TEST_BITMAP_BLOCKCOPY("empty-deep", false, "empty"); - TEST_BITMAP_BLOCKCOPY("basic-shallow", true, "basic"); - TEST_BITMAP_BLOCKCOPY("basic-deep", false, "basic"); - - TEST_BITMAP_BLOCKCOPY("snapshots-shallow", true, "snapshots"); - TEST_BITMAP_BLOCKCOPY("snapshots-deep", false, "snapshots"); - #define TEST_BITMAP_BLOCKCOMMIT(testname, topimg, baseimg, ndf) \ do {\ @@ -1432,38 +1370,6 @@ mymain(void) TEST_BITMAP_BLOCKCOMMIT("empty", 1, 2, "empty"); - TEST_BITMAP_BLOCKCOMMIT("basic-1-2", 1, 2, "basic"); - TEST_BITMAP_BLOCKCOMMIT("basic-1-3", 1, 3, "basic"); - TEST_BITMAP_BLOCKCOMMIT("basic-2-3", 2, 3, "basic"); - - TEST_BITMAP_BLOCKCOMMIT("snapshots-1-2", 1, 2, "snapshots"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-1-3", 1, 3, "snapshots"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-1-4", 1, 4, "snapshots"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-1-5", 1, 5, "snapshots"); - - TEST_BITMAP_BLOCKCOMMIT("snapshots-2-3", 2, 3, "snapshots"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-2-4", 2, 4, "snapshots"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-2-5", 2, 5, "snapshots"); - - TEST_BITMAP_BLOCKCOMMIT("snapshots-3-4", 3, 4, "snapshots"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-3-5", 3, 5, "snapshots"); - - TEST_BITMAP_BLOCKCOMMIT("snapshots-4-5", 4, 5, "snapshots"); - - TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-1-2", 1, 2, "snapshots-synthetic-broken"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-1-3", 1, 3, "snapshots-synthetic-broken"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-1-4", 1, 4, "snapshots-synthetic-broken"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-1-5", 1, 5, "snapshots-synthetic-broken"); - - TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-2-3", 2, 3, "snapshots-synthetic-broken"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-2-4", 2, 4, "snapshots-synthetic-broken"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-2-5", 2, 5, "snapshots-synthetic-broken"); - - TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-3-4", 3, 4, "snapshots-synthetic-broken"); - TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-3-5", 3, 5, "snapshots-synthetic-broken"); - - TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-4-5", 4, 5, "snapshots-synthetic-broken"); - cleanup: qemuTestDriverFree(&driver); VIR_FREE(capslatest_x86_64); diff --git a/tests/qemublocktestdata/backupmerge/basic-deep-out.json b/tests/qemublocktestdata/backupmerge/basic-deep-out.json deleted file mode 100644 index 28c3d16259..0000000000 --- a/tests/qemublocktestdata/backupmerge/basic-deep-out.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "node": "libvirt-1-format", - "name": "current" - }, - { - "node": "libvirt-1-format", - "name": "d" - }, - { - "node": "libvirt-1-format", - "name": "c" - }, - { - "node": "libvirt-1-format", - "name": "b" - }, - { - "node": "libvirt-1-format", - "name": "a" - } -] diff --git a/tests/qemublocktestdata/backupmerge/basic-flat-out.json b/tests/qemublocktestdata/backupmerge/basic-flat-out.json deleted file mode 100644 index b89252e284..0000000000 --- a/tests/qemublocktestdata/backupmerge/basic-flat-out.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - { - "node": "libvirt-1-format", - "name": "current" - } -] diff --git a/tests/qemublocktestdata/backupmerge/basic-intermediate-out.json b/tests/qemublocktestdata/backupmerge/basic-intermediate-out.json deleted file mode 100644 index 0dffcafd5f..0000000000 --- a/tests/qemublocktestdata/backupmerge/basic-intermediate-out.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "node": "libvirt-1-format", - "name": "current" - }, - { - "node": "libvirt-1-format", - "name": "d" - } -] diff --git a/tests/qemublocktestdata/backupmerge/snapshot-deep-out.json b/tests/qemublocktestdata/backupmerge/snapshot-deep-out.json deleted file mode 100644 index 526fc8d55b..0000000000 --- a/tests/qemublocktestdata/backupmerge/snapshot-deep-out.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "node": "libvirt-1-format", - "name": "current" - }, - { - "node": "libvirt-1-format", - "name": "d" - }, - { - "node": "libvirt-2-format", - "name": "d" - }, - { - "node": "libvirt-2-format", - "name": "c" - }, - { - "node": "libvirt-3-format", - "name": "c" - }, - { - "node": "libvirt-3-format", - "name": "b" - }, - { - "node": "libvirt-3-format", - "name": "a" - }, - { - "node": "libvirt-4-format", - "name": "a" - }, - { - "node": "libvirt-5-format", - "name": "a" - } -] diff --git a/tests/qemublocktestdata/backupmerge/snapshot-flat-out.json b/tests/qemublocktestdata/backupmerge/snapshot-flat-out.json deleted file mode 100644 index b89252e284..0000000000 --- a/tests/qemublocktestdata/backupmerge/snapshot-flat-out.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - { - "node": "libvirt-1-format", - "name": "current" - } -] diff --git a/tests/qemublocktestdata/backupmerge/snapshot-intermediate-out.json b/tests/qemublocktestdata/backupmerge/snapshot-intermediate-out.json deleted file mode 100644 index 537d776ec6..0000000000 --- a/tests/qemublocktestdata/backupmerge/snapshot-intermediate-out.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "node": "libvirt-1-format", - "name": "current" - }, - { - "node": "libvirt-1-format", - "name": "d" - }, - { - "node": "libvirt-2-format", - "name": "d" - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/basic-1-2 b/tests/qemublocktestdata/bitmapblockcommit/basic-1-2 deleted file mode 100644 index 8eeb4c3a11..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/basic-1-2 +++ /dev/null @@ -1,119 +0,0 @@ -pre job bitmap disable: -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-2-format", - "name": "a", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-2-format", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-2-format", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-2-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-2-format", - "name": "d", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/basic-1-3 b/tests/qemublocktestdata/bitmapblockcommit/basic-1-3 deleted file mode 100644 index 71b48e31a5..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/basic-1-3 +++ /dev/null @@ -1,119 +0,0 @@ -pre job bitmap disable: -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "a", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "d", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/basic-2-3 b/tests/qemublocktestdata/bitmapblockcommit/basic-2-3 deleted file mode 100644 index bfc58f994e..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/basic-2-3 +++ /dev/null @@ -1,2 +0,0 @@ -pre job bitmap disable: -merge bitmpas: diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2 deleted file mode 100644 index 0015b9ceb3..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2 +++ /dev/null @@ -1,49 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-2-format", - "name": "d" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-2-format", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3 deleted file mode 100644 index 5691b408aa..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3 +++ /dev/null @@ -1,76 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-3-format", - "name": "c" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "d", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - }, - { - "node": "libvirt-2-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4 deleted file mode 100644 index 454001531a..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4 +++ /dev/null @@ -1,126 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-4-format", - "name": "a" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - }, - { - "node": "libvirt-3-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "d", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - }, - { - "node": "libvirt-2-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5 deleted file mode 100644 index 2fd43d7917..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5 +++ /dev/null @@ -1,130 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-5-format", - "name": "a" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "a" - }, - { - "node": "libvirt-4-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - }, - { - "node": "libvirt-3-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "d", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - }, - { - "node": "libvirt-2-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3 deleted file mode 100644 index d719a90bd7..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3 +++ /dev/null @@ -1,49 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-3-format", - "name": "c" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "d", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4 deleted file mode 100644 index 9e37962344..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4 +++ /dev/null @@ -1,99 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-4-format", - "name": "a" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - }, - { - "node": "libvirt-3-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "d", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5 deleted file mode 100644 index d6b20a5d05..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5 +++ /dev/null @@ -1,103 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-5-format", - "name": "a" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "a" - }, - { - "node": "libvirt-4-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - }, - { - "node": "libvirt-3-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "d", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4 deleted file mode 100644 index b96e8910d7..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4 +++ /dev/null @@ -1,72 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-4-format", - "name": "a" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "c", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "c" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5 deleted file mode 100644 index 9570c34c40..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5 +++ /dev/null @@ -1,76 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-5-format", - "name": "a" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "a" - }, - { - "node": "libvirt-4-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "c", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "c" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5 deleted file mode 100644 index 7e1020d96e..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5 +++ /dev/null @@ -1,33 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-5-format", - "name": "a" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-5-format", - "name": "a" - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-4-format", - "name": "a" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2 deleted file mode 100644 index 463120d442..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2 +++ /dev/null @@ -1,57 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-2-format", - "name": "oa" - } - }, - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-2-format", - "name": "ob" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-2-format", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-2-format", - "name": "oa" - } - }, - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-2-format", - "name": "ob" - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3 deleted file mode 100644 index fec6f95dd1..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3 +++ /dev/null @@ -1,112 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-3-format", - "name": "b" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-3-format", - "name": "b" - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "oa", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "oa", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "oa" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "ob", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "ob", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "ob" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4 deleted file mode 100644 index 697230f67b..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4 +++ /dev/null @@ -1,119 +0,0 @@ -pre job bitmap disable: -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "b", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "oa", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "oa", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "oa" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "ob", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "ob", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "ob" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5 deleted file mode 100644 index 6bf1f0da64..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5 +++ /dev/null @@ -1,119 +0,0 @@ -pre job bitmap disable: -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "b", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "oa", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "oa", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "oa" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "ob", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "ob", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "ob" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3 deleted file mode 100644 index f202bb94b1..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3 +++ /dev/null @@ -1,89 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-3-format", - "name": "b" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-3-format", - "name": "b" - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "oa", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "oa", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "oa" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-3-format", - "name": "ob", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "ob", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "ob" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4 deleted file mode 100644 index 864cc9041b..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4 +++ /dev/null @@ -1,96 +0,0 @@ -pre job bitmap disable: -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "b", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "oa", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "oa", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "oa" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "ob", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "ob", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "ob" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5 deleted file mode 100644 index 4c5d8dbe80..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5 +++ /dev/null @@ -1,96 +0,0 @@ -pre job bitmap disable: -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "b", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "oa", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "oa", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "oa" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "ob", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "ob", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "ob" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-4 deleted file mode 100644 index 367a930a74..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-4 +++ /dev/null @@ -1,27 +0,0 @@ -pre job bitmap disable: -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-4-format", - "name": "b", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-4-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-5 deleted file mode 100644 index 0062ec140c..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-5 +++ /dev/null @@ -1,27 +0,0 @@ -pre job bitmap disable: -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-5-format", - "name": "b", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-5-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-4-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-4-5 deleted file mode 100644 index b1f10a8a24..0000000000 --- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-4-5 +++ /dev/null @@ -1,20 +0,0 @@ -pre job bitmap disable: -[ - { - "type": "block-dirty-bitmap-disable", - "data": { - "node": "libvirt-5-format", - "name": "a" - } - } -] -merge bitmpas: -[ - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-5-format", - "name": "a" - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json b/tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json deleted file mode 100644 index 4ed2b97e95..0000000000 --- a/tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json +++ /dev/null @@ -1,117 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "a", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "d", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json b/tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json deleted file mode 100644 index 4ed2b97e95..0000000000 --- a/tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json +++ /dev/null @@ -1,117 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "a", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "d", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json b/tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json deleted file mode 100644 index 5456553d78..0000000000 --- a/tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json +++ /dev/null @@ -1,133 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "a", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "a" - }, - { - "node": "libvirt-4-format", - "name": "a" - }, - { - "node": "libvirt-5-format", - "name": "a" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - }, - { - "node": "libvirt-3-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "d", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - }, - { - "node": "libvirt-2-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json b/tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json deleted file mode 100644 index ddd47f7ee1..0000000000 --- a/tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json +++ /dev/null @@ -1,48 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "current", - "persistent": true, - "disabled": false, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "current", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "mirror-format-node", - "name": "d", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "mirror-format-node", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - } - ] - } - } -] diff --git a/tests/qemublocktestdata/checkpointdelete/basic-current-out.json b/tests/qemublocktestdata/checkpointdelete/basic-current-out.json deleted file mode 100644 index 1b607567e8..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/basic-current-out.json +++ /dev/null @@ -1,29 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-1-format", - "name": "d" - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-1-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-1-format", - "name": "current" - } - } -] diff --git a/tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json deleted file mode 100644 index eccb7ed15f..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-1-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-1-format", - "name": "b" - } - } -] diff --git a/tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json deleted file mode 100644 index de40e4b5b0..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-1-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-1-format", - "name": "c" - } - } -] diff --git a/tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json deleted file mode 100644 index b5d85f43f0..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-1-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-1-format", - "name": "d" - } - } -] diff --git a/tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json deleted file mode 100644 index e87382fdb4..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-1-format", - "name": "a" - } - } -] diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json deleted file mode 100644 index 1b607567e8..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json +++ /dev/null @@ -1,29 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-1-format", - "name": "d" - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-1-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-1-format", - "name": "current" - } - } -] diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json deleted file mode 100644 index c9bda3a17a..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json +++ /dev/null @@ -1,24 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-3-format", - "name": "b" - } - } -] -reopen nodes: -libvirt-3-format diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json deleted file mode 100644 index 8a0e3f2cff..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json +++ /dev/null @@ -1,62 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-2-format", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-2-format", - "name": "c" - } - }, - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-3-format", - "name": "b" - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-3-format", - "name": "c" - } - } -] -reopen nodes: -libvirt-3-format -libvirt-2-format diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json deleted file mode 100644 index 211bc40baf..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json +++ /dev/null @@ -1,61 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-1-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-1-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-1-format", - "name": "d" - } - }, - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-2-format", - "name": "c" - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "d" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-2-format", - "name": "d" - } - } -] -reopen nodes: -libvirt-2-format diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json deleted file mode 100644 index f750f44da2..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-3-format", - "name": "a" - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-4-format", - "name": "a" - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-5-format", - "name": "a" - } - } -] -reopen nodes: -libvirt-5-format -libvirt-4-format -libvirt-3-format diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-current-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-current-out.json deleted file mode 100644 index 1b607567e8..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-current-out.json +++ /dev/null @@ -1,29 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-1-format", - "name": "d" - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-1-format", - "target": "d", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "current" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-1-format", - "name": "current" - } - } -] diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json deleted file mode 100644 index d7e6d18637..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json +++ /dev/null @@ -1,31 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-3-format", - "name": "a" - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-3-format", - "target": "a", - "bitmaps": [ - { - "node": "libvirt-3-format", - "name": "b" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-3-format", - "name": "b" - } - } -] -reopen nodes: -libvirt-3-format diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json deleted file mode 100644 index cfbff010c2..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json +++ /dev/null @@ -1,34 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-2-format", - "name": "b", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "b", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "c" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-2-format", - "name": "c" - } - } -] -reopen nodes: -libvirt-2-format diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json deleted file mode 100644 index 211bc40baf..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json +++ /dev/null @@ -1,61 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-add", - "data": { - "node": "libvirt-1-format", - "name": "c", - "persistent": true, - "disabled": true, - "granularity": 65536 - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-1-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-1-format", - "name": "d" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-1-format", - "name": "d" - } - }, - { - "type": "block-dirty-bitmap-enable", - "data": { - "node": "libvirt-2-format", - "name": "c" - } - }, - { - "type": "block-dirty-bitmap-merge", - "data": { - "node": "libvirt-2-format", - "target": "c", - "bitmaps": [ - { - "node": "libvirt-2-format", - "name": "d" - } - ] - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-2-format", - "name": "d" - } - } -] -reopen nodes: -libvirt-2-format diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json deleted file mode 100644 index f750f44da2..0000000000 --- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-3-format", - "name": "a" - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-4-format", - "name": "a" - } - }, - { - "type": "block-dirty-bitmap-remove", - "data": { - "node": "libvirt-5-format", - "name": "a" - } - } -] -reopen nodes: -libvirt-5-format -libvirt-4-format -libvirt-3-format -- 2.26.2

They will be replaced by a different set which will test scenarios relevant for the new semantics. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 3 - .../bitmap/snapshots-synthetic-broken.json | 837 ------------------ .../bitmap/snapshots-synthetic-broken.out | 14 - .../snapshots-synthetic-checkpoint.json | 827 ----------------- .../bitmap/snapshots-synthetic-checkpoint.out | 13 - tests/qemublocktestdata/bitmap/synthetic.json | 118 --- tests/qemublocktestdata/bitmap/synthetic.out | 6 - 7 files changed, 1818 deletions(-) delete mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json delete mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out delete mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.json delete mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.out delete mode 100644 tests/qemublocktestdata/bitmap/synthetic.json delete mode 100644 tests/qemublocktestdata/bitmap/synthetic.out diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index d2f105486e..28cbaeba38 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1293,10 +1293,7 @@ mymain(void) TEST_BITMAP_DETECT("empty"); TEST_BITMAP_DETECT("basic"); - TEST_BITMAP_DETECT("synthetic"); TEST_BITMAP_DETECT("snapshots"); - TEST_BITMAP_DETECT("snapshots-synthetic-checkpoint"); - TEST_BITMAP_DETECT("snapshots-synthetic-broken"); #define TEST_BACKUP_BITMAP_CALCULATE(testname, source, incrbackup, named) \ do { \ diff --git a/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json b/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json deleted file mode 100644 index 8cf14d4baa..0000000000 --- a/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json +++ /dev/null @@ -1,837 +0,0 @@ -[ - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "backing-image": { - "backing-image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911527", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 217088, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "c", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "b", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911522", - "backing-filename": "/tmp/pull4.1575911522", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911540", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 212992, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "d", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "c", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911527", - "backing-filename": "/tmp/pull4.1575911527", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911550", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 212992, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "in-use", - "auto" - ], - "name": "current", - "granularity": 65536 - }, - { - "flags": [ - "in-use" - ], - "name": "d", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911540", - "backing-filename": "/tmp/pull4.1575911540", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-1-format", - "backing_file_depth": 4, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.1575911540", - "dirty-bitmaps": [ - { - "name": "d", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, - { - "name": "current", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911550", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 393728, - "filename": "/tmp/pull4.1575911550", - "format": "file", - "actual-size": 212992, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-1-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911550", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "backing-image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911527", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 217088, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "c", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "b", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911522", - "backing-filename": "/tmp/pull4.1575911522", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911540", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 212992, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "d", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "c", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911527", - "backing-filename": "/tmp/pull4.1575911527", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-2-format", - "backing_file_depth": 3, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.1575911527", - "dirty-bitmaps": [ - { - "name": "c", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, - { - "name": "oa", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - }, - { - "name": "ob", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - }, - { - "name": "d", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "inconsistent": true, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911540", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 393728, - "filename": "/tmp/pull4.1575911540", - "format": "file", - "actual-size": 212992, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-2-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911540", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911527", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 217088, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "c", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "b", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911522", - "backing-filename": "/tmp/pull4.1575911522", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-3-format", - "backing_file_depth": 2, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.1575911522", - "dirty-bitmaps": [ - { - "name": "a", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, - { - "name": "b", - "recording": true, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911527", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 459264, - "filename": "/tmp/pull4.1575911527", - "format": "file", - "actual-size": 217088, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-3-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911527", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-4-format", - "backing_file_depth": 1, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.qcow2", - "dirty-bitmaps": [ - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911522", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 328192, - "filename": "/tmp/pull4.1575911522", - "format": "file", - "actual-size": 208896, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-4-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911522", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-5-format", - "backing_file_depth": 0, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "dirty-bitmaps": [ - { - "name": "a", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.qcow2", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 328192, - "filename": "/tmp/pull4.qcow2", - "format": "file", - "actual-size": 208896, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-5-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.qcow2", - "encryption_key_missing": false - } -] diff --git a/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out b/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out deleted file mode 100644 index ad24a580f1..0000000000 --- a/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out +++ /dev/null @@ -1,14 +0,0 @@ -libvirt-1-format: - d: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 -libvirt-2-format: - c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - oa: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - ob: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - d: record:1 busy:0 persist:1 inconsist:1 gran:65536 dirty:0 -libvirt-3-format: - a: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 -libvirt-4-format: -libvirt-5-format: - a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 diff --git a/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.json b/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.json deleted file mode 100644 index 25cc150d67..0000000000 --- a/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.json +++ /dev/null @@ -1,827 +0,0 @@ -[ - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "backing-image": { - "backing-image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911527", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 217088, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "c", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "b", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911522", - "backing-filename": "/tmp/pull4.1575911522", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911540", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 212992, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "d", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "c", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911527", - "backing-filename": "/tmp/pull4.1575911527", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911550", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 212992, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "in-use", - "auto" - ], - "name": "current", - "granularity": 65536 - }, - { - "flags": [ - "in-use" - ], - "name": "d", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911540", - "backing-filename": "/tmp/pull4.1575911540", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-1-format", - "backing_file_depth": 4, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.1575911540", - "dirty-bitmaps": [ - { - "name": "d", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, - { - "name": "current", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911550", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 393728, - "filename": "/tmp/pull4.1575911550", - "format": "file", - "actual-size": 212992, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-1-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911550", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "backing-image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911527", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 217088, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "c", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "b", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911522", - "backing-filename": "/tmp/pull4.1575911522", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911540", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 212992, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "d", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "c", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911527", - "backing-filename": "/tmp/pull4.1575911527", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-2-format", - "backing_file_depth": 3, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.1575911527", - "dirty-bitmaps": [ - { - "name": "c", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, - { - "name": "d", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911540", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 393728, - "filename": "/tmp/pull4.1575911540", - "format": "file", - "actual-size": 212992, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-2-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911540", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911527", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 217088, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "c", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "b", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911522", - "backing-filename": "/tmp/pull4.1575911522", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-3-format", - "backing_file_depth": 2, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.1575911522", - "dirty-bitmaps": [ - { - "name": "a", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, - { - "name": "b", - "recording": true, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911527", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 459264, - "filename": "/tmp/pull4.1575911527", - "format": "file", - "actual-size": 217088, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-3-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911527", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-4-format", - "backing_file_depth": 1, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.qcow2", - "dirty-bitmaps": [ - { - "name": "a", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911522", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 328192, - "filename": "/tmp/pull4.1575911522", - "format": "file", - "actual-size": 208896, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-4-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911522", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-5-format", - "backing_file_depth": 0, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "dirty-bitmaps": [ - { - "name": "a", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.qcow2", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 328192, - "filename": "/tmp/pull4.qcow2", - "format": "file", - "actual-size": 208896, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-5-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.qcow2", - "encryption_key_missing": false - } -] diff --git a/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.out b/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.out deleted file mode 100644 index 0270657001..0000000000 --- a/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.out +++ /dev/null @@ -1,13 +0,0 @@ -libvirt-1-format: - d: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 -libvirt-2-format: - 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-format: - a: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 -libvirt-4-format: - a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 -libvirt-5-format: - a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 diff --git a/tests/qemublocktestdata/bitmap/synthetic.json b/tests/qemublocktestdata/bitmap/synthetic.json deleted file mode 100644 index 56882bd615..0000000000 --- a/tests/qemublocktestdata/bitmap/synthetic.json +++ /dev/null @@ -1,118 +0,0 @@ -[ - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 200704, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-1-format", - "backing_file_depth": 0, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "dirty-bitmaps": [ - { - "name": "current", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - }, - { - "name": "d", - "recording": false, - "persistent": false, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, - { - "name": "c", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 1234, - "count": 0 - }, - { - "name": "b", - "recording": false, - "persistent": true, - "busy": true, - "status": "disabled", - "granularity": 65536, - "count": 21314 - }, - { - "name": "a", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "inconsistent": true, - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.qcow2", - "encryption_key_missing": false - }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 197120, - "filename": "/tmp/pull4.qcow2", - "format": "file", - "actual-size": 200704, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-1-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.qcow2", - "encryption_key_missing": false - } -] diff --git a/tests/qemublocktestdata/bitmap/synthetic.out b/tests/qemublocktestdata/bitmap/synthetic.out deleted file mode 100644 index e8041c5b77..0000000000 --- a/tests/qemublocktestdata/bitmap/synthetic.out +++ /dev/null @@ -1,6 +0,0 @@ -libvirt-1-format: - current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - d: record:0 busy:0 persist:0 inconsist:0 gran:65536 dirty:0 - c: record:0 busy:0 persist:1 inconsist:0 gran:1234 dirty:0 - b: record:0 busy:1 persist:1 inconsist:0 gran:65536 dirty:21314 - a: record:0 busy:0 persist:1 inconsist:1 gran:65536 dirty:0 -- 2.26.2

There will be multiple places where we'll need to print nodenames from a GSList of virStorageSource for testing purposes. Extract the code into a function. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 28cbaeba38..0ed9b99bc4 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -647,6 +647,23 @@ testQemuDetectBitmaps(const void *opaque) } +static void +testQemuBitmapListPrint(const char *title, + GSList *next, + virBufferPtr buf) +{ + if (!next) + return; + + virBufferAsprintf(buf, "%s\n", title); + + for (; next; next = next->next) { + virStorageSourcePtr src = next->data; + virBufferAsprintf(buf, "%s\n", src->nodeformat); + } +} + + static virStorageSourcePtr testQemuBackupIncrementalBitmapCalculateGetFakeImage(size_t idx) { @@ -829,7 +846,6 @@ testQemuCheckpointDeleteMerge(const void *opaque) g_autoptr(virHashTable) nodedata = NULL; g_autoptr(GSList) reopenimages = NULL; g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; - GSList *tmp; expectpath = g_strdup_printf("%s/%s%s-out.json", abs_srcdir, checkpointDeletePrefix, data->name); @@ -858,14 +874,7 @@ testQemuCheckpointDeleteMerge(const void *opaque) virBufferAddLit(&buf, "NULL\n"); } - if (reopenimages) { - virBufferAddLit(&buf, "reopen nodes:\n"); - - for (tmp = reopenimages; tmp; tmp = tmp->next) { - virStorageSourcePtr src = tmp->data; - virBufferAsprintf(&buf, "%s\n", src->nodeformat); - } - } + testQemuBitmapListPrint("reopen nodes:", reopenimages, &buf); actual = virBufferContentAndReset(&buf); -- 2.26.2

Chaining bitmaps for checkpoints (disabling the active one and creating a new) severely overcomplicated all operations in regards to bitmaps. Specifically it requires us re-matching the on-disk state to the internal metadata and in case of merging during block jobs it makes it almost impossible to cover all corner cases. Since the checkpoints and incremental backups were not yet enabled, let's change the design to keep one bitmap per checkpoint. In case of layered snapshots this will be filled in by using dirty-bitmap-populate. Finally the main reason for this unnecessary complexity was the fear that qemu's performance could degrade. In the end I think that addressing the performance issue will be better done in qemu (e.g by keeping an internal bitmap updated with changes and merging it periodically back to the real bitmaps. QEMU writes out changes to disk at shutdown so consistency is not a problem). Removing the relationships between bitmaps frees us from complex handling and also makes all the surrounding code more robust as one broken bitmap doesn't necessarily invalidate whole chains of backups. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_checkpoint.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c index b71b4a7d14..9b4f3ad396 100644 --- a/src/qemu/qemu_checkpoint.c +++ b/src/qemu/qemu_checkpoint.c @@ -456,7 +456,6 @@ qemuCheckpointPrepare(virQEMUDriverPtr driver, static int qemuCheckpointAddActions(virDomainObjPtr vm, virJSONValuePtr actions, - virDomainMomentObjPtr old_current, virDomainCheckpointDefPtr def) { size_t i; @@ -464,7 +463,6 @@ qemuCheckpointAddActions(virDomainObjPtr vm, for (i = 0; i < def->ndisks; i++) { virDomainCheckpointDiskDef *chkdisk = &def->disks[i]; virDomainDiskDefPtr domdisk = virDomainDiskByTarget(vm->def, chkdisk->name); - virDomainCheckpointDiskDef *parentchkdisk = NULL; /* checkpoint definition validator mandates that the corresponding * domdisk should exist */ @@ -475,23 +473,6 @@ qemuCheckpointAddActions(virDomainObjPtr vm, if (qemuMonitorTransactionBitmapAdd(actions, domdisk->src->nodeformat, chkdisk->bitmap, true, false, 0) < 0) return -1; - - /* We only want one active bitmap for a disk along the - * checkpoint chain, then later differential backups will - * merge the bitmaps (only one active) between the bounding - * checkpoint and the leaf checkpoint. If the same disks are - * involved in each checkpoint, this search terminates in one - * iteration; but it is also possible to have to search - * further than the immediate parent to find another - * checkpoint with a bitmap on the same disk. */ - if ((parentchkdisk = qemuCheckpointFindActiveDiskInParent(vm, old_current, - chkdisk->name))) { - - if (qemuMonitorTransactionBitmapDisable(actions, - domdisk->src->nodeformat, - parentchkdisk->bitmap) < 0) - return -1; - } } return 0; } @@ -540,7 +521,7 @@ qemuCheckpointCreateCommon(virQEMUDriverPtr driver, tmpactions = virJSONValueNewArray(); - if (qemuCheckpointAddActions(vm, tmpactions, parent, *def) < 0) + if (qemuCheckpointAddActions(vm, tmpactions, *def) < 0) return -1; if (!(*chk = virDomainCheckpointAssignDef(vm->checkpoints, *def))) -- 2.26.2

Use test data which conforms to the new semantics which changed in the previous patch. The test data was created by the same set of commands as originally in commit 9aac9d5bdab039a50de2d8c627b3a1f1578ed471 Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktestdata/bitmap/basic.json | 229 +++++++++++----------- tests/qemublocktestdata/bitmap/basic.out | 8 +- 2 files changed, 119 insertions(+), 118 deletions(-) diff --git a/tests/qemublocktestdata/bitmap/basic.json b/tests/qemublocktestdata/bitmap/basic.json index 9d418b1a37..718106bf99 100644 --- a/tests/qemublocktestdata/bitmap/basic.json +++ b/tests/qemublocktestdata/bitmap/basic.json @@ -1,117 +1,118 @@ [ - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 200704, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-1-format", - "backing_file_depth": 0, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "dirty-bitmaps": [ - { - "name": "current", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - }, - { - "name": "d", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, - { - "name": "c", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, - { - "name": "b", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, - { - "name": "a", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.qcow2", - "encryption_key_missing": false + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.qcow2", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 200704, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false + } + }, + "dirty-flag": false }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 197120, - "filename": "/tmp/pull4.qcow2", - "format": "file", - "actual-size": 200704, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-1-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.qcow2", - "encryption_key_missing": false - } + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-1-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "dirty-bitmaps": [ + { + "name": "current", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + }, + { + "name": "d", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + }, + { + "name": "c", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + }, + { + "name": "b", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + }, + { + "name": "a", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + } + ], + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.qcow2", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 197120, + "filename": "/tmp/bitmaps.qcow2", + "format": "file", + "actual-size": 200704, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-1-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.qcow2", + "encryption_key_missing": false + } ] diff --git a/tests/qemublocktestdata/bitmap/basic.out b/tests/qemublocktestdata/bitmap/basic.out index 539f7d9bad..5c4c35b3f0 100644 --- a/tests/qemublocktestdata/bitmap/basic.out +++ b/tests/qemublocktestdata/bitmap/basic.out @@ -1,6 +1,6 @@ libvirt-1-format: current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - d: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - b: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - a: 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 + 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 -- 2.26.2

With the upcoming changes to use 'dirty-bitmap-populate' job, this will no longer be required to do the backups, so we can stop creating bitmaps which would be pointless. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_driver.c | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 88517ba6a7..5a3b3bb35b 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15016,44 +15016,6 @@ qemuDomainSnapshotDiskCleanup(qemuDomainSnapshotDiskDataPtr data, } -/** - * qemuDomainSnapshotDiskBitmapsPropagate: - * - * This function propagates any active persistent bitmap present in the original - * image into the new snapshot. This is necessary to keep tracking the changed - * blocks in the active bitmaps as the backing file will become read-only. - * We leave the original bitmap active as in cases when the overlay is - * discarded (snapshot revert with abandoning the history) everything works as - * expected. - */ -static int -qemuDomainSnapshotDiskBitmapsPropagate(qemuDomainSnapshotDiskDataPtr dd, - virJSONValuePtr actions, - virHashTablePtr blockNamedNodeData) -{ - qemuBlockNamedNodeDataPtr entry; - size_t i; - - if (!(entry = virHashLookup(blockNamedNodeData, dd->disk->src->nodeformat))) - return 0; - - for (i = 0; i < entry->nbitmaps; i++) { - qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i]; - - /* we don't care about temporary, inconsistent, or disabled bitmaps */ - if (!bitmap->persistent || !bitmap->recording || bitmap->inconsistent) - continue; - - if (qemuMonitorTransactionBitmapAdd(actions, dd->src->nodeformat, - bitmap->name, true, false, - bitmap->granularity) < 0) - return -1; - } - - return 0; -} - - static int qemuDomainSnapshotDiskPrepareOneBlockdev(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -15200,9 +15162,6 @@ qemuDomainSnapshotDiskPrepareOne(virQEMUDriverPtr driver, blockNamedNodeData, asyncJob) < 0) return -1; - if (qemuDomainSnapshotDiskBitmapsPropagate(dd, actions, blockNamedNodeData) < 0) - return -1; - if (qemuBlockSnapshotAddBlockdev(actions, dd->disk, dd->src) < 0) return -1; } else { -- 2.26.2

On 6/9/20 10:00 AM, Peter Krempa wrote:
With the upcoming changes to use 'dirty-bitmap-populate' job, this will no longer be required to do the backups, so we can stop creating bitmaps which would be pointless.
Even if qemu 5.1 adds block-dirty-bitmap-populate, don't we still want to keep supporting qemu 5.0 where it was not present, and therefore need code for propagating bitmaps during snapshot creation? Or is the plan that you won't enable incremental backup support in libvirt unless you detect new enough qemu including bitmap-populate support? -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org

Use test data which conforms to the new semantics which changed in the previous patch. The test data was created by the same set of commands as originally in commit 0b27b655b1bac480186ce80457113cd5dc34e6a1 Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktestdata/bitmap/snapshots.json | 1254 ++++++----------- tests/qemublocktestdata/bitmap/snapshots.out | 6 +- 2 files changed, 440 insertions(+), 820 deletions(-) diff --git a/tests/qemublocktestdata/bitmap/snapshots.json b/tests/qemublocktestdata/bitmap/snapshots.json index 87e77ad408..054269d9bc 100644 --- a/tests/qemublocktestdata/bitmap/snapshots.json +++ b/tests/qemublocktestdata/bitmap/snapshots.json @@ -1,836 +1,460 @@ [ - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "backing-image": { - "backing-image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911527", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 217088, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "c", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "b", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911522", - "backing-filename": "/tmp/pull4.1575911522", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911540", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 212992, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "d", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "c", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911527", - "backing-filename": "/tmp/pull4.1575911527", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911550", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 212992, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "in-use", - "auto" - ], - "name": "current", - "granularity": 65536 - }, - { - "flags": [ - "in-use" - ], - "name": "d", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911540", - "backing-filename": "/tmp/pull4.1575911540", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-1-format", - "backing_file_depth": 4, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.1575911540", - "dirty-bitmaps": [ - { - "name": "d", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "backing-filename-format": "qcow2", + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.1590749073", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 208896, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "bitmaps": [ { - "name": "current", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 + "flags": [ + "in-use", + "auto" + ], + "name": "current", + "granularity": 65536 } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911550", - "encryption_key_missing": false + ], + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "/tmp/bitmaps.1590749012", + "backing-filename": "/tmp/bitmaps.1590749012", + "dirty-flag": false }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 393728, - "filename": "/tmp/pull4.1575911550", - "format": "file", - "actual-size": 212992, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-1-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911550", - "encryption_key_missing": false + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-1-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "backing_file": "/tmp/bitmaps.1590749012", + "dirty-bitmaps": [ + { + "name": "current", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + } + ], + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "backing-image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911527", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 217088, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "c", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "b", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911522", - "backing-filename": "/tmp/pull4.1575911522", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911540", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 212992, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "d", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "c", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911527", - "backing-filename": "/tmp/pull4.1575911527", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-2-format", - "backing_file_depth": 3, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.1575911527", - "dirty-bitmaps": [ - { - "name": "c", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, + "file": "/tmp/bitmaps.1590749073", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 328192, + "filename": "/tmp/bitmaps.1590749073", + "format": "file", + "actual-size": 208896, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-1-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590749073", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "backing-filename-format": "qcow2", + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.1590749012", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 208896, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "bitmaps": [ { - "name": "d", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 + "flags": [ + "auto" + ], + "name": "d", + "granularity": 65536 } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911540", - "encryption_key_missing": false + ], + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "/tmp/bitmaps.1590748995", + "backing-filename": "/tmp/bitmaps.1590748995", + "dirty-flag": false }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 393728, - "filename": "/tmp/pull4.1575911540", - "format": "file", - "actual-size": 212992, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-2-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911540", - "encryption_key_missing": false + "iops_wr": 0, + "ro": true, + "node-name": "libvirt-2-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "backing_file": "/tmp/bitmaps.1590748995", + "dirty-bitmaps": [ + { + "name": "d", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + } + ], + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911527", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 217088, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "c", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "b", - "granularity": 65536 - }, - { - "flags": [ - - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.1575911522", - "backing-filename": "/tmp/pull4.1575911522", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-3-format", - "backing_file_depth": 2, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.1575911522", - "dirty-bitmaps": [ - { - "name": "a", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 - }, + "file": "/tmp/bitmaps.1590749012", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 328192, + "filename": "/tmp/bitmaps.1590749012", + "format": "file", + "actual-size": 208896, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-2-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590749012", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "backing-filename-format": "qcow2", + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.1590748995", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 212992, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "bitmaps": [ { - "name": "b", - "recording": false, - "persistent": true, - "busy": false, - "status": "disabled", - "granularity": 65536, - "count": 0 + "flags": [ + "auto" + ], + "name": "c", + "granularity": 65536 }, { - "name": "c", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 + "flags": [ + "auto" + ], + "name": "b", + "granularity": 65536 } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911527", - "encryption_key_missing": false + ], + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "/tmp/bitmaps.1590748992", + "backing-filename": "/tmp/bitmaps.1590748992", + "dirty-flag": false }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 459264, - "filename": "/tmp/pull4.1575911527", - "format": "file", - "actual-size": 217088, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-3-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911527", - "encryption_key_missing": false + "iops_wr": 0, + "ro": true, + "node-name": "libvirt-3-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "backing_file": "/tmp/bitmaps.1590748992", + "dirty-bitmaps": [ + { + "name": "b", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + }, + { + "name": "c", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + } + ], + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "backing-image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "backing-filename-format": "qcow2", - "virtual-size": 10485760, - "filename": "/tmp/pull4.1575911522", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "full-backing-filename": "/tmp/pull4.qcow2", - "backing-filename": "/tmp/pull4.qcow2", - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-4-format", - "backing_file_depth": 1, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "backing_file": "/tmp/pull4.qcow2", - "dirty-bitmaps": [ - { - "name": "a", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 - } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911522", - "encryption_key_missing": false + "file": "/tmp/bitmaps.1590748995", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 393728, + "filename": "/tmp/bitmaps.1590748995", + "format": "file", + "actual-size": 212992, + "dirty-flag": false }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 328192, - "filename": "/tmp/pull4.1575911522", - "format": "file", - "actual-size": 208896, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-4-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.1575911522", - "encryption_key_missing": false + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-3-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 10485760, - "filename": "/tmp/pull4.qcow2", - "cluster-size": 65536, - "format": "qcow2", - "actual-size": 208896, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "bitmaps": [ - { - "flags": [ - "auto" - ], - "name": "a", - "granularity": 65536 - } - ], - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": true, - "node-name": "libvirt-5-format", - "backing_file_depth": 0, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "dirty-bitmaps": [ + "file": "/tmp/bitmaps.1590748995", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "backing-filename-format": "qcow2", + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.1590748992", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 200704, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "/tmp/bitmaps.qcow2", + "backing-filename": "/tmp/bitmaps.qcow2", + "dirty-flag": false + }, + "iops_wr": 0, + "ro": true, + "node-name": "libvirt-4-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "backing_file": "/tmp/bitmaps.qcow2", + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590748992", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 197120, + "filename": "/tmp/bitmaps.1590748992", + "format": "file", + "actual-size": 200704, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-4-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590748992", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.qcow2", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 208896, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "bitmaps": [ { - "name": "a", - "recording": true, - "persistent": true, - "busy": false, - "status": "active", - "granularity": 65536, - "count": 0 + "flags": [ + "auto" + ], + "name": "a", + "granularity": 65536 } - ], - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.qcow2", - "encryption_key_missing": false + ], + "refcount-bits": 16, + "corrupt": false + } + }, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": true, + "node-name": "libvirt-5-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "dirty-bitmaps": [ + { + "name": "a", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + } + ], + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.qcow2", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 328192, + "filename": "/tmp/bitmaps.qcow2", + "format": "file", + "actual-size": 208896, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-5-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true }, - { - "iops_rd": 0, - "detect_zeroes": "off", - "image": { - "virtual-size": 328192, - "filename": "/tmp/pull4.qcow2", - "format": "file", - "actual-size": 208896, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "node-name": "libvirt-5-storage", - "backing_file_depth": 0, - "drv": "file", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "/tmp/pull4.qcow2", - "encryption_key_missing": false - } + "file": "/tmp/bitmaps.qcow2", + "encryption_key_missing": false + } ] diff --git a/tests/qemublocktestdata/bitmap/snapshots.out b/tests/qemublocktestdata/bitmap/snapshots.out index 5dafe946cf..688c69c101 100644 --- a/tests/qemublocktestdata/bitmap/snapshots.out +++ b/tests/qemublocktestdata/bitmap/snapshots.out @@ -1,14 +1,10 @@ libvirt-1-format: - d: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 libvirt-2-format: - 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-format: - a: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 - b: record:0 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-4-format: - a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 libvirt-5-format: a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 -- 2.26.2

Reject duplicates and other problematic bitmaps according to the new semantics of bitmap use in libvirt. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 6f9c7071c9..f42fd200a3 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -2851,40 +2851,36 @@ qemuBlockGetNamedNodeData(virDomainObjPtr vm, * qemuBlockBitmapChainIsValid: * * Validates that the backing chain of @src contains proper consistent bitmap - * data for a chain of bitmaps named @bitmapname. + * @bitmapname. * - * A valid chain: - * 1) bitmaps of same name are in a consecutive subset of images without gap - * 2) don't have any inconsistent bitmaps + * A valid bitmap: + * 1) There's only one such bitmap in the backing chain + * 2) It's persistent. + * 3) It's active + * 4) isn't incosistent */ bool qemuBlockBitmapChainIsValid(virStorageSourcePtr src, const char *bitmapname, virHashTablePtr blockNamedNodeData) { - qemuBlockNamedNodeDataBitmapPtr bitmap; virStorageSourcePtr n; - bool chain_started = false; - bool chain_ended = false; + bool found = false; - for (n = src; n; n = n->backingStore) { - if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, n, bitmapname))) { - if (chain_started) - chain_ended = true; + for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) { + qemuBlockNamedNodeDataBitmapPtr bitmap; + if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, + n, bitmapname))) continue; - } - if (chain_ended) + if (found || bitmap->inconsistent || !bitmap->persistent || !bitmap->recording) return false; - chain_started = true; - - if (bitmap->inconsistent) - return false; + found = true; } - return chain_started; + return found; } -- 2.26.2

Now that we've updated both the test data and the validator to new semantics we can start testing again. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 0ed9b99bc4..6d1bf3f250 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1346,6 +1346,18 @@ mymain(void) TEST_BITMAP_VALIDATE("empty", "a", false); + TEST_BITMAP_VALIDATE("basic", "a", true); + TEST_BITMAP_VALIDATE("basic", "b", true); + TEST_BITMAP_VALIDATE("basic", "c", true); + TEST_BITMAP_VALIDATE("basic", "d", true); + TEST_BITMAP_VALIDATE("basic", "current", true); + + TEST_BITMAP_VALIDATE("snapshots", "a", true); + TEST_BITMAP_VALIDATE("snapshots", "b", true); + TEST_BITMAP_VALIDATE("snapshots", "c", true); + TEST_BITMAP_VALIDATE("snapshots", "d", true); + TEST_BITMAP_VALIDATE("snapshots", "current", true); + #define TEST_BITMAP_BLOCKCOPY(testname, shllw, ndf) \ do { \ blockbitmapblockcopydata.name = testname; \ -- 2.26.2

Based on the 'snapshots' example with manual tweaks to introduce inactive, transient, inconsistent and duplicate bitmaps in various parts of the chain to excercise detection and new validation code. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 11 + tests/qemublocktestdata/bitmap/synthetic.json | 506 ++++++++++++++++++ tests/qemublocktestdata/bitmap/synthetic.out | 15 + 3 files changed, 532 insertions(+) create mode 100644 tests/qemublocktestdata/bitmap/synthetic.json create mode 100644 tests/qemublocktestdata/bitmap/synthetic.out diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 6d1bf3f250..63112eea24 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1303,6 +1303,7 @@ mymain(void) TEST_BITMAP_DETECT("basic"); TEST_BITMAP_DETECT("snapshots"); + TEST_BITMAP_DETECT("synthetic"); #define TEST_BACKUP_BITMAP_CALCULATE(testname, source, incrbackup, named) \ do { \ @@ -1358,6 +1359,16 @@ mymain(void) TEST_BITMAP_VALIDATE("snapshots", "d", true); TEST_BITMAP_VALIDATE("snapshots", "current", true); + TEST_BITMAP_VALIDATE("synthetic", "a", true); + TEST_BITMAP_VALIDATE("synthetic", "b", false); + TEST_BITMAP_VALIDATE("synthetic", "c", false); + TEST_BITMAP_VALIDATE("synthetic", "d", false); + TEST_BITMAP_VALIDATE("synthetic", "current", false); + TEST_BITMAP_VALIDATE("synthetic", "top-ok", true); + TEST_BITMAP_VALIDATE("synthetic", "top-inactive", false); + TEST_BITMAP_VALIDATE("synthetic", "top-transient", false); + TEST_BITMAP_VALIDATE("synthetic", "top-inactive-transient", false); + #define TEST_BITMAP_BLOCKCOPY(testname, shllw, ndf) \ do { \ blockbitmapblockcopydata.name = testname; \ diff --git a/tests/qemublocktestdata/bitmap/synthetic.json b/tests/qemublocktestdata/bitmap/synthetic.json new file mode 100644 index 0000000000..3712c8e5fc --- /dev/null +++ b/tests/qemublocktestdata/bitmap/synthetic.json @@ -0,0 +1,506 @@ +[ + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "backing-filename-format": "qcow2", + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.1590749073", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 208896, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "bitmaps": [ + { + "flags": [ + "in-use", + "auto" + ], + "name": "current", + "granularity": 65536 + } + ], + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "/tmp/bitmaps.1590749012", + "backing-filename": "/tmp/bitmaps.1590749012", + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-1-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "backing_file": "/tmp/bitmaps.1590749012", + "dirty-bitmaps": [ + { + "name": "current", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "inconsistent": true, + "granularity": 65536, + "count": 0 + }, + { + "name": "top-ok", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + }, + { + "name": "top-inactive", + "recording": false, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + }, + { + "name": "top-transient", + "recording": true, + "persistent": false, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + }, + { + "name": "top-transient-inactive", + "recording": false, + "persistent": false, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + } + ], + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590749073", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 328192, + "filename": "/tmp/bitmaps.1590749073", + "format": "file", + "actual-size": 208896, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-1-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590749073", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "backing-filename-format": "qcow2", + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.1590749012", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 208896, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "bitmaps": [ + { + "flags": [ + "auto" + ], + "name": "d", + "granularity": 65536 + } + ], + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "/tmp/bitmaps.1590748995", + "backing-filename": "/tmp/bitmaps.1590748995", + "dirty-flag": false + }, + "iops_wr": 0, + "ro": true, + "node-name": "libvirt-2-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "backing_file": "/tmp/bitmaps.1590748995", + "dirty-bitmaps": [ + { + "name": "d", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + } + ], + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590749012", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 328192, + "filename": "/tmp/bitmaps.1590749012", + "format": "file", + "actual-size": 208896, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-2-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590749012", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "backing-filename-format": "qcow2", + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.1590748995", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 212992, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "bitmaps": [ + { + "flags": [ + "auto" + ], + "name": "c", + "granularity": 65536 + }, + { + "flags": [ + "auto" + ], + "name": "b", + "granularity": 65536 + } + ], + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "/tmp/bitmaps.1590748992", + "backing-filename": "/tmp/bitmaps.1590748992", + "dirty-flag": false + }, + "iops_wr": 0, + "ro": true, + "node-name": "libvirt-3-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "backing_file": "/tmp/bitmaps.1590748992", + "dirty-bitmaps": [ + { + "name": "b", + "recording": true, + "persistent": false, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + }, + { + "name": "c", + "recording": false, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + }, + { + "name": "d", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + } + ], + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590748995", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 393728, + "filename": "/tmp/bitmaps.1590748995", + "format": "file", + "actual-size": 212992, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-3-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590748995", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "backing-filename-format": "qcow2", + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.1590748992", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 200704, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "/tmp/bitmaps.qcow2", + "backing-filename": "/tmp/bitmaps.qcow2", + "dirty-flag": false + }, + "iops_wr": 0, + "ro": true, + "node-name": "libvirt-4-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "backing_file": "/tmp/bitmaps.qcow2", + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590748992", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 197120, + "filename": "/tmp/bitmaps.1590748992", + "format": "file", + "actual-size": 200704, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-4-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.1590748992", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 10485760, + "filename": "/tmp/bitmaps.qcow2", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 208896, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "bitmaps": [ + { + "flags": [ + "auto" + ], + "name": "a", + "granularity": 65536 + } + ], + "refcount-bits": 16, + "corrupt": false + } + }, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": true, + "node-name": "libvirt-5-format", + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "dirty-bitmaps": [ + { + "name": "a", + "recording": true, + "persistent": true, + "busy": false, + "status": "active", + "granularity": 65536, + "count": 0 + } + ], + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.qcow2", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 328192, + "filename": "/tmp/bitmaps.qcow2", + "format": "file", + "actual-size": 208896, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-5-storage", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/bitmaps.qcow2", + "encryption_key_missing": false + } +] diff --git a/tests/qemublocktestdata/bitmap/synthetic.out b/tests/qemublocktestdata/bitmap/synthetic.out new file mode 100644 index 0000000000..cde7228e01 --- /dev/null +++ b/tests/qemublocktestdata/bitmap/synthetic.out @@ -0,0 +1,15 @@ +libvirt-1-format: + current: record:1 busy:0 persist:1 inconsist:1 gran:65536 dirty:0 + top-ok: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 + 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-2-format: + d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 +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-4-format: +libvirt-5-format: + a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0 -- 2.26.2

Now that we've switched to the simple handling, the first thing that can be massively simplified is checkpoint deletion. We now need to only go through the backing chain and find the appropriately named bitmaps and delete them, no complex lookups or merging. Note that compared to other functions this deletes the bitmap in all layers compared to others where we expect only exactly 1 bitmap of a name in the backing chain to prevent potential problems. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_checkpoint.c | 153 ++++++------------------------------- src/qemu/qemu_checkpoint.h | 1 - tests/qemublocktest.c | 7 +- 3 files changed, 25 insertions(+), 136 deletions(-) diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c index 9b4f3ad396..c24d97443c 100644 --- a/src/qemu/qemu_checkpoint.c +++ b/src/qemu/qemu_checkpoint.c @@ -105,140 +105,41 @@ qemuCheckpointWriteMetadata(virDomainObjPtr vm, } -/** - * qemuCheckpointFindActiveDiskInParent: - * @vm: domain object - * @from: starting moment object - * @diskname: name (target) of the disk to find - * - * Find the first checkpoint starting from @from continuing through parents - * of the checkpoint which describes disk @diskname. Return the pointer to the - * definition of the disk. - */ -static virDomainCheckpointDiskDef * -qemuCheckpointFindActiveDiskInParent(virDomainObjPtr vm, - virDomainMomentObjPtr from, - const char *diskname) -{ - virDomainMomentObjPtr parent = from; - virDomainCheckpointDefPtr parentdef = NULL; - size_t i; - - while (parent) { - parentdef = virDomainCheckpointObjGetDef(parent); - - for (i = 0; i < parentdef->ndisks; i++) { - virDomainCheckpointDiskDef *chkdisk = &parentdef->disks[i]; - - if (STRNEQ(chkdisk->name, diskname)) - continue; - - /* currently inspected checkpoint doesn't describe the disk, - * continue into parent checkpoint */ - if (chkdisk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP) - break; - - return chkdisk; - } - - parent = virDomainCheckpointFindByName(vm->checkpoints, - parentdef->parent.parent_name); - } - - return NULL; -} - - int qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src, virHashTablePtr blockNamedNodeData, const char *delbitmap, - const char *parentbitmap, virJSONValuePtr actions, const char *diskdst, GSList **reopenimages) { - virStorageSourcePtr n = src; + virStorageSourcePtr n; + bool found = false; /* find the backing chain entry with bitmap named '@delbitmap' */ - while (n) { - qemuBlockNamedNodeDataBitmapPtr tmp; - - if ((tmp = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, - n, delbitmap))) { - break; - } - - n = n->backingStore; - } - - if (!n) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("bitmap '%s' not found in backing chain of '%s'"), - delbitmap, diskdst); - return -1; - } - - while (n) { - qemuBlockNamedNodeDataBitmapPtr srcbitmap; - - if (!(srcbitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, - n, delbitmap))) - break; - - /* For the actual checkpoint deletion we will merge any bitmap into the - * bitmap of the parent checkpoint (@parentbitmap) or for any image - * where the parent checkpoint bitmap is not present we must rename - * the bitmap of the deleted checkpoint into the bitmap of the parent - * checkpoint as qemu can't currently take the allocation map and turn - * it into a bitmap and thus we wouldn't be able to do a backup. */ - if (parentbitmap) { - qemuBlockNamedNodeDataBitmapPtr dstbitmap; - g_autoptr(virJSONValue) arr = NULL; - - dstbitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, - n, parentbitmap); - - if (dstbitmap) { - if (srcbitmap->recording && !dstbitmap->recording) { - if (qemuMonitorTransactionBitmapEnable(actions, - n->nodeformat, - dstbitmap->name) < 0) - return -1; - } - - } else { - if (qemuMonitorTransactionBitmapAdd(actions, - n->nodeformat, - parentbitmap, - true, - !srcbitmap->recording, - srcbitmap->granularity) < 0) - return -1; - } + for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) { + qemuBlockNamedNodeDataBitmapPtr bitmapdata; - arr = virJSONValueNewArray(); - - if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, - n->nodeformat, - srcbitmap->name) < 0) - return -1; + if (!(bitmapdata = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, + n, delbitmap))) + continue; - if (qemuMonitorTransactionBitmapMerge(actions, - n->nodeformat, - parentbitmap, &arr) < 0) - return -1; - } + found = true; if (qemuMonitorTransactionBitmapRemove(actions, n->nodeformat, - srcbitmap->name) < 0) + bitmapdata->name) < 0) return -1; if (n != src) *reopenimages = g_slist_prepend(*reopenimages, n); + } - n = n->backingStore; + if (!found) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("bitmap '%s' not found in backing chain of '%s'"), + delbitmap, diskdst); + return -1; } return 0; @@ -247,8 +148,7 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src, static int qemuCheckpointDiscardBitmaps(virDomainObjPtr vm, - virDomainCheckpointDefPtr chkdef, - virDomainMomentObjPtr parent) + virDomainCheckpointDefPtr chkdef) { qemuDomainObjPrivatePtr priv = vm->privateData; virQEMUDriverPtr driver = priv->driver; @@ -268,8 +168,6 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm, for (i = 0; i < chkdef->ndisks; i++) { virDomainCheckpointDiskDef *chkdisk = &chkdef->disks[i]; virDomainDiskDefPtr domdisk = virDomainDiskByTarget(vm->def, chkdisk->name); - virDomainCheckpointDiskDef *parentchkdisk = NULL; - const char *parentbitmap = NULL; /* domdisk can be missing e.g. when it was unplugged */ if (!domdisk) @@ -278,15 +176,8 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm, if (chkdisk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP) continue; - /* If any ancestor checkpoint has a bitmap for the same - * disk, then this bitmap must be merged to the - * ancestor. */ - if ((parentchkdisk = qemuCheckpointFindActiveDiskInParent(vm, parent, - chkdisk->name))) - parentbitmap = parentchkdisk->bitmap; - if (qemuCheckpointDiscardDiskBitmaps(domdisk->src, blockNamedNodeData, - chkdisk->bitmap, parentbitmap, + chkdisk->bitmap, actions, domdisk->dst, &reopenimages) < 0) return -1; @@ -334,7 +225,6 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver, bool update_parent, bool metadata_only) { - virDomainMomentObjPtr parent = NULL; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autofree char *chkFile = NULL; bool chkcurrent = chk == virDomainCheckpointGetCurrent(vm->checkpoints); @@ -350,14 +240,17 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver, if (!metadata_only) { virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk); - parent = virDomainCheckpointFindByName(vm->checkpoints, - chk->def->parent_name); - if (qemuCheckpointDiscardBitmaps(vm, chkdef, parent) < 0) + if (qemuCheckpointDiscardBitmaps(vm, chkdef) < 0) return -1; } if (chkcurrent) { + virDomainMomentObjPtr parent = NULL; + virDomainCheckpointSetCurrent(vm->checkpoints, NULL); + parent = virDomainCheckpointFindByName(vm->checkpoints, + chk->def->parent_name); + if (update_parent && parent) { virDomainCheckpointSetCurrent(vm->checkpoints, parent); if (qemuCheckpointWriteMetadata(vm, parent, diff --git a/src/qemu/qemu_checkpoint.h b/src/qemu/qemu_checkpoint.h index cf1e9e46cb..0d267a188c 100644 --- a/src/qemu/qemu_checkpoint.h +++ b/src/qemu/qemu_checkpoint.h @@ -76,7 +76,6 @@ int qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src, virHashTablePtr blockNamedNodeData, const char *delbitmap, - const char *parentbitmap, virJSONValuePtr actions, const char *diskdst, GSList **reopenimages); diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 63112eea24..2dc06fd420 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -830,7 +830,6 @@ struct testQemuCheckpointDeleteMergeData { const char *name; virStorageSourcePtr chain; const char *deletebitmap; - const char *parentbitmap; const char *nodedatafile; }; @@ -864,7 +863,6 @@ testQemuCheckpointDeleteMerge(const void *opaque) if (qemuCheckpointDiscardDiskBitmaps(data->chain, nodedata, data->deletebitmap, - data->parentbitmap, actions, "testdisk", &reopenimages) >= 0) { @@ -1319,19 +1317,18 @@ mymain(void) TEST_BACKUP_BITMAP_CALCULATE("empty", bitmapSourceChain, "a", "empty"); -#define TEST_CHECKPOINT_DELETE_MERGE(testname, delbmp, parbmp, named) \ +#define TEST_CHECKPOINT_DELETE_MERGE(testname, delbmp, named) \ do { \ checkpointdeletedata.name = testname; \ checkpointdeletedata.chain = bitmapSourceChain; \ checkpointdeletedata.deletebitmap = delbmp; \ - checkpointdeletedata.parentbitmap = parbmp; \ checkpointdeletedata.nodedatafile = named; \ if (virTestRun("checkpoint delete " testname, \ testQemuCheckpointDeleteMerge, &checkpointdeletedata) < 0) \ ret = -1; \ } while (0) - TEST_CHECKPOINT_DELETE_MERGE("empty", "a", NULL, "empty"); + TEST_CHECKPOINT_DELETE_MERGE("empty", "a", "empty"); #define TEST_BITMAP_VALIDATE(testname, bitmap, rc) \ do { \ -- 2.26.2

Also rename the helper struct and function. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 2dc06fd420..f7773f4a51 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -826,7 +826,7 @@ testQemuBackupIncrementalBitmapCalculate(const void *opaque) static const char *checkpointDeletePrefix = "qemublocktestdata/checkpointdelete/"; -struct testQemuCheckpointDeleteMergeData { +struct testQemuCheckpointDeleteData { const char *name; virStorageSourcePtr chain; const char *deletebitmap; @@ -835,9 +835,9 @@ struct testQemuCheckpointDeleteMergeData { static int -testQemuCheckpointDeleteMerge(const void *opaque) +testQemuCheckpointDelete(const void *opaque) { - const struct testQemuCheckpointDeleteMergeData *data = opaque; + const struct testQemuCheckpointDeleteData *data = opaque; g_autofree char *actual = NULL; g_autofree char *expectpath = NULL; g_autoptr(virJSONValue) actions = NULL; @@ -1037,7 +1037,7 @@ mymain(void) struct testJSONtoJSONData jsontojsondata; struct testQemuImageCreateData imagecreatedata; struct testQemuBackupIncrementalBitmapCalculateData backupbitmapcalcdata; - struct testQemuCheckpointDeleteMergeData checkpointdeletedata; + struct testQemuCheckpointDeleteData checkpointdeletedata; struct testQemuBlockBitmapValidateData blockbitmapvalidatedata; struct testQemuBlockBitmapBlockcopyData blockbitmapblockcopydata; struct testQemuBlockBitmapBlockcommitData blockbitmapblockcommitdata; @@ -1317,18 +1317,18 @@ mymain(void) TEST_BACKUP_BITMAP_CALCULATE("empty", bitmapSourceChain, "a", "empty"); -#define TEST_CHECKPOINT_DELETE_MERGE(testname, delbmp, named) \ +#define TEST_CHECKPOINT_DELETE(testname, delbmp, named) \ do { \ checkpointdeletedata.name = testname; \ checkpointdeletedata.chain = bitmapSourceChain; \ checkpointdeletedata.deletebitmap = delbmp; \ checkpointdeletedata.nodedatafile = named; \ if (virTestRun("checkpoint delete " testname, \ - testQemuCheckpointDeleteMerge, &checkpointdeletedata) < 0) \ + testQemuCheckpointDelete, &checkpointdeletedata) < 0) \ ret = -1; \ } while (0) - TEST_CHECKPOINT_DELETE_MERGE("empty", "a", "empty"); + TEST_CHECKPOINT_DELETE("empty", "a", "empty"); #define TEST_BITMAP_VALIDATE(testname, bitmap, rc) \ do { \ -- 2.26.2

Exercise the now arguably simpler checkpoint deletion code on the 'basic', 'snapshots', and 'synthetic' test data sets. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 18 ++++++++++++++++++ .../checkpointdelete/basic-current-out.json | 9 +++++++++ .../basic-intermediate1-out.json | 9 +++++++++ .../basic-intermediate2-out.json | 9 +++++++++ .../basic-intermediate3-out.json | 9 +++++++++ .../checkpointdelete/basic-noparent-out.json | 9 +++++++++ .../snapshots-current-out.json | 9 +++++++++ .../snapshots-intermediate1-out.json | 11 +++++++++++ .../snapshots-intermediate2-out.json | 11 +++++++++++ .../snapshots-intermediate3-out.json | 11 +++++++++++ .../snapshots-noparent-out.json | 11 +++++++++++ .../synthetic-current-out.json | 9 +++++++++ .../synthetic-intermediate1-out.json | 11 +++++++++++ .../synthetic-intermediate2-out.json | 11 +++++++++++ .../synthetic-intermediate3-out.json | 19 +++++++++++++++++++ .../synthetic-noparent-out.json | 11 +++++++++++ 16 files changed, 177 insertions(+) create mode 100644 tests/qemublocktestdata/checkpointdelete/basic-current-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/synthetic-current-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/synthetic-intermediate1-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/synthetic-intermediate2-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/synthetic-intermediate3-out.json create mode 100644 tests/qemublocktestdata/checkpointdelete/synthetic-noparent-out.json diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index f7773f4a51..c10eabb6a0 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1330,6 +1330,24 @@ mymain(void) TEST_CHECKPOINT_DELETE("empty", "a", "empty"); + TEST_CHECKPOINT_DELETE("basic-noparent", "a", "basic"); + TEST_CHECKPOINT_DELETE("basic-intermediate1", "b", "basic"); + TEST_CHECKPOINT_DELETE("basic-intermediate2", "c", "basic"); + TEST_CHECKPOINT_DELETE("basic-intermediate3", "d", "basic"); + TEST_CHECKPOINT_DELETE("basic-current", "current", "basic"); + + TEST_CHECKPOINT_DELETE("snapshots-noparent", "a", "snapshots"); + TEST_CHECKPOINT_DELETE("snapshots-intermediate1", "b", "snapshots"); + TEST_CHECKPOINT_DELETE("snapshots-intermediate2", "c", "snapshots"); + TEST_CHECKPOINT_DELETE("snapshots-intermediate3", "d", "snapshots"); + TEST_CHECKPOINT_DELETE("snapshots-current", "current", "snapshots"); + + TEST_CHECKPOINT_DELETE("synthetic-noparent", "a", "synthetic"); + TEST_CHECKPOINT_DELETE("synthetic-intermediate1", "b", "synthetic"); + TEST_CHECKPOINT_DELETE("synthetic-intermediate2", "c", "synthetic"); + TEST_CHECKPOINT_DELETE("synthetic-intermediate3", "d", "synthetic"); + TEST_CHECKPOINT_DELETE("synthetic-current", "current", "synthetic"); + #define TEST_BITMAP_VALIDATE(testname, bitmap, rc) \ do { \ blockbitmapvalidatedata.name = testname; \ diff --git a/tests/qemublocktestdata/checkpointdelete/basic-current-out.json b/tests/qemublocktestdata/checkpointdelete/basic-current-out.json new file mode 100644 index 0000000000..6ed1b63b66 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/basic-current-out.json @@ -0,0 +1,9 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-1-format", + "name": "current" + } + } +] diff --git a/tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json new file mode 100644 index 0000000000..e1dd4920cd --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json @@ -0,0 +1,9 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-1-format", + "name": "b" + } + } +] diff --git a/tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json new file mode 100644 index 0000000000..5638532d35 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json @@ -0,0 +1,9 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-1-format", + "name": "c" + } + } +] diff --git a/tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json new file mode 100644 index 0000000000..8c56b0e689 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json @@ -0,0 +1,9 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-1-format", + "name": "d" + } + } +] diff --git a/tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json new file mode 100644 index 0000000000..e87382fdb4 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json @@ -0,0 +1,9 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-1-format", + "name": "a" + } + } +] diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json new file mode 100644 index 0000000000..6ed1b63b66 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json @@ -0,0 +1,9 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-1-format", + "name": "current" + } + } +] diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json new file mode 100644 index 0000000000..6eb9716aaa --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json @@ -0,0 +1,11 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-3-format", + "name": "b" + } + } +] +reopen nodes: +libvirt-3-format diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json new file mode 100644 index 0000000000..92b849cfc9 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json @@ -0,0 +1,11 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-3-format", + "name": "c" + } + } +] +reopen nodes: +libvirt-3-format diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json new file mode 100644 index 0000000000..1e8e79b1f6 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json @@ -0,0 +1,11 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-2-format", + "name": "d" + } + } +] +reopen nodes: +libvirt-2-format diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json new file mode 100644 index 0000000000..0479815f36 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json @@ -0,0 +1,11 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-5-format", + "name": "a" + } + } +] +reopen nodes: +libvirt-5-format diff --git a/tests/qemublocktestdata/checkpointdelete/synthetic-current-out.json b/tests/qemublocktestdata/checkpointdelete/synthetic-current-out.json new file mode 100644 index 0000000000..6ed1b63b66 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/synthetic-current-out.json @@ -0,0 +1,9 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-1-format", + "name": "current" + } + } +] diff --git a/tests/qemublocktestdata/checkpointdelete/synthetic-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/synthetic-intermediate1-out.json new file mode 100644 index 0000000000..6eb9716aaa --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/synthetic-intermediate1-out.json @@ -0,0 +1,11 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-3-format", + "name": "b" + } + } +] +reopen nodes: +libvirt-3-format diff --git a/tests/qemublocktestdata/checkpointdelete/synthetic-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/synthetic-intermediate2-out.json new file mode 100644 index 0000000000..92b849cfc9 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/synthetic-intermediate2-out.json @@ -0,0 +1,11 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-3-format", + "name": "c" + } + } +] +reopen nodes: +libvirt-3-format diff --git a/tests/qemublocktestdata/checkpointdelete/synthetic-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/synthetic-intermediate3-out.json new file mode 100644 index 0000000000..466df52007 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/synthetic-intermediate3-out.json @@ -0,0 +1,19 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-2-format", + "name": "d" + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-3-format", + "name": "d" + } + } +] +reopen nodes: +libvirt-3-format +libvirt-2-format diff --git a/tests/qemublocktestdata/checkpointdelete/synthetic-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/synthetic-noparent-out.json new file mode 100644 index 0000000000..0479815f36 --- /dev/null +++ b/tests/qemublocktestdata/checkpointdelete/synthetic-noparent-out.json @@ -0,0 +1,11 @@ +[ + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-5-format", + "name": "a" + } + } +] +reopen nodes: +libvirt-5-format -- 2.26.2

Note that this is not the final version and will be updated once qemu pushes the patches. --- .../caps_5.1.0.x86_64.replies | 2737 +++++++++-------- .../caps_5.1.0.x86_64.xml | 2 +- 2 files changed, 1406 insertions(+), 1333 deletions(-) diff --git a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.replies index c44cff7e50..04b0cc1bbe 100644 --- a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.replies +++ b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.replies @@ -21,7 +21,7 @@ "minor": 0, "major": 5 }, - "package": "v5.0.0-870-g5cc7a54c2e" + "package": "v5.0.0-966-gdcfd91ce51" }, "id": "libvirt-2" } @@ -501,6 +501,9 @@ { "name": "x-debug-block-dirty-bitmap-sha256" }, + { + "name": "block-dirty-bitmap-populate" + }, { "name": "block-dirty-bitmap-merge" }, @@ -674,14 +677,14 @@ "name": "ich9-usb-uhci5", "parent": "pci-uhci-usb" }, - { - "name": "pci-ipmi-bt", - "parent": "pci-device" - }, { "name": "Icelake-Server-v1-x86_64-cpu", "parent": "x86_64-cpu" }, + { + "name": "pci-ipmi-bt", + "parent": "pci-device" + }, { "name": "ich9-usb-uhci6", "parent": "pci-uhci-usb" @@ -1262,6 +1265,10 @@ "name": "ide-cd", "parent": "ide-device" }, + { + "name": "mioe3680_pci", + "parent": "pci-device" + }, { "name": "tcg-accel", "parent": "accel" @@ -1294,10 +1301,6 @@ "name": "nec-usb-xhci", "parent": "base-xhci" }, - { - "name": "mioe3680_pci", - "parent": "pci-device" - }, { "name": "i82551", "parent": "pci-device" @@ -1318,6 +1321,10 @@ "name": "piix4-ide", "parent": "pci-ide" }, + { + "name": "vhost-user-backend", + "parent": "object" + }, { "name": "pc-i440fx-2.6-machine", "parent": "generic-pc-machine" @@ -1326,10 +1333,6 @@ "name": "nvme", "parent": "pci-device" }, - { - "name": "vhost-user-backend", - "parent": "object" - }, { "name": "vmxnet3", "parent": "pci-device" @@ -1442,6 +1445,10 @@ "name": "kvm32-v1-x86_64-cpu", "parent": "x86_64-cpu" }, + { + "name": "dwc2-usb", + "parent": "sys-bus-device" + }, { "name": "pc-i440fx-2.1-machine", "parent": "generic-pc-machine" @@ -2150,14 +2157,14 @@ "name": "pc-dimm", "parent": "device" }, - { - "name": "virtio-net-pci-transitional", - "parent": "virtio-net-pci-base" - }, { "name": "virtio-balloon-pci-non-transitional", "parent": "virtio-balloon-pci-base" }, + { + "name": "virtio-net-pci-transitional", + "parent": "virtio-net-pci-base" + }, { "name": "ipmi-bmc-sim", "parent": "ipmi-bmc" @@ -11598,9 +11605,15 @@ "meta-type": "command", "arg-type": "37" }, + { + "name": "block-dirty-bitmap-populate", + "ret-type": "0", + "meta-type": "command", + "arg-type": "38" + }, { "name": "x-debug-block-dirty-bitmap-sha256", - "ret-type": "38", + "ret-type": "39", "meta-type": "command", "arg-type": "36" }, @@ -11608,155 +11621,155 @@ "name": "blockdev-mirror", "ret-type": "0", "meta-type": "command", - "arg-type": "39" + "arg-type": "40" }, { "name": "block-stream", "ret-type": "0", "meta-type": "command", - "arg-type": "40" + "arg-type": "41" }, { "name": "block-job-set-speed", "ret-type": "0", "meta-type": "command", - "arg-type": "41" + "arg-type": "42" }, { "name": "block-job-cancel", "ret-type": "0", "meta-type": "command", - "arg-type": "42" + "arg-type": "43" }, { "name": "block-job-pause", "ret-type": "0", "meta-type": "command", - "arg-type": "43" + "arg-type": "44" }, { "name": "block-job-resume", "ret-type": "0", "meta-type": "command", - "arg-type": "44" + "arg-type": "45" }, { "name": "block-job-complete", "ret-type": "0", "meta-type": "command", - "arg-type": "45" + "arg-type": "46" }, { "name": "block-job-dismiss", "ret-type": "0", "meta-type": "command", - "arg-type": "46" + "arg-type": "47" }, { "name": "block-job-finalize", "ret-type": "0", "meta-type": "command", - "arg-type": "47" + "arg-type": "48" }, { "name": "blockdev-add", "ret-type": "0", "meta-type": "command", - "arg-type": "48" + "arg-type": "49" }, { "name": "x-blockdev-reopen", "ret-type": "0", "meta-type": "command", - "arg-type": "48" + "arg-type": "49" }, { "name": "blockdev-del", "ret-type": "0", "meta-type": "command", - "arg-type": "49" + "arg-type": "50" }, { "name": "blockdev-create", "ret-type": "0", "meta-type": "command", - "arg-type": "50" + "arg-type": "51" }, { "name": "BLOCK_IMAGE_CORRUPTED", "meta-type": "event", - "arg-type": "51" + "arg-type": "52" }, { "name": "BLOCK_IO_ERROR", "meta-type": "event", - "arg-type": "52" + "arg-type": "53" }, { "name": "BLOCK_JOB_COMPLETED", "meta-type": "event", - "arg-type": "53" + "arg-type": "54" }, { "name": "BLOCK_JOB_CANCELLED", "meta-type": "event", - "arg-type": "54" + "arg-type": "55" }, { "name": "BLOCK_JOB_ERROR", "meta-type": "event", - "arg-type": "55" + "arg-type": "56" }, { "name": "BLOCK_JOB_READY", "meta-type": "event", - "arg-type": "56" + "arg-type": "57" }, { "name": "BLOCK_JOB_PENDING", "meta-type": "event", - "arg-type": "57" + "arg-type": "58" }, { "name": "BLOCK_WRITE_THRESHOLD", "meta-type": "event", - "arg-type": "58" + "arg-type": "59" }, { "name": "block-set-write-threshold", "ret-type": "0", "meta-type": "command", - "arg-type": "59" + "arg-type": "60" }, { "name": "x-blockdev-change", "ret-type": "0", "meta-type": "command", - "arg-type": "60" + "arg-type": "61" }, { "name": "x-blockdev-set-iothread", "ret-type": "0", "meta-type": "command", - "arg-type": "61" + "arg-type": "62" }, { "name": "nbd-server-start", "ret-type": "0", "meta-type": "command", - "arg-type": "62" + "arg-type": "63" }, { "name": "nbd-server-add", "ret-type": "0", "meta-type": "command", - "arg-type": "63" + "arg-type": "64" }, { "name": "nbd-server-remove", "ret-type": "0", "meta-type": "command", - "arg-type": "64" + "arg-type": "65" }, { "name": "nbd-server-stop", @@ -11767,81 +11780,81 @@ { "name": "QUORUM_FAILURE", "meta-type": "event", - "arg-type": "65" + "arg-type": "66" }, { "name": "QUORUM_REPORT_BAD", "meta-type": "event", - "arg-type": "66" + "arg-type": "67" }, { "name": "blockdev-snapshot-internal-sync", "ret-type": "0", "meta-type": "command", - "arg-type": "67" + "arg-type": "68" }, { "name": "blockdev-snapshot-delete-internal-sync", - "ret-type": "69", + "ret-type": "70", "meta-type": "command", - "arg-type": "68" + "arg-type": "69" }, { "name": "JOB_STATUS_CHANGE", "meta-type": "event", - "arg-type": "70" + "arg-type": "71" }, { "name": "job-pause", "ret-type": "0", "meta-type": "command", - "arg-type": "71" + "arg-type": "72" }, { "name": "job-resume", "ret-type": "0", "meta-type": "command", - "arg-type": "72" + "arg-type": "73" }, { "name": "job-cancel", "ret-type": "0", "meta-type": "command", - "arg-type": "73" + "arg-type": "74" }, { "name": "job-complete", "ret-type": "0", "meta-type": "command", - "arg-type": "74" + "arg-type": "75" }, { "name": "job-dismiss", "ret-type": "0", "meta-type": "command", - "arg-type": "75" + "arg-type": "76" }, { "name": "job-finalize", "ret-type": "0", "meta-type": "command", - "arg-type": "76" + "arg-type": "77" }, { "name": "query-jobs", - "ret-type": "[77]", + "ret-type": "[78]", "meta-type": "command", "arg-type": "0" }, { "name": "query-chardev", - "ret-type": "[78]", + "ret-type": "[79]", "meta-type": "command", "arg-type": "0" }, { "name": "query-chardev-backends", - "ret-type": "[79]", + "ret-type": "[80]", "meta-type": "command", "arg-type": "0" }, @@ -11849,63 +11862,63 @@ "name": "ringbuf-write", "ret-type": "0", "meta-type": "command", - "arg-type": "80" + "arg-type": "81" }, { "name": "ringbuf-read", "ret-type": "str", "meta-type": "command", - "arg-type": "81" + "arg-type": "82" }, { "name": "chardev-add", - "ret-type": "83", + "ret-type": "84", "meta-type": "command", - "arg-type": "82" + "arg-type": "83" }, { "name": "chardev-change", - "ret-type": "83", + "ret-type": "84", "meta-type": "command", - "arg-type": "84" + "arg-type": "85" }, { "name": "chardev-remove", "ret-type": "0", "meta-type": "command", - "arg-type": "85" + "arg-type": "86" }, { "name": "chardev-send-break", "ret-type": "0", "meta-type": "command", - "arg-type": "86" + "arg-type": "87" }, { "name": "VSERPORT_CHANGE", "meta-type": "event", - "arg-type": "87" + "arg-type": "88" }, { "name": "dump-guest-memory", "ret-type": "0", "meta-type": "command", - "arg-type": "88" + "arg-type": "89" }, { "name": "query-dump", - "ret-type": "89", + "ret-type": "90", "meta-type": "command", "arg-type": "0" }, { "name": "DUMP_COMPLETED", "meta-type": "event", - "arg-type": "90" + "arg-type": "91" }, { "name": "query-dump-guest-memory-capability", - "ret-type": "91", + "ret-type": "92", "meta-type": "command", "arg-type": "0" }, @@ -11913,86 +11926,86 @@ "name": "set_link", "ret-type": "0", "meta-type": "command", - "arg-type": "92" + "arg-type": "93" }, { "name": "netdev_add", "ret-type": "0", "meta-type": "command", - "arg-type": "93" + "arg-type": "94" }, { "name": "netdev_del", "ret-type": "0", "meta-type": "command", - "arg-type": "94" + "arg-type": "95" }, { "name": "query-rx-filter", - "ret-type": "[96]", + "ret-type": "[97]", "meta-type": "command", - "arg-type": "95" + "arg-type": "96" }, { "name": "NIC_RX_FILTER_CHANGED", "meta-type": "event", - "arg-type": "97" + "arg-type": "98" }, { "name": "announce-self", "ret-type": "0", "meta-type": "command", - "arg-type": "98" + "arg-type": "99" }, { "name": "FAILOVER_NEGOTIATED", "meta-type": "event", - "arg-type": "99" + "arg-type": "100" }, { "name": "RDMA_GID_STATUS_CHANGED", "meta-type": "event", - "arg-type": "100" + "arg-type": "101" }, { "name": "query-rocker", - "ret-type": "102", + "ret-type": "103", "meta-type": "command", - "arg-type": "101" + "arg-type": "102" }, { "name": "query-rocker-ports", - "ret-type": "[104]", + "ret-type": "[105]", "meta-type": "command", - "arg-type": "103" + "arg-type": "104" }, { "name": "query-rocker-of-dpa-flows", - "ret-type": "[106]", + "ret-type": "[107]", "meta-type": "command", - "arg-type": "105" + "arg-type": "106" }, { "name": "query-rocker-of-dpa-groups", - "ret-type": "[108]", + "ret-type": "[109]", "meta-type": "command", - "arg-type": "107" + "arg-type": "108" }, { "name": "query-tpm-models", - "ret-type": "[109]", + "ret-type": "[110]", "meta-type": "command", "arg-type": "0" }, { "name": "query-tpm-types", - "ret-type": "[110]", + "ret-type": "[111]", "meta-type": "command", "arg-type": "0" }, { "name": "query-tpm", - "ret-type": "[111]", + "ret-type": "[112]", "meta-type": "command", "arg-type": "0" }, @@ -12000,40 +12013,40 @@ "name": "set_password", "ret-type": "0", "meta-type": "command", - "arg-type": "112" + "arg-type": "113" }, { "name": "expire_password", "ret-type": "0", "meta-type": "command", - "arg-type": "113" + "arg-type": "114" }, { "name": "screendump", "ret-type": "0", "meta-type": "command", - "arg-type": "114" + "arg-type": "115" }, { "name": "query-spice", - "ret-type": "115", + "ret-type": "116", "meta-type": "command", "arg-type": "0" }, { "name": "SPICE_CONNECTED", "meta-type": "event", - "arg-type": "116" + "arg-type": "117" }, { "name": "SPICE_INITIALIZED", "meta-type": "event", - "arg-type": "117" + "arg-type": "118" }, { "name": "SPICE_DISCONNECTED", "meta-type": "event", - "arg-type": "118" + "arg-type": "119" }, { "name": "SPICE_MIGRATE_COMPLETED", @@ -12042,13 +12055,13 @@ }, { "name": "query-vnc", - "ret-type": "119", + "ret-type": "120", "meta-type": "command", "arg-type": "0" }, { "name": "query-vnc-servers", - "ret-type": "[120]", + "ret-type": "[121]", "meta-type": "command", "arg-type": "0" }, @@ -12056,26 +12069,26 @@ "name": "change-vnc-password", "ret-type": "0", "meta-type": "command", - "arg-type": "121" + "arg-type": "122" }, { "name": "VNC_CONNECTED", "meta-type": "event", - "arg-type": "122" + "arg-type": "123" }, { "name": "VNC_INITIALIZED", "meta-type": "event", - "arg-type": "123" + "arg-type": "124" }, { "name": "VNC_DISCONNECTED", "meta-type": "event", - "arg-type": "124" + "arg-type": "125" }, { "name": "query-mice", - "ret-type": "[125]", + "ret-type": "[126]", "meta-type": "command", "arg-type": "0" }, @@ -12083,23 +12096,23 @@ "name": "send-key", "ret-type": "0", "meta-type": "command", - "arg-type": "126" + "arg-type": "127" }, { "name": "input-send-event", "ret-type": "0", "meta-type": "command", - "arg-type": "127" + "arg-type": "128" }, { "name": "query-display-options", - "ret-type": "128", + "ret-type": "129", "meta-type": "command", "arg-type": "0" }, { "name": "query-migrate", - "ret-type": "129", + "ret-type": "130", "meta-type": "command", "arg-type": "0" }, @@ -12107,11 +12120,11 @@ "name": "migrate-set-capabilities", "ret-type": "0", "meta-type": "command", - "arg-type": "130" + "arg-type": "131" }, { "name": "query-migrate-capabilities", - "ret-type": "[131]", + "ret-type": "[132]", "meta-type": "command", "arg-type": "0" }, @@ -12119,11 +12132,11 @@ "name": "migrate-set-parameters", "ret-type": "0", "meta-type": "command", - "arg-type": "132" + "arg-type": "133" }, { "name": "query-migrate-parameters", - "ret-type": "133", + "ret-type": "134", "meta-type": "command", "arg-type": "0" }, @@ -12131,7 +12144,7 @@ "name": "client_migrate_info", "ret-type": "0", "meta-type": "command", - "arg-type": "134" + "arg-type": "135" }, { "name": "migrate-start-postcopy", @@ -12142,17 +12155,17 @@ { "name": "MIGRATION", "meta-type": "event", - "arg-type": "135" + "arg-type": "136" }, { "name": "MIGRATION_PASS", "meta-type": "event", - "arg-type": "136" + "arg-type": "137" }, { "name": "COLO_EXIT", "meta-type": "event", - "arg-type": "137" + "arg-type": "138" }, { "name": "x-colo-lost-heartbeat", @@ -12170,13 +12183,13 @@ "name": "migrate-continue", "ret-type": "0", "meta-type": "command", - "arg-type": "138" + "arg-type": "139" }, { "name": "migrate_set_downtime", "ret-type": "0", "meta-type": "command", - "arg-type": "139", + "arg-type": "140", "features": [ "deprecated" ] @@ -12185,7 +12198,7 @@ "name": "migrate_set_speed", "ret-type": "0", "meta-type": "command", - "arg-type": "140", + "arg-type": "141", "features": [ "deprecated" ] @@ -12194,7 +12207,7 @@ "name": "migrate-set-cache-size", "ret-type": "0", "meta-type": "command", - "arg-type": "141", + "arg-type": "142", "features": [ "deprecated" ] @@ -12212,29 +12225,29 @@ "name": "migrate", "ret-type": "0", "meta-type": "command", - "arg-type": "142" + "arg-type": "143" }, { "name": "migrate-incoming", "ret-type": "0", "meta-type": "command", - "arg-type": "143" + "arg-type": "144" }, { "name": "xen-save-devices-state", "ret-type": "0", "meta-type": "command", - "arg-type": "144" + "arg-type": "145" }, { "name": "xen-set-replication", "ret-type": "0", "meta-type": "command", - "arg-type": "145" + "arg-type": "146" }, { "name": "query-xen-replication-status", - "ret-type": "146", + "ret-type": "147", "meta-type": "command", "arg-type": "0" }, @@ -12246,7 +12259,7 @@ }, { "name": "query-colo-status", - "ret-type": "147", + "ret-type": "148", "meta-type": "command", "arg-type": "0" }, @@ -12255,7 +12268,7 @@ "ret-type": "0", "allow-oob": true, "meta-type": "command", - "arg-type": "148" + "arg-type": "149" }, { "name": "migrate-pause", @@ -12267,47 +12280,47 @@ { "name": "UNPLUG_PRIMARY", "meta-type": "event", - "arg-type": "149" + "arg-type": "150" }, { "name": "transaction", "ret-type": "0", "meta-type": "command", - "arg-type": "150" + "arg-type": "151" }, { "name": "trace-event-get-state", - "ret-type": "[152]", + "ret-type": "[153]", "meta-type": "command", - "arg-type": "151" + "arg-type": "152" }, { "name": "trace-event-set-state", "ret-type": "0", "meta-type": "command", - "arg-type": "153" + "arg-type": "154" }, { "name": "qmp_capabilities", "ret-type": "0", "meta-type": "command", - "arg-type": "154" + "arg-type": "155" }, { "name": "query-version", - "ret-type": "155", + "ret-type": "156", "meta-type": "command", "arg-type": "0" }, { "name": "query-commands", - "ret-type": "[156]", + "ret-type": "[157]", "meta-type": "command", "arg-type": "0" }, { "name": "query-events", - "ret-type": "[157]", + "ret-type": "[158]", "meta-type": "command", "arg-type": "0", "features": [ @@ -12322,78 +12335,78 @@ }, { "name": "query-qmp-schema", - "ret-type": "[158]", + "ret-type": "[159]", "meta-type": "command", "arg-type": "0" }, { "name": "qom-list", - "ret-type": "[160]", + "ret-type": "[161]", "meta-type": "command", - "arg-type": "159" + "arg-type": "160" }, { "name": "qom-get", "ret-type": "any", "meta-type": "command", - "arg-type": "161" + "arg-type": "162" }, { "name": "qom-set", "ret-type": "0", "meta-type": "command", - "arg-type": "162" + "arg-type": "163" }, { "name": "qom-list-types", - "ret-type": "[164]", + "ret-type": "[165]", "meta-type": "command", - "arg-type": "163" + "arg-type": "164" }, { "name": "qom-list-properties", - "ret-type": "[160]", + "ret-type": "[161]", "meta-type": "command", - "arg-type": "165" + "arg-type": "166" }, { "name": "object-add", "ret-type": "0", "meta-type": "command", - "arg-type": "166" + "arg-type": "167" }, { "name": "object-del", "ret-type": "0", "meta-type": "command", - "arg-type": "167" + "arg-type": "168" }, { "name": "device-list-properties", - "ret-type": "[160]", + "ret-type": "[161]", "meta-type": "command", - "arg-type": "168" + "arg-type": "169" }, { "name": "device_add", "ret-type": "0", "meta-type": "command", - "arg-type": "169" + "arg-type": "170" }, { "name": "device_del", "ret-type": "0", "meta-type": "command", - "arg-type": "170" + "arg-type": "171" }, { "name": "DEVICE_DELETED", "meta-type": "event", - "arg-type": "171" + "arg-type": "172" }, { "name": "query-cpus", - "ret-type": "[172]", + "ret-type": "[173]", "meta-type": "command", "arg-type": "0", "features": [ @@ -12402,7 +12415,7 @@ }, { "name": "query-cpus-fast", - "ret-type": "[173]", + "ret-type": "[174]", "meta-type": "command", "arg-type": "0" }, @@ -12410,38 +12423,38 @@ "name": "cpu-add", "ret-type": "0", "meta-type": "command", - "arg-type": "174", + "arg-type": "175", "features": [ "deprecated" ] }, { "name": "query-machines", - "ret-type": "[175]", + "ret-type": "[176]", "meta-type": "command", "arg-type": "0" }, { "name": "query-current-machine", - "ret-type": "176", + "ret-type": "177", "meta-type": "command", "arg-type": "0" }, { "name": "query-target", - "ret-type": "177", + "ret-type": "178", "meta-type": "command", "arg-type": "0" }, { "name": "query-memdev", - "ret-type": "[178]", + "ret-type": "[179]", "meta-type": "command", "arg-type": "0" }, { "name": "query-hotpluggable-cpus", - "ret-type": "[179]", + "ret-type": "[180]", "meta-type": "command", "arg-type": "0" }, @@ -12449,17 +12462,17 @@ "name": "set-numa-node", "ret-type": "0", "meta-type": "command", - "arg-type": "180" + "arg-type": "181" }, { "name": "query-cpu-model-expansion", - "ret-type": "186", + "ret-type": "187", "meta-type": "command", - "arg-type": "185" + "arg-type": "186" }, { "name": "query-cpu-definitions", - "ret-type": "[187]", + "ret-type": "[188]", "meta-type": "command", "arg-type": "0" }, @@ -12467,46 +12480,46 @@ "name": "add_client", "ret-type": "0", "meta-type": "command", - "arg-type": "188" + "arg-type": "189" }, { "name": "query-name", - "ret-type": "189", + "ret-type": "190", "meta-type": "command", "arg-type": "0" }, { "name": "query-kvm", - "ret-type": "190", + "ret-type": "191", "meta-type": "command", "arg-type": "0" }, { "name": "query-uuid", - "ret-type": "191", + "ret-type": "192", "meta-type": "command", "arg-type": "0" }, { "name": "query-iothreads", - "ret-type": "[192]", + "ret-type": "[193]", "meta-type": "command", "arg-type": "0" }, { "name": "query-balloon", - "ret-type": "193", + "ret-type": "194", "meta-type": "command", "arg-type": "0" }, { "name": "BALLOON_CHANGE", "meta-type": "event", - "arg-type": "194" + "arg-type": "195" }, { "name": "query-pci", - "ret-type": "[195]", + "ret-type": "[196]", "meta-type": "command", "arg-type": "0" }, @@ -12532,13 +12545,13 @@ "name": "memsave", "ret-type": "0", "meta-type": "command", - "arg-type": "196" + "arg-type": "197" }, { "name": "pmemsave", "ret-type": "0", "meta-type": "command", - "arg-type": "197" + "arg-type": "198" }, { "name": "cont", @@ -12568,13 +12581,13 @@ "name": "balloon", "ret-type": "0", "meta-type": "command", - "arg-type": "198" + "arg-type": "199" }, { "name": "human-monitor-command", "ret-type": "str", "meta-type": "command", - "arg-type": "199", + "arg-type": "200", "features": [ "savevm-monitor-nodes" ] @@ -12583,7 +12596,7 @@ "name": "change", "ret-type": "0", "meta-type": "command", - "arg-type": "200", + "arg-type": "201", "features": [ "deprecated" ] @@ -12592,88 +12605,88 @@ "name": "xen-set-global-dirty-log", "ret-type": "0", "meta-type": "command", - "arg-type": "201" + "arg-type": "202" }, { "name": "getfd", "ret-type": "0", "meta-type": "command", - "arg-type": "202" + "arg-type": "203" }, { "name": "closefd", "ret-type": "0", "meta-type": "command", - "arg-type": "203" + "arg-type": "204" }, { "name": "query-memory-size-summary", - "ret-type": "204", + "ret-type": "205", "meta-type": "command", "arg-type": "0" }, { "name": "add-fd", - "ret-type": "206", + "ret-type": "207", "meta-type": "command", - "arg-type": "205" + "arg-type": "206" }, { "name": "remove-fd", "ret-type": "0", "meta-type": "command", - "arg-type": "207" + "arg-type": "208" }, { "name": "query-fdsets", - "ret-type": "[208]", + "ret-type": "[209]", "meta-type": "command", "arg-type": "0" }, { "name": "query-command-line-options", - "ret-type": "[210]", + "ret-type": "[211]", "meta-type": "command", - "arg-type": "209" + "arg-type": "210" }, { "name": "query-memory-devices", - "ret-type": "[211]", + "ret-type": "[212]", "meta-type": "command", "arg-type": "0" }, { "name": "MEM_UNPLUG_ERROR", "meta-type": "event", - "arg-type": "212" + "arg-type": "213" }, { "name": "query-acpi-ospm-status", - "ret-type": "[213]", + "ret-type": "[214]", "meta-type": "command", "arg-type": "0" }, { "name": "ACPI_DEVICE_OST", "meta-type": "event", - "arg-type": "214" + "arg-type": "215" }, { "name": "xen-load-devices-state", "ret-type": "0", "meta-type": "command", - "arg-type": "215" + "arg-type": "216" }, { "name": "query-vm-generation-id", - "ret-type": "216", + "ret-type": "217", "meta-type": "command", "arg-type": "0" }, { "name": "RTC_CHANGE", "meta-type": "event", - "arg-type": "217" + "arg-type": "218" }, { "name": "rtc-reset-reinjection", @@ -12683,19 +12696,19 @@ }, { "name": "query-sev", - "ret-type": "218", + "ret-type": "219", "meta-type": "command", "arg-type": "0" }, { "name": "query-sev-launch-measure", - "ret-type": "219", + "ret-type": "220", "meta-type": "command", "arg-type": "0" }, { "name": "query-sev-capabilities", - "ret-type": "220", + "ret-type": "221", "meta-type": "command", "arg-type": "0" }, @@ -12718,7 +12731,7 @@ }, { "name": "status", - "type": "223" + "type": "224" } ], "meta-type": "object" @@ -12732,7 +12745,7 @@ }, { "name": "reason", - "type": "224" + "type": "225" } ], "meta-type": "object" @@ -12746,7 +12759,7 @@ }, { "name": "reason", - "type": "224" + "type": "225" } ], "meta-type": "object" @@ -12756,7 +12769,7 @@ "members": [ { "name": "action", - "type": "225" + "type": "226" } ], "meta-type": "object" @@ -12766,7 +12779,7 @@ "members": [ { "name": "action", - "type": "225" + "type": "226" } ], "meta-type": "object" @@ -12776,12 +12789,12 @@ "members": [ { "name": "action", - "type": "226" + "type": "227" }, { "name": "info", "default": null, - "type": "227" + "type": "228" } ], "meta-type": "object" @@ -12791,12 +12804,12 @@ "members": [ { "name": "action", - "type": "226" + "type": "227" }, { "name": "info", "default": null, - "type": "227" + "type": "228" } ], "meta-type": "object" @@ -12939,7 +12952,7 @@ { "name": "read-only-mode", "default": null, - "type": "228" + "type": "229" } ], "meta-type": "object" @@ -13161,12 +13174,12 @@ { "name": "io-status", "default": null, - "type": "229" + "type": "230" }, { "name": "dirty-bitmaps", "default": null, - "type": "[230]", + "type": "[231]", "features": [ "deprecated" ] @@ -13210,12 +13223,12 @@ }, { "name": "stats", - "type": "231" + "type": "232" }, { "name": "driver-specific", "default": null, - "type": "232" + "type": "233" }, { "name": "parent", @@ -13268,7 +13281,7 @@ }, { "name": "io-status", - "type": "229" + "type": "230" }, { "name": "ready", @@ -13276,7 +13289,7 @@ }, { "name": "status", - "type": "233" + "type": "234" }, { "name": "auto-finalize", @@ -13364,7 +13377,7 @@ { "name": "mode", "default": null, - "type": "234" + "type": "235" } ], "meta-type": "object" @@ -13452,7 +13465,7 @@ { "name": "on-error", "default": null, - "type": "235" + "type": "236" }, { "name": "filter-node-name", @@ -13486,7 +13499,7 @@ }, { "name": "sync", - "type": "236" + "type": "237" }, { "name": "speed", @@ -13501,7 +13514,7 @@ { "name": "bitmap-mode", "default": null, - "type": "237" + "type": "238" }, { "name": "compress", @@ -13511,12 +13524,12 @@ { "name": "on-source-error", "default": null, - "type": "235" + "type": "236" }, { "name": "on-target-error", "default": null, - "type": "235" + "type": "236" }, { "name": "auto-finalize", @@ -13545,7 +13558,7 @@ { "name": "mode", "default": null, - "type": "234" + "type": "235" } ], "meta-type": "object" @@ -13564,7 +13577,7 @@ }, { "name": "sync", - "type": "236" + "type": "237" }, { "name": "speed", @@ -13579,7 +13592,7 @@ { "name": "bitmap-mode", "default": null, - "type": "237" + "type": "238" }, { "name": "compress", @@ -13589,12 +13602,12 @@ { "name": "on-source-error", "default": null, - "type": "235" + "type": "236" }, { "name": "on-target-error", "default": null, - "type": "235" + "type": "236" }, { "name": "auto-finalize", @@ -13676,7 +13689,7 @@ }, { "name": "detect_zeroes", - "type": "238" + "type": "239" }, { "name": "bps", @@ -13704,7 +13717,7 @@ }, { "name": "image", - "type": "239" + "type": "240" }, { "name": "bps_max", @@ -13778,7 +13791,7 @@ }, { "name": "cache", - "type": "240" + "type": "241" }, { "name": "write_threshold", @@ -13787,7 +13800,7 @@ { "name": "dirty-bitmaps", "default": null, - "type": "[230]" + "type": "[231]" } ], "meta-type": "object" @@ -13797,11 +13810,11 @@ "members": [ { "name": "nodes", - "type": "[241]" + "type": "[242]" }, { "name": "edges", - "type": "[242]" + "type": "[243]" } ], "meta-type": "object" @@ -13839,12 +13852,12 @@ }, { "name": "sync", - "type": "236" + "type": "237" }, { "name": "mode", "default": null, - "type": "234" + "type": "235" }, { "name": "speed", @@ -13864,12 +13877,12 @@ { "name": "on-source-error", "default": null, - "type": "235" + "type": "236" }, { "name": "on-target-error", "default": null, - "type": "235" + "type": "236" }, { "name": "unmap", @@ -13879,7 +13892,7 @@ { "name": "copy-mode", "default": null, - "type": "243" + "type": "244" }, { "name": "auto-finalize", @@ -13950,7 +13963,7 @@ }, { "name": "bitmaps", - "type": "[244]" + "type": "[245]" } ], "meta-type": "object" @@ -13959,14 +13972,51 @@ "name": "38", "members": [ { - "name": "sha256", + "name": "node", + "type": "str" + }, + { + "name": "name", "type": "str" + }, + { + "name": "job-id", + "type": "str" + }, + { + "name": "pattern", + "type": "246" + }, + { + "name": "on-error", + "default": null, + "type": "236" + }, + { + "name": "auto-finalize", + "default": null, + "type": "bool" + }, + { + "name": "auto-dismiss", + "default": null, + "type": "bool" } ], "meta-type": "object" }, { "name": "39", + "members": [ + { + "name": "sha256", + "type": "str" + } + ], + "meta-type": "object" + }, + { + "name": "40", "members": [ { "name": "job-id", @@ -13988,7 +14038,7 @@ }, { "name": "sync", - "type": "236" + "type": "237" }, { "name": "speed", @@ -14008,12 +14058,12 @@ { "name": "on-source-error", "default": null, - "type": "235" + "type": "236" }, { "name": "on-target-error", "default": null, - "type": "235" + "type": "236" }, { "name": "filter-node-name", @@ -14023,7 +14073,7 @@ { "name": "copy-mode", "default": null, - "type": "243" + "type": "244" }, { "name": "auto-finalize", @@ -14039,7 +14089,7 @@ "meta-type": "object" }, { - "name": "40", + "name": "41", "members": [ { "name": "job-id", @@ -14073,7 +14123,7 @@ { "name": "on-error", "default": null, - "type": "235" + "type": "236" }, { "name": "auto-finalize", @@ -14089,7 +14139,7 @@ "meta-type": "object" }, { - "name": "41", + "name": "42", "members": [ { "name": "device", @@ -14103,7 +14153,7 @@ "meta-type": "object" }, { - "name": "42", + "name": "43", "members": [ { "name": "device", @@ -14118,7 +14168,7 @@ "meta-type": "object" }, { - "name": "43", + "name": "44", "members": [ { "name": "device", @@ -14128,7 +14178,7 @@ "meta-type": "object" }, { - "name": "44", + "name": "45", "members": [ { "name": "device", @@ -14138,7 +14188,7 @@ "meta-type": "object" }, { - "name": "45", + "name": "46", "members": [ { "name": "device", @@ -14148,7 +14198,7 @@ "meta-type": "object" }, { - "name": "46", + "name": "47", "members": [ { "name": "id", @@ -14158,7 +14208,7 @@ "meta-type": "object" }, { - "name": "47", + "name": "48", "members": [ { "name": "id", @@ -14168,178 +14218,178 @@ "meta-type": "object" }, { - "name": "48", + "name": "49", "tag": "driver", "variants": [ { "case": "blkdebug", - "type": "248" + "type": "250" }, { "case": "blklogwrites", - "type": "249" + "type": "251" }, { "case": "blkverify", - "type": "250" + "type": "252" }, { "case": "blkreplay", - "type": "251" + "type": "253" }, { "case": "bochs", - "type": "252" + "type": "254" }, { "case": "cloop", - "type": "252" + "type": "254" }, { "case": "compress", - "type": "252" + "type": "254" }, { "case": "copy-on-read", - "type": "252" + "type": "254" }, { "case": "dmg", - "type": "252" + "type": "254" }, { "case": "file", - "type": "253" + "type": "255" }, { "case": "ftp", - "type": "254" + "type": "256" }, { "case": "ftps", - "type": "255" + "type": "257" }, { "case": "gluster", - "type": "256" + "type": "258" }, { "case": "host_cdrom", - "type": "253" + "type": "255" }, { "case": "host_device", - "type": "253" + "type": "255" }, { "case": "http", - "type": "257" + "type": "259" }, { "case": "https", - "type": "258" + "type": "260" }, { "case": "iscsi", - "type": "259" + "type": "261" }, { "case": "luks", - "type": "260" + "type": "262" }, { "case": "nbd", - "type": "261" + "type": "263" }, { "case": "nfs", - "type": "262" + "type": "264" }, { "case": "null-aio", - "type": "263" + "type": "265" }, { "case": "null-co", - "type": "263" + "type": "265" }, { "case": "nvme", - "type": "264" + "type": "266" }, { "case": "parallels", - "type": "252" + "type": "254" }, { "case": "qcow2", - "type": "265" + "type": "267" }, { "case": "qcow", - "type": "266" + "type": "268" }, { "case": "qed", - "type": "267" + "type": "269" }, { "case": "quorum", - "type": "268" + "type": "270" }, { "case": "raw", - "type": "269" + "type": "271" }, { "case": "rbd", - "type": "270" + "type": "272" }, { "case": "replication", - "type": "271" + "type": "273" }, { "case": "sheepdog", - "type": "272" + "type": "274" }, { "case": "ssh", - "type": "273" + "type": "275" }, { "case": "throttle", - "type": "274" + "type": "276" }, { "case": "vdi", - "type": "252" + "type": "254" }, { "case": "vhdx", - "type": "252" + "type": "254" }, { "case": "vmdk", - "type": "267" + "type": "269" }, { "case": "vpc", - "type": "252" + "type": "254" }, { "case": "vvfat", - "type": "275" + "type": "277" }, { "case": "vxhs", - "type": "276" + "type": "278" } ], "members": [ { "name": "driver", - "type": "245" + "type": "247" }, { "name": "node-name", @@ -14349,12 +14399,12 @@ { "name": "discard", "default": null, - "type": "246" + "type": "248" }, { "name": "cache", "default": null, - "type": "247" + "type": "249" }, { "name": "read-only", @@ -14374,13 +14424,13 @@ { "name": "detect-zeroes", "default": null, - "type": "238" + "type": "239" } ], "meta-type": "object" }, { - "name": "49", + "name": "50", "members": [ { "name": "node-name", @@ -14390,7 +14440,7 @@ "meta-type": "object" }, { - "name": "50", + "name": "51", "members": [ { "name": "job-id", @@ -14398,13 +14448,13 @@ }, { "name": "options", - "type": "277" + "type": "279" } ], "meta-type": "object" }, { - "name": "51", + "name": "52", "members": [ { "name": "device", @@ -14437,7 +14487,7 @@ "meta-type": "object" }, { - "name": "52", + "name": "53", "members": [ { "name": "device", @@ -14450,11 +14500,11 @@ }, { "name": "operation", - "type": "278" + "type": "280" }, { "name": "action", - "type": "279" + "type": "281" }, { "name": "nospace", @@ -14469,11 +14519,11 @@ "meta-type": "object" }, { - "name": "53", + "name": "54", "members": [ { "name": "type", - "type": "280" + "type": "282" }, { "name": "device", @@ -14500,11 +14550,11 @@ "meta-type": "object" }, { - "name": "54", + "name": "55", "members": [ { "name": "type", - "type": "280" + "type": "282" }, { "name": "device", @@ -14526,7 +14576,7 @@ "meta-type": "object" }, { - "name": "55", + "name": "56", "members": [ { "name": "device", @@ -14534,21 +14584,21 @@ }, { "name": "operation", - "type": "278" + "type": "280" }, { "name": "action", - "type": "279" + "type": "281" } ], "meta-type": "object" }, { - "name": "56", + "name": "57", "members": [ { "name": "type", - "type": "280" + "type": "282" }, { "name": "device", @@ -14570,11 +14620,11 @@ "meta-type": "object" }, { - "name": "57", + "name": "58", "members": [ { "name": "type", - "type": "280" + "type": "282" }, { "name": "id", @@ -14584,7 +14634,7 @@ "meta-type": "object" }, { - "name": "58", + "name": "59", "members": [ { "name": "node-name", @@ -14602,7 +14652,7 @@ "meta-type": "object" }, { - "name": "59", + "name": "60", "members": [ { "name": "node-name", @@ -14616,7 +14666,7 @@ "meta-type": "object" }, { - "name": "60", + "name": "61", "members": [ { "name": "parent", @@ -14636,7 +14686,7 @@ "meta-type": "object" }, { - "name": "61", + "name": "62", "members": [ { "name": "node-name", @@ -14644,7 +14694,7 @@ }, { "name": "iothread", - "type": "281" + "type": "283" }, { "name": "force", @@ -14655,11 +14705,11 @@ "meta-type": "object" }, { - "name": "62", + "name": "63", "members": [ { "name": "addr", - "type": "282" + "type": "284" }, { "name": "tls-creds", @@ -14675,7 +14725,7 @@ "meta-type": "object" }, { - "name": "63", + "name": "64", "members": [ { "name": "device", @@ -14705,7 +14755,7 @@ "meta-type": "object" }, { - "name": "64", + "name": "65", "members": [ { "name": "name", @@ -14714,13 +14764,13 @@ { "name": "mode", "default": null, - "type": "283" + "type": "285" } ], "meta-type": "object" }, { - "name": "65", + "name": "66", "members": [ { "name": "reference", @@ -14738,11 +14788,11 @@ "meta-type": "object" }, { - "name": "66", + "name": "67", "members": [ { "name": "type", - "type": "284" + "type": "286" }, { "name": "error", @@ -14765,7 +14815,7 @@ "meta-type": "object" }, { - "name": "67", + "name": "68", "members": [ { "name": "device", @@ -14779,7 +14829,7 @@ "meta-type": "object" }, { - "name": "68", + "name": "69", "members": [ { "name": "device", @@ -14799,7 +14849,7 @@ "meta-type": "object" }, { - "name": "69", + "name": "70", "members": [ { "name": "id", @@ -14833,7 +14883,7 @@ "meta-type": "object" }, { - "name": "70", + "name": "71", "members": [ { "name": "id", @@ -14841,13 +14891,13 @@ }, { "name": "status", - "type": "233" + "type": "234" } ], "meta-type": "object" }, { - "name": "71", + "name": "72", "members": [ { "name": "id", @@ -14857,7 +14907,7 @@ "meta-type": "object" }, { - "name": "72", + "name": "73", "members": [ { "name": "id", @@ -14867,7 +14917,7 @@ "meta-type": "object" }, { - "name": "73", + "name": "74", "members": [ { "name": "id", @@ -14877,7 +14927,7 @@ "meta-type": "object" }, { - "name": "74", + "name": "75", "members": [ { "name": "id", @@ -14887,7 +14937,7 @@ "meta-type": "object" }, { - "name": "75", + "name": "76", "members": [ { "name": "id", @@ -14897,7 +14947,7 @@ "meta-type": "object" }, { - "name": "76", + "name": "77", "members": [ { "name": "id", @@ -14907,12 +14957,12 @@ "meta-type": "object" }, { - "name": "[77]", - "element-type": "77", + "name": "[78]", + "element-type": "78", "meta-type": "array" }, { - "name": "77", + "name": "78", "members": [ { "name": "id", @@ -14920,11 +14970,11 @@ }, { "name": "type", - "type": "280" + "type": "282" }, { "name": "status", - "type": "233" + "type": "234" }, { "name": "current-progress", @@ -14943,12 +14993,12 @@ "meta-type": "object" }, { - "name": "[78]", - "element-type": "78", + "name": "[79]", + "element-type": "79", "meta-type": "array" }, { - "name": "78", + "name": "79", "members": [ { "name": "label", @@ -14966,12 +15016,12 @@ "meta-type": "object" }, { - "name": "[79]", - "element-type": "79", + "name": "[80]", + "element-type": "80", "meta-type": "array" }, { - "name": "79", + "name": "80", "members": [ { "name": "name", @@ -14981,7 +15031,7 @@ "meta-type": "object" }, { - "name": "80", + "name": "81", "members": [ { "name": "device", @@ -14994,13 +15044,13 @@ { "name": "format", "default": null, - "type": "285" + "type": "287" } ], "meta-type": "object" }, { - "name": "81", + "name": "82", "members": [ { "name": "device", @@ -15013,7 +15063,7 @@ { "name": "format", "default": null, - "type": "285" + "type": "287" } ], "meta-type": "object" @@ -15024,7 +15074,7 @@ "meta-type": "builtin" }, { - "name": "82", + "name": "83", "members": [ { "name": "id", @@ -15032,13 +15082,13 @@ }, { "name": "backend", - "type": "286" + "type": "288" } ], "meta-type": "object" }, { - "name": "83", + "name": "84", "members": [ { "name": "pty", @@ -15049,7 +15099,7 @@ "meta-type": "object" }, { - "name": "84", + "name": "85", "members": [ { "name": "id", @@ -15057,13 +15107,13 @@ }, { "name": "backend", - "type": "286" + "type": "288" } ], "meta-type": "object" }, { - "name": "85", + "name": "86", "members": [ { "name": "id", @@ -15073,7 +15123,7 @@ "meta-type": "object" }, { - "name": "86", + "name": "87", "members": [ { "name": "id", @@ -15083,7 +15133,7 @@ "meta-type": "object" }, { - "name": "87", + "name": "88", "members": [ { "name": "id", @@ -15097,7 +15147,7 @@ "meta-type": "object" }, { - "name": "88", + "name": "89", "members": [ { "name": "paging", @@ -15125,17 +15175,17 @@ { "name": "format", "default": null, - "type": "287" + "type": "289" } ], "meta-type": "object" }, { - "name": "89", + "name": "90", "members": [ { "name": "status", - "type": "288" + "type": "290" }, { "name": "completed", @@ -15149,11 +15199,11 @@ "meta-type": "object" }, { - "name": "90", + "name": "91", "members": [ { "name": "result", - "type": "89" + "type": "90" }, { "name": "error", @@ -15164,17 +15214,17 @@ "meta-type": "object" }, { - "name": "91", + "name": "92", "members": [ { "name": "formats", - "type": "[287]" + "type": "[289]" } ], "meta-type": "object" }, { - "name": "92", + "name": "93", "members": [ { "name": "name", @@ -15188,48 +15238,48 @@ "meta-type": "object" }, { - "name": "93", + "name": "94", "tag": "type", "variants": [ { "case": "nic", - "type": "290" + "type": "292" }, { "case": "user", - "type": "291" + "type": "293" }, { "case": "tap", - "type": "292" + "type": "294" }, { "case": "l2tpv3", - "type": "293" + "type": "295" }, { "case": "socket", - "type": "294" + "type": "296" }, { "case": "vde", - "type": "295" + "type": "297" }, { "case": "bridge", - "type": "296" + "type": "298" }, { "case": "hubport", - "type": "297" + "type": "299" }, { "case": "netmap", - "type": "298" + "type": "300" }, { "case": "vhost-user", - "type": "299" + "type": "301" }, { "case": "none", @@ -15243,13 +15293,13 @@ }, { "name": "type", - "type": "289" + "type": "291" } ], "meta-type": "object" }, { - "name": "94", + "name": "95", "members": [ { "name": "id", @@ -15259,7 +15309,7 @@ "meta-type": "object" }, { - "name": "95", + "name": "96", "members": [ { "name": "name", @@ -15270,12 +15320,12 @@ "meta-type": "object" }, { - "name": "[96]", - "element-type": "96", + "name": "[97]", + "element-type": "97", "meta-type": "array" }, { - "name": "96", + "name": "97", "members": [ { "name": "name", @@ -15287,15 +15337,15 @@ }, { "name": "multicast", - "type": "300" + "type": "302" }, { "name": "unicast", - "type": "300" + "type": "302" }, { "name": "vlan", - "type": "300" + "type": "302" }, { "name": "broadcast-allowed", @@ -15329,7 +15379,7 @@ "meta-type": "object" }, { - "name": "97", + "name": "98", "members": [ { "name": "name", @@ -15344,7 +15394,7 @@ "meta-type": "object" }, { - "name": "98", + "name": "99", "members": [ { "name": "initial", @@ -15376,7 +15426,7 @@ "meta-type": "object" }, { - "name": "99", + "name": "100", "members": [ { "name": "device-id", @@ -15386,7 +15436,7 @@ "meta-type": "object" }, { - "name": "100", + "name": "101", "members": [ { "name": "netdev", @@ -15408,7 +15458,7 @@ "meta-type": "object" }, { - "name": "101", + "name": "102", "members": [ { "name": "name", @@ -15418,7 +15468,7 @@ "meta-type": "object" }, { - "name": "102", + "name": "103", "members": [ { "name": "name", @@ -15436,7 +15486,7 @@ "meta-type": "object" }, { - "name": "103", + "name": "104", "members": [ { "name": "name", @@ -15446,12 +15496,12 @@ "meta-type": "object" }, { - "name": "[104]", - "element-type": "104", + "name": "[105]", + "element-type": "105", "meta-type": "array" }, { - "name": "104", + "name": "105", "members": [ { "name": "name", @@ -15471,17 +15521,17 @@ }, { "name": "duplex", - "type": "301" + "type": "303" }, { "name": "autoneg", - "type": "302" + "type": "304" } ], "meta-type": "object" }, { - "name": "105", + "name": "106", "members": [ { "name": "name", @@ -15496,12 +15546,12 @@ "meta-type": "object" }, { - "name": "[106]", - "element-type": "106", + "name": "[107]", + "element-type": "107", "meta-type": "array" }, { - "name": "106", + "name": "107", "members": [ { "name": "cookie", @@ -15513,21 +15563,21 @@ }, { "name": "key", - "type": "303" + "type": "305" }, { "name": "mask", - "type": "304" + "type": "306" }, { "name": "action", - "type": "305" + "type": "307" } ], "meta-type": "object" }, { - "name": "107", + "name": "108", "members": [ { "name": "name", @@ -15542,12 +15592,12 @@ "meta-type": "object" }, { - "name": "[108]", - "element-type": "108", + "name": "[109]", + "element-type": "109", "meta-type": "array" }, { - "name": "108", + "name": "109", "members": [ { "name": "id", @@ -15616,12 +15666,12 @@ "meta-type": "object" }, { - "name": "[109]", - "element-type": "109", + "name": "[110]", + "element-type": "110", "meta-type": "array" }, { - "name": "109", + "name": "110", "meta-type": "enum", "values": [ "tpm-tis", @@ -15630,12 +15680,12 @@ ] }, { - "name": "[110]", - "element-type": "110", + "name": "[111]", + "element-type": "111", "meta-type": "array" }, { - "name": "110", + "name": "111", "meta-type": "enum", "values": [ "passthrough", @@ -15643,12 +15693,12 @@ ] }, { - "name": "[111]", - "element-type": "111", + "name": "[112]", + "element-type": "112", "meta-type": "array" }, { - "name": "111", + "name": "112", "members": [ { "name": "id", @@ -15656,17 +15706,17 @@ }, { "name": "model", - "type": "109" + "type": "110" }, { "name": "options", - "type": "306" + "type": "308" } ], "meta-type": "object" }, { - "name": "112", + "name": "113", "members": [ { "name": "protocol", @@ -15685,7 +15735,7 @@ "meta-type": "object" }, { - "name": "113", + "name": "114", "members": [ { "name": "protocol", @@ -15699,7 +15749,7 @@ "meta-type": "object" }, { - "name": "114", + "name": "115", "members": [ { "name": "filename", @@ -15719,7 +15769,7 @@ "meta-type": "object" }, { - "name": "115", + "name": "116", "members": [ { "name": "enabled", @@ -15756,60 +15806,60 @@ }, { "name": "mouse-mode", - "type": "307" + "type": "309" }, { "name": "channels", "default": null, - "type": "[308]" + "type": "[310]" } ], "meta-type": "object" }, { - "name": "116", + "name": "117", "members": [ { "name": "server", - "type": "309" + "type": "311" }, { "name": "client", - "type": "309" + "type": "311" } ], "meta-type": "object" }, { - "name": "117", + "name": "118", "members": [ { "name": "server", - "type": "310" + "type": "312" }, { "name": "client", - "type": "308" + "type": "310" } ], "meta-type": "object" }, { - "name": "118", + "name": "119", "members": [ { "name": "server", - "type": "309" + "type": "311" }, { "name": "client", - "type": "309" + "type": "311" } ], "meta-type": "object" }, { - "name": "119", + "name": "120", "members": [ { "name": "enabled", @@ -15823,7 +15873,7 @@ { "name": "family", "default": null, - "type": "311" + "type": "313" }, { "name": "service", @@ -15838,18 +15888,18 @@ { "name": "clients", "default": null, - "type": "[312]" + "type": "[314]" } ], "meta-type": "object" }, { - "name": "[120]", - "element-type": "120", + "name": "[121]", + "element-type": "121", "meta-type": "array" }, { - "name": "120", + "name": "121", "members": [ { "name": "id", @@ -15857,20 +15907,20 @@ }, { "name": "server", - "type": "[313]" + "type": "[315]" }, { "name": "clients", - "type": "[312]" + "type": "[314]" }, { "name": "auth", - "type": "314" + "type": "316" }, { "name": "vencrypt", "default": null, - "type": "315" + "type": "317" }, { "name": "display", @@ -15881,7 +15931,7 @@ "meta-type": "object" }, { - "name": "121", + "name": "122", "members": [ { "name": "password", @@ -15891,54 +15941,54 @@ "meta-type": "object" }, { - "name": "122", + "name": "123", "members": [ { "name": "server", - "type": "316" + "type": "318" }, { "name": "client", - "type": "317" + "type": "319" } ], "meta-type": "object" }, { - "name": "123", + "name": "124", "members": [ { "name": "server", - "type": "316" + "type": "318" }, { "name": "client", - "type": "312" + "type": "314" } ], "meta-type": "object" }, { - "name": "124", + "name": "125", "members": [ { "name": "server", - "type": "316" + "type": "318" }, { "name": "client", - "type": "312" + "type": "314" } ], "meta-type": "object" }, { - "name": "[125]", - "element-type": "125", + "name": "[126]", + "element-type": "126", "meta-type": "array" }, { - "name": "125", + "name": "126", "members": [ { "name": "name", @@ -15960,11 +16010,11 @@ "meta-type": "object" }, { - "name": "126", + "name": "127", "members": [ { "name": "keys", - "type": "[318]" + "type": "[320]" }, { "name": "hold-time", @@ -15975,7 +16025,7 @@ "meta-type": "object" }, { - "name": "127", + "name": "128", "members": [ { "name": "device", @@ -15989,26 +16039,26 @@ }, { "name": "events", - "type": "[319]" + "type": "[321]" } ], "meta-type": "object" }, { - "name": "128", + "name": "129", "tag": "type", "variants": [ { "case": "gtk", - "type": "322" + "type": "324" }, { "case": "curses", - "type": "323" + "type": "325" }, { "case": "egl-headless", - "type": "324" + "type": "326" }, { "case": "default", @@ -16034,7 +16084,7 @@ "members": [ { "name": "type", - "type": "320" + "type": "322" }, { "name": "full-screen", @@ -16054,33 +16104,33 @@ { "name": "gl", "default": null, - "type": "321" + "type": "323" } ], "meta-type": "object" }, { - "name": "129", + "name": "130", "members": [ { "name": "status", "default": null, - "type": "325" + "type": "327" }, { "name": "ram", "default": null, - "type": "326" + "type": "328" }, { "name": "disk", "default": null, - "type": "326" + "type": "328" }, { "name": "xbzrle-cache", "default": null, - "type": "327" + "type": "329" }, { "name": "total-time", @@ -16125,37 +16175,37 @@ { "name": "compression", "default": null, - "type": "328" + "type": "330" }, { "name": "socket-address", "default": null, - "type": "[329]" + "type": "[331]" } ], "meta-type": "object" }, { - "name": "130", + "name": "131", "members": [ { "name": "capabilities", - "type": "[131]" + "type": "[132]" } ], "meta-type": "object" }, { - "name": "[131]", - "element-type": "131", + "name": "[132]", + "element-type": "132", "meta-type": "array" }, { - "name": "131", + "name": "132", "members": [ { "name": "capability", - "type": "330" + "type": "332" }, { "name": "state", @@ -16165,7 +16215,7 @@ "meta-type": "object" }, { - "name": "132", + "name": "133", "members": [ { "name": "announce-initial", @@ -16230,17 +16280,17 @@ { "name": "tls-creds", "default": null, - "type": "281" + "type": "283" }, { "name": "tls-hostname", "default": null, - "type": "281" + "type": "283" }, { "name": "tls-authz", "default": null, - "type": "281" + "type": "283" }, { "name": "max-bandwidth", @@ -16285,7 +16335,7 @@ { "name": "multifd-compression", "default": null, - "type": "331" + "type": "333" }, { "name": "multifd-zlib-level", @@ -16301,7 +16351,7 @@ "meta-type": "object" }, { - "name": "133", + "name": "134", "members": [ { "name": "announce-initial", @@ -16421,7 +16471,7 @@ { "name": "multifd-compression", "default": null, - "type": "331" + "type": "333" }, { "name": "multifd-zlib-level", @@ -16437,7 +16487,7 @@ "meta-type": "object" }, { - "name": "134", + "name": "135", "members": [ { "name": "protocol", @@ -16466,17 +16516,17 @@ "meta-type": "object" }, { - "name": "135", + "name": "136", "members": [ { "name": "status", - "type": "325" + "type": "327" } ], "meta-type": "object" }, { - "name": "136", + "name": "137", "members": [ { "name": "pass", @@ -16486,31 +16536,31 @@ "meta-type": "object" }, { - "name": "137", + "name": "138", "members": [ { "name": "mode", - "type": "332" + "type": "334" }, { "name": "reason", - "type": "333" + "type": "335" } ], "meta-type": "object" }, { - "name": "138", + "name": "139", "members": [ { "name": "state", - "type": "325" + "type": "327" } ], "meta-type": "object" }, { - "name": "139", + "name": "140", "members": [ { "name": "value", @@ -16520,7 +16570,7 @@ "meta-type": "object" }, { - "name": "140", + "name": "141", "members": [ { "name": "value", @@ -16530,7 +16580,7 @@ "meta-type": "object" }, { - "name": "141", + "name": "142", "members": [ { "name": "value", @@ -16545,7 +16595,7 @@ "meta-type": "builtin" }, { - "name": "142", + "name": "143", "members": [ { "name": "uri", @@ -16575,7 +16625,7 @@ "meta-type": "object" }, { - "name": "143", + "name": "144", "members": [ { "name": "uri", @@ -16585,7 +16635,7 @@ "meta-type": "object" }, { - "name": "144", + "name": "145", "members": [ { "name": "filename", @@ -16600,7 +16650,7 @@ "meta-type": "object" }, { - "name": "145", + "name": "146", "members": [ { "name": "enable", @@ -16619,7 +16669,7 @@ "meta-type": "object" }, { - "name": "146", + "name": "147", "members": [ { "name": "error", @@ -16634,25 +16684,25 @@ "meta-type": "object" }, { - "name": "147", + "name": "148", "members": [ { "name": "mode", - "type": "332" + "type": "334" }, { "name": "last-mode", - "type": "332" + "type": "334" }, { "name": "reason", - "type": "333" + "type": "335" } ], "meta-type": "object" }, { - "name": "148", + "name": "149", "members": [ { "name": "uri", @@ -16662,7 +16712,7 @@ "meta-type": "object" }, { - "name": "149", + "name": "150", "members": [ { "name": "device-id", @@ -16672,22 +16722,22 @@ "meta-type": "object" }, { - "name": "150", + "name": "151", "members": [ { "name": "actions", - "type": "[334]" + "type": "[336]" }, { "name": "properties", "default": null, - "type": "335" + "type": "337" } ], "meta-type": "object" }, { - "name": "151", + "name": "152", "members": [ { "name": "name", @@ -16702,12 +16752,12 @@ "meta-type": "object" }, { - "name": "[152]", - "element-type": "152", + "name": "[153]", + "element-type": "153", "meta-type": "array" }, { - "name": "152", + "name": "153", "members": [ { "name": "name", @@ -16715,7 +16765,7 @@ }, { "name": "state", - "type": "336" + "type": "338" }, { "name": "vcpu", @@ -16725,7 +16775,7 @@ "meta-type": "object" }, { - "name": "153", + "name": "154", "members": [ { "name": "name", @@ -16749,22 +16799,22 @@ "meta-type": "object" }, { - "name": "154", + "name": "155", "members": [ { "name": "enable", "default": null, - "type": "[337]" + "type": "[339]" } ], "meta-type": "object" }, { - "name": "155", + "name": "156", "members": [ { "name": "qemu", - "type": "338" + "type": "340" }, { "name": "package", @@ -16774,12 +16824,12 @@ "meta-type": "object" }, { - "name": "[156]", - "element-type": "156", + "name": "[157]", + "element-type": "157", "meta-type": "array" }, { - "name": "156", + "name": "157", "members": [ { "name": "name", @@ -16789,12 +16839,12 @@ "meta-type": "object" }, { - "name": "[157]", - "element-type": "157", + "name": "[158]", + "element-type": "158", "meta-type": "array" }, { - "name": "157", + "name": "158", "members": [ { "name": "name", @@ -16804,41 +16854,41 @@ "meta-type": "object" }, { - "name": "[158]", - "element-type": "158", + "name": "[159]", + "element-type": "159", "meta-type": "array" }, { - "name": "158", + "name": "159", "tag": "meta-type", "variants": [ { "case": "builtin", - "type": "340" + "type": "342" }, { "case": "enum", - "type": "341" + "type": "343" }, { "case": "array", - "type": "342" + "type": "344" }, { "case": "object", - "type": "343" + "type": "345" }, { "case": "alternate", - "type": "344" + "type": "346" }, { "case": "command", - "type": "345" + "type": "347" }, { "case": "event", - "type": "346" + "type": "348" } ], "members": [ @@ -16848,7 +16898,7 @@ }, { "name": "meta-type", - "type": "339" + "type": "341" }, { "name": "features", @@ -16859,7 +16909,7 @@ "meta-type": "object" }, { - "name": "159", + "name": "160", "members": [ { "name": "path", @@ -16869,12 +16919,12 @@ "meta-type": "object" }, { - "name": "[160]", - "element-type": "160", + "name": "[161]", + "element-type": "161", "meta-type": "array" }, { - "name": "160", + "name": "161", "members": [ { "name": "name", @@ -16898,7 +16948,7 @@ "meta-type": "object" }, { - "name": "161", + "name": "162", "members": [ { "name": "path", @@ -16917,7 +16967,7 @@ "meta-type": "builtin" }, { - "name": "162", + "name": "163", "members": [ { "name": "path", @@ -16935,7 +16985,7 @@ "meta-type": "object" }, { - "name": "163", + "name": "164", "members": [ { "name": "implements", @@ -16951,12 +17001,12 @@ "meta-type": "object" }, { - "name": "[164]", - "element-type": "164", + "name": "[165]", + "element-type": "165", "meta-type": "array" }, { - "name": "164", + "name": "165", "members": [ { "name": "name", @@ -16976,7 +17026,7 @@ "meta-type": "object" }, { - "name": "165", + "name": "166", "members": [ { "name": "typename", @@ -16986,7 +17036,7 @@ "meta-type": "object" }, { - "name": "166", + "name": "167", "members": [ { "name": "qom-type", @@ -17005,7 +17055,7 @@ "meta-type": "object" }, { - "name": "167", + "name": "168", "members": [ { "name": "id", @@ -17015,7 +17065,7 @@ "meta-type": "object" }, { - "name": "168", + "name": "169", "members": [ { "name": "typename", @@ -17025,7 +17075,7 @@ "meta-type": "object" }, { - "name": "169", + "name": "170", "members": [ { "name": "driver", @@ -17045,7 +17095,7 @@ "meta-type": "object" }, { - "name": "170", + "name": "171", "members": [ { "name": "id", @@ -17055,7 +17105,7 @@ "meta-type": "object" }, { - "name": "171", + "name": "172", "members": [ { "name": "device", @@ -17070,41 +17120,41 @@ "meta-type": "object" }, { - "name": "[172]", - "element-type": "172", + "name": "[173]", + "element-type": "173", "meta-type": "array" }, { - "name": "172", + "name": "173", "tag": "arch", "variants": [ { "case": "x86", - "type": "349" + "type": "351" }, { "case": "sparc", - "type": "350" + "type": "352" }, { "case": "ppc", - "type": "351" + "type": "353" }, { "case": "mips", - "type": "352" + "type": "354" }, { "case": "tricore", - "type": "353" + "type": "355" }, { "case": "s390", - "type": "354" + "type": "356" }, { "case": "riscv", - "type": "355" + "type": "357" }, { "case": "other", @@ -17135,27 +17185,27 @@ { "name": "props", "default": null, - "type": "347" + "type": "349" }, { "name": "arch", - "type": "348" + "type": "350" } ], "meta-type": "object" }, { - "name": "[173]", - "element-type": "173", + "name": "[174]", + "element-type": "174", "meta-type": "array" }, { - "name": "173", + "name": "174", "tag": "target", "variants": [ { "case": "s390x", - "type": "354" + "type": "356" }, { "case": "aarch64", @@ -17298,24 +17348,24 @@ { "name": "props", "default": null, - "type": "347" + "type": "349" }, { "name": "arch", - "type": "348", + "type": "350", "features": [ "deprecated" ] }, { "name": "target", - "type": "356" + "type": "358" } ], "meta-type": "object" }, { - "name": "174", + "name": "175", "members": [ { "name": "id", @@ -17325,12 +17375,12 @@ "meta-type": "object" }, { - "name": "[175]", - "element-type": "175", + "name": "[176]", + "element-type": "176", "meta-type": "array" }, { - "name": "175", + "name": "176", "members": [ { "name": "name", @@ -17371,7 +17421,7 @@ "meta-type": "object" }, { - "name": "176", + "name": "177", "members": [ { "name": "wakeup-suspend-support", @@ -17381,22 +17431,22 @@ "meta-type": "object" }, { - "name": "177", + "name": "178", "members": [ { "name": "arch", - "type": "356" + "type": "358" } ], "meta-type": "object" }, { - "name": "[178]", - "element-type": "178", + "name": "[179]", + "element-type": "179", "meta-type": "array" }, { - "name": "178", + "name": "179", "members": [ { "name": "id", @@ -17425,18 +17475,18 @@ }, { "name": "policy", - "type": "357" + "type": "359" } ], "meta-type": "object" }, { - "name": "[179]", - "element-type": "179", + "name": "[180]", + "element-type": "180", "meta-type": "array" }, { - "name": "179", + "name": "180", "members": [ { "name": "type", @@ -17448,7 +17498,7 @@ }, { "name": "props", - "type": "347" + "type": "349" }, { "name": "qom-path", @@ -17459,69 +17509,69 @@ "meta-type": "object" }, { - "name": "180", + "name": "181", "tag": "type", "variants": [ { "case": "node", - "type": "359" + "type": "361" }, { "case": "dist", - "type": "360" + "type": "362" }, { "case": "cpu", - "type": "361" + "type": "363" }, { "case": "hmat-lb", - "type": "362" + "type": "364" }, { "case": "hmat-cache", - "type": "363" + "type": "365" } ], "members": [ { "name": "type", - "type": "358" + "type": "360" } ], "meta-type": "object" }, { - "name": "185", + "name": "186", "members": [ { "name": "type", - "type": "366" + "type": "368" }, { "name": "model", - "type": "364" + "type": "366" } ], "meta-type": "object" }, { - "name": "186", + "name": "187", "members": [ { "name": "model", - "type": "364" + "type": "366" } ], "meta-type": "object" }, { - "name": "[187]", - "element-type": "187", + "name": "[188]", + "element-type": "188", "meta-type": "array" }, { - "name": "187", + "name": "188", "members": [ { "name": "name", @@ -17554,7 +17604,7 @@ "meta-type": "object" }, { - "name": "188", + "name": "189", "members": [ { "name": "protocol", @@ -17578,7 +17628,7 @@ "meta-type": "object" }, { - "name": "189", + "name": "190", "members": [ { "name": "name", @@ -17589,7 +17639,7 @@ "meta-type": "object" }, { - "name": "190", + "name": "191", "members": [ { "name": "enabled", @@ -17603,7 +17653,7 @@ "meta-type": "object" }, { - "name": "191", + "name": "192", "members": [ { "name": "UUID", @@ -17613,12 +17663,12 @@ "meta-type": "object" }, { - "name": "[192]", - "element-type": "192", + "name": "[193]", + "element-type": "193", "meta-type": "array" }, { - "name": "192", + "name": "193", "members": [ { "name": "id", @@ -17644,7 +17694,7 @@ "meta-type": "object" }, { - "name": "193", + "name": "194", "members": [ { "name": "actual", @@ -17654,7 +17704,7 @@ "meta-type": "object" }, { - "name": "194", + "name": "195", "members": [ { "name": "actual", @@ -17664,12 +17714,12 @@ "meta-type": "object" }, { - "name": "[195]", - "element-type": "195", + "name": "[196]", + "element-type": "196", "meta-type": "array" }, { - "name": "195", + "name": "196", "members": [ { "name": "bus", @@ -17677,13 +17727,13 @@ }, { "name": "devices", - "type": "[367]" + "type": "[369]" } ], "meta-type": "object" }, { - "name": "196", + "name": "197", "members": [ { "name": "val", @@ -17706,7 +17756,7 @@ "meta-type": "object" }, { - "name": "197", + "name": "198", "members": [ { "name": "val", @@ -17724,7 +17774,7 @@ "meta-type": "object" }, { - "name": "198", + "name": "199", "members": [ { "name": "value", @@ -17734,7 +17784,7 @@ "meta-type": "object" }, { - "name": "199", + "name": "200", "members": [ { "name": "command-line", @@ -17749,7 +17799,7 @@ "meta-type": "object" }, { - "name": "200", + "name": "201", "members": [ { "name": "device", @@ -17768,7 +17818,7 @@ "meta-type": "object" }, { - "name": "201", + "name": "202", "members": [ { "name": "enable", @@ -17778,7 +17828,7 @@ "meta-type": "object" }, { - "name": "202", + "name": "203", "members": [ { "name": "fdname", @@ -17788,7 +17838,7 @@ "meta-type": "object" }, { - "name": "203", + "name": "204", "members": [ { "name": "fdname", @@ -17798,7 +17848,7 @@ "meta-type": "object" }, { - "name": "204", + "name": "205", "members": [ { "name": "base-memory", @@ -17813,7 +17863,7 @@ "meta-type": "object" }, { - "name": "205", + "name": "206", "members": [ { "name": "fdset-id", @@ -17829,7 +17879,7 @@ "meta-type": "object" }, { - "name": "206", + "name": "207", "members": [ { "name": "fdset-id", @@ -17843,7 +17893,7 @@ "meta-type": "object" }, { - "name": "207", + "name": "208", "members": [ { "name": "fdset-id", @@ -17858,12 +17908,12 @@ "meta-type": "object" }, { - "name": "[208]", - "element-type": "208", + "name": "[209]", + "element-type": "209", "meta-type": "array" }, { - "name": "208", + "name": "209", "members": [ { "name": "fdset-id", @@ -17871,13 +17921,13 @@ }, { "name": "fds", - "type": "[368]" + "type": "[370]" } ], "meta-type": "object" }, { - "name": "209", + "name": "210", "members": [ { "name": "option", @@ -17888,12 +17938,12 @@ "meta-type": "object" }, { - "name": "[210]", - "element-type": "210", + "name": "[211]", + "element-type": "211", "meta-type": "array" }, { - "name": "210", + "name": "211", "members": [ { "name": "option", @@ -17901,43 +17951,43 @@ }, { "name": "parameters", - "type": "[369]" + "type": "[371]" } ], "meta-type": "object" }, { - "name": "[211]", - "element-type": "211", + "name": "[212]", + "element-type": "212", "meta-type": "array" }, { - "name": "211", + "name": "212", "tag": "type", "variants": [ { "case": "dimm", - "type": "371" + "type": "373" }, { "case": "nvdimm", - "type": "371" + "type": "373" }, { "case": "virtio-pmem", - "type": "372" + "type": "374" } ], "members": [ { "name": "type", - "type": "370" + "type": "372" } ], "meta-type": "object" }, { - "name": "212", + "name": "213", "members": [ { "name": "device", @@ -17951,12 +18001,12 @@ "meta-type": "object" }, { - "name": "[213]", - "element-type": "213", + "name": "[214]", + "element-type": "214", "meta-type": "array" }, { - "name": "213", + "name": "214", "members": [ { "name": "device", @@ -17969,7 +18019,7 @@ }, { "name": "slot-type", - "type": "373" + "type": "375" }, { "name": "source", @@ -17983,17 +18033,17 @@ "meta-type": "object" }, { - "name": "214", + "name": "215", "members": [ { "name": "info", - "type": "213" + "type": "214" } ], "meta-type": "object" }, { - "name": "215", + "name": "216", "members": [ { "name": "filename", @@ -18003,7 +18053,7 @@ "meta-type": "object" }, { - "name": "216", + "name": "217", "members": [ { "name": "guid", @@ -18013,7 +18063,7 @@ "meta-type": "object" }, { - "name": "217", + "name": "218", "members": [ { "name": "offset", @@ -18023,7 +18073,7 @@ "meta-type": "object" }, { - "name": "218", + "name": "219", "members": [ { "name": "enabled", @@ -18047,7 +18097,7 @@ }, { "name": "state", - "type": "374" + "type": "376" }, { "name": "handle", @@ -18057,7 +18107,7 @@ "meta-type": "object" }, { - "name": "219", + "name": "220", "members": [ { "name": "data", @@ -18067,7 +18117,7 @@ "meta-type": "object" }, { - "name": "220", + "name": "221", "members": [ { "name": "pdh", @@ -18094,7 +18144,7 @@ "meta-type": "builtin" }, { - "name": "223", + "name": "224", "meta-type": "enum", "values": [ "debug", @@ -18117,7 +18167,7 @@ ] }, { - "name": "224", + "name": "225", "meta-type": "enum", "values": [ "none", @@ -18133,7 +18183,7 @@ ] }, { - "name": "225", + "name": "226", "meta-type": "enum", "values": [ "reset", @@ -18146,7 +18196,7 @@ ] }, { - "name": "226", + "name": "227", "meta-type": "enum", "values": [ "pause", @@ -18155,28 +18205,28 @@ ] }, { - "name": "227", + "name": "228", "tag": "type", "variants": [ { "case": "hyper-v", - "type": "376" + "type": "378" }, { "case": "s390", - "type": "377" + "type": "379" } ], "members": [ { "name": "type", - "type": "375" + "type": "377" } ], "meta-type": "object" }, { - "name": "228", + "name": "229", "meta-type": "enum", "values": [ "retain", @@ -18190,7 +18240,7 @@ "meta-type": "array" }, { - "name": "229", + "name": "230", "meta-type": "enum", "values": [ "ok", @@ -18199,12 +18249,12 @@ ] }, { - "name": "[230]", - "element-type": "230", + "name": "[231]", + "element-type": "231", "meta-type": "array" }, { - "name": "230", + "name": "231", "members": [ { "name": "name", @@ -18229,7 +18279,7 @@ }, { "name": "status", - "type": "378", + "type": "380", "features": [ "deprecated" ] @@ -18247,7 +18297,7 @@ "meta-type": "object" }, { - "name": "231", + "name": "232", "members": [ { "name": "rd_bytes", @@ -18356,37 +18406,37 @@ }, { "name": "timed_stats", - "type": "[379]" + "type": "[381]" }, { "name": "rd_latency_histogram", "default": null, - "type": "380" + "type": "382" }, { "name": "wr_latency_histogram", "default": null, - "type": "380" + "type": "382" }, { "name": "flush_latency_histogram", "default": null, - "type": "380" + "type": "382" } ], "meta-type": "object" }, { - "name": "232", + "name": "233", "tag": "driver", "variants": [ { "case": "file", - "type": "381" + "type": "383" }, { "case": "host_device", - "type": "381" + "type": "383" }, { "case": "blkdebug", @@ -18548,13 +18598,13 @@ "members": [ { "name": "driver", - "type": "245" + "type": "247" } ], "meta-type": "object" }, { - "name": "233", + "name": "234", "meta-type": "enum", "values": [ "undefined", @@ -18571,7 +18621,7 @@ ] }, { - "name": "234", + "name": "235", "meta-type": "enum", "values": [ "existing", @@ -18579,7 +18629,7 @@ ] }, { - "name": "235", + "name": "236", "meta-type": "enum", "values": [ "report", @@ -18590,7 +18640,7 @@ ] }, { - "name": "236", + "name": "237", "meta-type": "enum", "values": [ "top", @@ -18601,7 +18651,7 @@ ] }, { - "name": "237", + "name": "238", "meta-type": "enum", "values": [ "on-success", @@ -18610,7 +18660,7 @@ ] }, { - "name": "238", + "name": "239", "meta-type": "enum", "values": [ "off", @@ -18619,7 +18669,7 @@ ] }, { - "name": "239", + "name": "240", "members": [ { "name": "filename", @@ -18676,23 +18726,23 @@ { "name": "snapshots", "default": null, - "type": "[69]" + "type": "[70]" }, { "name": "backing-image", "default": null, - "type": "239" + "type": "240" }, { "name": "format-specific", "default": null, - "type": "382" + "type": "384" } ], "meta-type": "object" }, { - "name": "240", + "name": "241", "members": [ { "name": "writeback", @@ -18710,12 +18760,12 @@ "meta-type": "object" }, { - "name": "[241]", - "element-type": "241", + "name": "[242]", + "element-type": "242", "meta-type": "array" }, { - "name": "241", + "name": "242", "members": [ { "name": "id", @@ -18723,7 +18773,7 @@ }, { "name": "type", - "type": "383" + "type": "385" }, { "name": "name", @@ -18733,12 +18783,12 @@ "meta-type": "object" }, { - "name": "[242]", - "element-type": "242", + "name": "[243]", + "element-type": "243", "meta-type": "array" }, { - "name": "242", + "name": "243", "members": [ { "name": "parent", @@ -18754,17 +18804,17 @@ }, { "name": "perm", - "type": "[384]" + "type": "[386]" }, { "name": "shared-perm", - "type": "[384]" + "type": "[386]" } ], "meta-type": "object" }, { - "name": "243", + "name": "244", "meta-type": "enum", "values": [ "background", @@ -18772,12 +18822,12 @@ ] }, { - "name": "[244]", - "element-type": "244", + "name": "[245]", + "element-type": "245", "meta-type": "array" }, { - "name": "244", + "name": "245", "members": [ { "type": "str" @@ -18789,7 +18839,14 @@ "meta-type": "alternate" }, { - "name": "245", + "name": "246", + "meta-type": "enum", + "values": [ + "allocation-top" + ] + }, + { + "name": "247", "meta-type": "enum", "values": [ "blkdebug", @@ -18836,7 +18893,7 @@ ] }, { - "name": "246", + "name": "248", "meta-type": "enum", "values": [ "ignore", @@ -18844,7 +18901,7 @@ ] }, { - "name": "247", + "name": "249", "members": [ { "name": "direct", @@ -18860,11 +18917,11 @@ "meta-type": "object" }, { - "name": "248", + "name": "250", "members": [ { "name": "image", - "type": "385" + "type": "387" }, { "name": "config", @@ -18904,36 +18961,36 @@ { "name": "inject-error", "default": null, - "type": "[386]" + "type": "[388]" }, { "name": "set-state", "default": null, - "type": "[387]" + "type": "[389]" }, { "name": "take-child-perms", "default": null, - "type": "[384]" + "type": "[386]" }, { "name": "unshare-child-perms", "default": null, - "type": "[384]" + "type": "[386]" } ], "meta-type": "object" }, { - "name": "249", + "name": "251", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "log", - "type": "385" + "type": "387" }, { "name": "log-sector-size", @@ -18954,41 +19011,41 @@ "meta-type": "object" }, { - "name": "250", + "name": "252", "members": [ { "name": "test", - "type": "385" + "type": "387" }, { "name": "raw", - "type": "385" + "type": "387" } ], "meta-type": "object" }, { - "name": "251", + "name": "253", "members": [ { "name": "image", - "type": "385" + "type": "387" } ], "meta-type": "object" }, { - "name": "252", + "name": "254", "members": [ { "name": "file", - "type": "385" + "type": "387" } ], "meta-type": "object" }, { - "name": "253", + "name": "255", "members": [ { "name": "filename", @@ -19002,12 +19059,12 @@ { "name": "locking", "default": null, - "type": "388" + "type": "390" }, { "name": "aio", "default": null, - "type": "389" + "type": "391" }, { "name": "drop-cache", @@ -19026,7 +19083,7 @@ ] }, { - "name": "254", + "name": "256", "members": [ { "name": "url", @@ -19066,7 +19123,7 @@ "meta-type": "object" }, { - "name": "255", + "name": "257", "members": [ { "name": "url", @@ -19111,7 +19168,7 @@ "meta-type": "object" }, { - "name": "256", + "name": "258", "members": [ { "name": "volume", @@ -19123,7 +19180,7 @@ }, { "name": "server", - "type": "[329]" + "type": "[331]" }, { "name": "debug", @@ -19139,7 +19196,7 @@ "meta-type": "object" }, { - "name": "257", + "name": "259", "members": [ { "name": "url", @@ -19189,7 +19246,7 @@ "meta-type": "object" }, { - "name": "258", + "name": "260", "members": [ { "name": "url", @@ -19244,11 +19301,11 @@ "meta-type": "object" }, { - "name": "259", + "name": "261", "members": [ { "name": "transport", - "type": "390" + "type": "392" }, { "name": "portal", @@ -19281,7 +19338,7 @@ { "name": "header-digest", "default": null, - "type": "391" + "type": "393" }, { "name": "timeout", @@ -19292,11 +19349,11 @@ "meta-type": "object" }, { - "name": "260", + "name": "262", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "key-secret", @@ -19307,11 +19364,11 @@ "meta-type": "object" }, { - "name": "261", + "name": "263", "members": [ { "name": "server", - "type": "329" + "type": "331" }, { "name": "export", @@ -19337,11 +19394,11 @@ "meta-type": "object" }, { - "name": "262", + "name": "264", "members": [ { "name": "server", - "type": "392" + "type": "394" }, { "name": "path", @@ -19381,7 +19438,7 @@ "meta-type": "object" }, { - "name": "263", + "name": "265", "members": [ { "name": "size", @@ -19402,7 +19459,7 @@ "meta-type": "object" }, { - "name": "264", + "name": "266", "members": [ { "name": "device", @@ -19416,16 +19473,16 @@ "meta-type": "object" }, { - "name": "265", + "name": "267", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "backing", "default": null, - "type": "393" + "type": "395" }, { "name": "lazy-refcounts", @@ -19450,7 +19507,7 @@ { "name": "overlap-check", "default": null, - "type": "394" + "type": "396" }, { "name": "cache-size", @@ -19480,53 +19537,53 @@ { "name": "encrypt", "default": null, - "type": "395" + "type": "397" }, { "name": "data-file", "default": null, - "type": "385" + "type": "387" } ], "meta-type": "object" }, { - "name": "266", + "name": "268", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "backing", "default": null, - "type": "393" + "type": "395" }, { "name": "encrypt", "default": null, - "type": "396" + "type": "398" } ], "meta-type": "object" }, { - "name": "267", + "name": "269", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "backing", "default": null, - "type": "393" + "type": "395" } ], "meta-type": "object" }, { - "name": "268", + "name": "270", "members": [ { "name": "blkverify", @@ -19535,7 +19592,7 @@ }, { "name": "children", - "type": "[385]" + "type": "[387]" }, { "name": "vote-threshold", @@ -19549,17 +19606,17 @@ { "name": "read-pattern", "default": null, - "type": "397" + "type": "399" } ], "meta-type": "object" }, { - "name": "269", + "name": "271", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "offset", @@ -19575,7 +19632,7 @@ "meta-type": "object" }, { - "name": "270", + "name": "272", "members": [ { "name": "pool", @@ -19608,7 +19665,7 @@ { "name": "auth-client-required", "default": null, - "type": "[398]" + "type": "[400]" }, { "name": "key-secret", @@ -19618,21 +19675,21 @@ { "name": "server", "default": null, - "type": "[399]" + "type": "[401]" } ], "meta-type": "object" }, { - "name": "271", + "name": "273", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "mode", - "type": "400" + "type": "402" }, { "name": "top-id", @@ -19643,11 +19700,11 @@ "meta-type": "object" }, { - "name": "272", + "name": "274", "members": [ { "name": "server", - "type": "329" + "type": "331" }, { "name": "vdi", @@ -19667,11 +19724,11 @@ "meta-type": "object" }, { - "name": "273", + "name": "275", "members": [ { "name": "server", - "type": "401" + "type": "403" }, { "name": "path", @@ -19685,13 +19742,13 @@ { "name": "host-key-check", "default": null, - "type": "402" + "type": "404" } ], "meta-type": "object" }, { - "name": "274", + "name": "276", "members": [ { "name": "throttle-group", @@ -19699,13 +19756,13 @@ }, { "name": "file", - "type": "385" + "type": "387" } ], "meta-type": "object" }, { - "name": "275", + "name": "277", "members": [ { "name": "dir", @@ -19735,7 +19792,7 @@ "meta-type": "object" }, { - "name": "276", + "name": "278", "members": [ { "name": "vdisk-id", @@ -19743,7 +19800,7 @@ }, { "name": "server", - "type": "399" + "type": "401" }, { "name": "tls-creds", @@ -19754,68 +19811,68 @@ "meta-type": "object" }, { - "name": "277", + "name": "279", "tag": "driver", "variants": [ { "case": "file", - "type": "403" + "type": "405" }, { "case": "gluster", - "type": "404" + "type": "406" }, { "case": "luks", - "type": "405" + "type": "407" }, { "case": "nfs", - "type": "406" + "type": "408" }, { "case": "parallels", - "type": "407" + "type": "409" }, { "case": "qcow", - "type": "408" + "type": "410" }, { "case": "qcow2", - "type": "409" + "type": "411" }, { "case": "qed", - "type": "410" + "type": "412" }, { "case": "rbd", - "type": "411" + "type": "413" }, { "case": "sheepdog", - "type": "412" + "type": "414" }, { "case": "ssh", - "type": "413" + "type": "415" }, { "case": "vdi", - "type": "414" + "type": "416" }, { "case": "vhdx", - "type": "415" + "type": "417" }, { "case": "vmdk", - "type": "416" + "type": "418" }, { "case": "vpc", - "type": "417" + "type": "419" }, { "case": "blkdebug", @@ -19925,13 +19982,13 @@ "members": [ { "name": "driver", - "type": "245" + "type": "247" } ], "meta-type": "object" }, { - "name": "278", + "name": "280", "meta-type": "enum", "values": [ "read", @@ -19939,7 +19996,7 @@ ] }, { - "name": "279", + "name": "281", "meta-type": "enum", "values": [ "ignore", @@ -19948,18 +20005,19 @@ ] }, { - "name": "280", + "name": "282", "meta-type": "enum", "values": [ "commit", "stream", "mirror", "backup", - "create" + "create", + "bitmap-populate" ] }, { - "name": "281", + "name": "283", "members": [ { "type": "str" @@ -19971,36 +20029,36 @@ "meta-type": "alternate" }, { - "name": "282", + "name": "284", "tag": "type", "variants": [ { "case": "inet", - "type": "419" + "type": "421" }, { "case": "unix", - "type": "420" + "type": "422" }, { "case": "vsock", - "type": "421" + "type": "423" }, { "case": "fd", - "type": "422" + "type": "424" } ], "members": [ { "name": "type", - "type": "418" + "type": "420" } ], "meta-type": "object" }, { - "name": "283", + "name": "285", "meta-type": "enum", "values": [ "safe", @@ -20008,7 +20066,7 @@ ] }, { - "name": "284", + "name": "286", "meta-type": "enum", "values": [ "read", @@ -20017,7 +20075,7 @@ ] }, { - "name": "285", + "name": "287", "meta-type": "enum", "values": [ "utf8", @@ -20025,100 +20083,100 @@ ] }, { - "name": "286", + "name": "288", "tag": "type", "variants": [ { "case": "file", - "type": "424" + "type": "426" }, { "case": "serial", - "type": "425" + "type": "427" }, { "case": "parallel", - "type": "425" + "type": "427" }, { "case": "pipe", - "type": "425" + "type": "427" }, { "case": "socket", - "type": "426" + "type": "428" }, { "case": "udp", - "type": "427" + "type": "429" }, { "case": "pty", - "type": "428" + "type": "430" }, { "case": "null", - "type": "428" + "type": "430" }, { "case": "mux", - "type": "429" + "type": "431" }, { "case": "msmouse", - "type": "428" + "type": "430" }, { "case": "wctablet", - "type": "428" + "type": "430" }, { "case": "braille", - "type": "428" + "type": "430" }, { "case": "testdev", - "type": "428" + "type": "430" }, { "case": "stdio", - "type": "430" + "type": "432" }, { "case": "console", - "type": "428" + "type": "430" }, { "case": "spicevmc", - "type": "431" + "type": "433" }, { "case": "spiceport", - "type": "432" + "type": "434" }, { "case": "vc", - "type": "433" + "type": "435" }, { "case": "ringbuf", - "type": "434" + "type": "436" }, { "case": "memory", - "type": "434" + "type": "436" } ], "members": [ { "name": "type", - "type": "423" + "type": "425" } ], "meta-type": "object" }, { - "name": "287", + "name": "289", "meta-type": "enum", "values": [ "elf", @@ -20129,7 +20187,7 @@ ] }, { - "name": "288", + "name": "290", "meta-type": "enum", "values": [ "none", @@ -20139,12 +20197,12 @@ ] }, { - "name": "[287]", - "element-type": "287", + "name": "[289]", + "element-type": "289", "meta-type": "array" }, { - "name": "289", + "name": "291", "meta-type": "enum", "values": [ "none", @@ -20161,7 +20219,7 @@ ] }, { - "name": "290", + "name": "292", "members": [ { "name": "netdev", @@ -20192,7 +20250,7 @@ "meta-type": "object" }, { - "name": "291", + "name": "293", "members": [ { "name": "hostname", @@ -20252,7 +20310,7 @@ { "name": "dnssearch", "default": null, - "type": "[435]" + "type": "[437]" }, { "name": "domainname", @@ -20292,12 +20350,12 @@ { "name": "hostfwd", "default": null, - "type": "[435]" + "type": "[437]" }, { "name": "guestfwd", "default": null, - "type": "[435]" + "type": "[437]" }, { "name": "tftp-server-name", @@ -20308,7 +20366,7 @@ "meta-type": "object" }, { - "name": "292", + "name": "294", "members": [ { "name": "ifname", @@ -20389,7 +20447,7 @@ "meta-type": "object" }, { - "name": "293", + "name": "295", "members": [ { "name": "src", @@ -20462,7 +20520,7 @@ "meta-type": "object" }, { - "name": "294", + "name": "296", "members": [ { "name": "fd", @@ -20498,7 +20556,7 @@ "meta-type": "object" }, { - "name": "295", + "name": "297", "members": [ { "name": "sock", @@ -20524,7 +20582,7 @@ "meta-type": "object" }, { - "name": "296", + "name": "298", "members": [ { "name": "br", @@ -20540,7 +20598,7 @@ "meta-type": "object" }, { - "name": "297", + "name": "299", "members": [ { "name": "hubid", @@ -20555,7 +20613,7 @@ "meta-type": "object" }, { - "name": "298", + "name": "300", "members": [ { "name": "ifname", @@ -20570,7 +20628,7 @@ "meta-type": "object" }, { - "name": "299", + "name": "301", "members": [ { "name": "chardev", @@ -20590,7 +20648,7 @@ "meta-type": "object" }, { - "name": "300", + "name": "302", "meta-type": "enum", "values": [ "normal", @@ -20604,7 +20662,7 @@ "meta-type": "array" }, { - "name": "301", + "name": "303", "meta-type": "enum", "values": [ "half", @@ -20612,7 +20670,7 @@ ] }, { - "name": "302", + "name": "304", "meta-type": "enum", "values": [ "off", @@ -20620,7 +20678,7 @@ ] }, { - "name": "303", + "name": "305", "members": [ { "name": "priority", @@ -20679,7 +20737,7 @@ "meta-type": "object" }, { - "name": "304", + "name": "306", "members": [ { "name": "in-pport", @@ -20720,7 +20778,7 @@ "meta-type": "object" }, { - "name": "305", + "name": "307", "members": [ { "name": "goto-tbl", @@ -20756,28 +20814,28 @@ "meta-type": "object" }, { - "name": "306", + "name": "308", "tag": "type", "variants": [ { "case": "passthrough", - "type": "437" + "type": "439" }, { "case": "emulator", - "type": "438" + "type": "440" } ], "members": [ { "name": "type", - "type": "436" + "type": "438" } ], "meta-type": "object" }, { - "name": "307", + "name": "309", "meta-type": "enum", "values": [ "client", @@ -20786,12 +20844,12 @@ ] }, { - "name": "[308]", - "element-type": "308", + "name": "[310]", + "element-type": "310", "meta-type": "array" }, { - "name": "308", + "name": "310", "members": [ { "name": "host", @@ -20803,7 +20861,7 @@ }, { "name": "family", - "type": "311" + "type": "313" }, { "name": "connection-id", @@ -20825,7 +20883,7 @@ "meta-type": "object" }, { - "name": "309", + "name": "311", "members": [ { "name": "host", @@ -20837,13 +20895,13 @@ }, { "name": "family", - "type": "311" + "type": "313" } ], "meta-type": "object" }, { - "name": "310", + "name": "312", "members": [ { "name": "host", @@ -20855,7 +20913,7 @@ }, { "name": "family", - "type": "311" + "type": "313" }, { "name": "auth", @@ -20866,7 +20924,7 @@ "meta-type": "object" }, { - "name": "311", + "name": "313", "meta-type": "enum", "values": [ "ipv4", @@ -20877,12 +20935,12 @@ ] }, { - "name": "[312]", - "element-type": "312", + "name": "[314]", + "element-type": "314", "meta-type": "array" }, { - "name": "312", + "name": "314", "members": [ { "name": "host", @@ -20894,7 +20952,7 @@ }, { "name": "family", - "type": "311" + "type": "313" }, { "name": "websocket", @@ -20914,12 +20972,12 @@ "meta-type": "object" }, { - "name": "[313]", - "element-type": "313", + "name": "[315]", + "element-type": "315", "meta-type": "array" }, { - "name": "313", + "name": "315", "members": [ { "name": "host", @@ -20931,7 +20989,7 @@ }, { "name": "family", - "type": "311" + "type": "313" }, { "name": "websocket", @@ -20939,18 +20997,18 @@ }, { "name": "auth", - "type": "314" + "type": "316" }, { "name": "vencrypt", "default": null, - "type": "315" + "type": "317" } ], "meta-type": "object" }, { - "name": "314", + "name": "316", "meta-type": "enum", "values": [ "none", @@ -20965,7 +21023,7 @@ ] }, { - "name": "315", + "name": "317", "meta-type": "enum", "values": [ "plain", @@ -20980,7 +21038,7 @@ ] }, { - "name": "316", + "name": "318", "members": [ { "name": "host", @@ -20992,7 +21050,7 @@ }, { "name": "family", - "type": "311" + "type": "313" }, { "name": "websocket", @@ -21007,7 +21065,7 @@ "meta-type": "object" }, { - "name": "317", + "name": "319", "members": [ { "name": "host", @@ -21019,7 +21077,7 @@ }, { "name": "family", - "type": "311" + "type": "313" }, { "name": "websocket", @@ -21029,67 +21087,67 @@ "meta-type": "object" }, { - "name": "[318]", - "element-type": "318", + "name": "[320]", + "element-type": "320", "meta-type": "array" }, { - "name": "318", + "name": "320", "tag": "type", "variants": [ { "case": "number", - "type": "440" + "type": "442" }, { "case": "qcode", - "type": "441" + "type": "443" } ], "members": [ { "name": "type", - "type": "439" + "type": "441" } ], "meta-type": "object" }, { - "name": "[319]", - "element-type": "319", + "name": "[321]", + "element-type": "321", "meta-type": "array" }, { - "name": "319", + "name": "321", "tag": "type", "variants": [ { "case": "key", - "type": "443" + "type": "445" }, { "case": "btn", - "type": "444" + "type": "446" }, { "case": "rel", - "type": "445" + "type": "447" }, { "case": "abs", - "type": "445" + "type": "447" } ], "members": [ { "name": "type", - "type": "442" + "type": "444" } ], "meta-type": "object" }, { - "name": "320", + "name": "322", "meta-type": "enum", "values": [ "default", @@ -21103,7 +21161,7 @@ ] }, { - "name": "321", + "name": "323", "meta-type": "enum", "values": [ "off", @@ -21113,7 +21171,7 @@ ] }, { - "name": "322", + "name": "324", "members": [ { "name": "grab-on-hover", @@ -21129,7 +21187,7 @@ "meta-type": "object" }, { - "name": "323", + "name": "325", "members": [ { "name": "charset", @@ -21140,7 +21198,7 @@ "meta-type": "object" }, { - "name": "324", + "name": "326", "members": [ { "name": "rendernode", @@ -21151,7 +21209,7 @@ "meta-type": "object" }, { - "name": "325", + "name": "327", "meta-type": "enum", "values": [ "none", @@ -21171,7 +21229,7 @@ ] }, { - "name": "326", + "name": "328", "members": [ { "name": "transferred", @@ -21233,7 +21291,7 @@ "meta-type": "object" }, { - "name": "327", + "name": "329", "members": [ { "name": "cache-size", @@ -21267,7 +21325,7 @@ "meta-type": "object" }, { - "name": "328", + "name": "330", "members": [ { "name": "pages", @@ -21293,41 +21351,41 @@ "meta-type": "object" }, { - "name": "[329]", - "element-type": "329", + "name": "[331]", + "element-type": "331", "meta-type": "array" }, { - "name": "329", + "name": "331", "tag": "type", "variants": [ { "case": "inet", - "type": "401" + "type": "403" }, { "case": "unix", - "type": "447" + "type": "449" }, { "case": "vsock", - "type": "448" + "type": "450" }, { "case": "fd", - "type": "435" + "type": "437" } ], "members": [ { "name": "type", - "type": "446" + "type": "448" } ], "meta-type": "object" }, { - "name": "330", + "name": "332", "meta-type": "enum", "values": [ "xbzrle", @@ -21351,7 +21409,7 @@ ] }, { - "name": "331", + "name": "333", "meta-type": "enum", "values": [ "none", @@ -21359,7 +21417,7 @@ ] }, { - "name": "332", + "name": "334", "meta-type": "enum", "values": [ "none", @@ -21368,7 +21426,7 @@ ] }, { - "name": "333", + "name": "335", "meta-type": "enum", "values": [ "none", @@ -21383,84 +21441,88 @@ "meta-type": "builtin" }, { - "name": "[334]", - "element-type": "334", + "name": "[336]", + "element-type": "336", "meta-type": "array" }, { - "name": "334", + "name": "336", "tag": "type", "variants": [ { "case": "abort", - "type": "450" + "type": "452" }, { "case": "block-dirty-bitmap-add", - "type": "451" + "type": "453" }, { "case": "block-dirty-bitmap-remove", - "type": "452" + "type": "454" }, { "case": "block-dirty-bitmap-clear", - "type": "452" + "type": "454" }, { "case": "block-dirty-bitmap-enable", - "type": "452" + "type": "454" }, { "case": "block-dirty-bitmap-disable", - "type": "452" + "type": "454" }, { "case": "block-dirty-bitmap-merge", - "type": "453" + "type": "455" + }, + { + "case": "block-dirty-bitmap-populate", + "type": "456" }, { "case": "blockdev-backup", - "type": "454" + "type": "457" }, { "case": "blockdev-snapshot", - "type": "455" + "type": "458" }, { "case": "blockdev-snapshot-internal-sync", - "type": "456" + "type": "459" }, { "case": "blockdev-snapshot-sync", - "type": "457" + "type": "460" }, { "case": "drive-backup", - "type": "458" + "type": "461" } ], "members": [ { "name": "type", - "type": "449" + "type": "451" } ], "meta-type": "object" }, { - "name": "335", + "name": "337", "members": [ { "name": "completion-mode", "default": null, - "type": "459" + "type": "462" } ], "meta-type": "object" }, { - "name": "336", + "name": "338", "meta-type": "enum", "values": [ "unavailable", @@ -21469,19 +21531,19 @@ ] }, { - "name": "[337]", - "element-type": "337", + "name": "[339]", + "element-type": "339", "meta-type": "array" }, { - "name": "337", + "name": "339", "meta-type": "enum", "values": [ "oob" ] }, { - "name": "338", + "name": "340", "members": [ { "name": "major", @@ -21499,7 +21561,7 @@ "meta-type": "object" }, { - "name": "339", + "name": "341", "meta-type": "enum", "values": [ "builtin", @@ -21512,17 +21574,17 @@ ] }, { - "name": "340", + "name": "342", "members": [ { "name": "json-type", - "type": "460" + "type": "463" } ], "meta-type": "object" }, { - "name": "341", + "name": "343", "members": [ { "name": "values", @@ -21532,7 +21594,7 @@ "meta-type": "object" }, { - "name": "342", + "name": "344", "members": [ { "name": "element-type", @@ -21542,11 +21604,11 @@ "meta-type": "object" }, { - "name": "343", + "name": "345", "members": [ { "name": "members", - "type": "[461]" + "type": "[464]" }, { "name": "tag", @@ -21556,23 +21618,23 @@ { "name": "variants", "default": null, - "type": "[462]" + "type": "[465]" } ], "meta-type": "object" }, { - "name": "344", + "name": "346", "members": [ { "name": "members", - "type": "[463]" + "type": "[466]" } ], "meta-type": "object" }, { - "name": "345", + "name": "347", "members": [ { "name": "arg-type", @@ -21591,7 +21653,7 @@ "meta-type": "object" }, { - "name": "346", + "name": "348", "members": [ { "name": "arg-type", @@ -21601,7 +21663,7 @@ "meta-type": "object" }, { - "name": "347", + "name": "349", "members": [ { "name": "node-id", @@ -21632,7 +21694,7 @@ "meta-type": "object" }, { - "name": "348", + "name": "350", "meta-type": "enum", "values": [ "x86", @@ -21646,7 +21708,7 @@ ] }, { - "name": "349", + "name": "351", "members": [ { "name": "pc", @@ -21656,7 +21718,7 @@ "meta-type": "object" }, { - "name": "350", + "name": "352", "members": [ { "name": "pc", @@ -21670,7 +21732,7 @@ "meta-type": "object" }, { - "name": "351", + "name": "353", "members": [ { "name": "nip", @@ -21680,7 +21742,7 @@ "meta-type": "object" }, { - "name": "352", + "name": "354", "members": [ { "name": "PC", @@ -21690,7 +21752,7 @@ "meta-type": "object" }, { - "name": "353", + "name": "355", "members": [ { "name": "PC", @@ -21700,17 +21762,17 @@ "meta-type": "object" }, { - "name": "354", + "name": "356", "members": [ { "name": "cpu-state", - "type": "464" + "type": "467" } ], "meta-type": "object" }, { - "name": "355", + "name": "357", "members": [ { "name": "pc", @@ -21720,7 +21782,7 @@ "meta-type": "object" }, { - "name": "356", + "name": "358", "meta-type": "enum", "values": [ "aarch64", @@ -21758,7 +21820,7 @@ ] }, { - "name": "357", + "name": "359", "meta-type": "enum", "values": [ "default", @@ -21768,7 +21830,7 @@ ] }, { - "name": "358", + "name": "360", "meta-type": "enum", "values": [ "node", @@ -21779,7 +21841,7 @@ ] }, { - "name": "359", + "name": "361", "members": [ { "name": "nodeid", @@ -21810,7 +21872,7 @@ "meta-type": "object" }, { - "name": "360", + "name": "362", "members": [ { "name": "src", @@ -21828,7 +21890,7 @@ "meta-type": "object" }, { - "name": "361", + "name": "363", "members": [ { "name": "node-id", @@ -21859,7 +21921,7 @@ "meta-type": "object" }, { - "name": "362", + "name": "364", "members": [ { "name": "initiator", @@ -21871,11 +21933,11 @@ }, { "name": "hierarchy", - "type": "465" + "type": "468" }, { "name": "data-type", - "type": "466" + "type": "469" }, { "name": "latency", @@ -21891,7 +21953,7 @@ "meta-type": "object" }, { - "name": "363", + "name": "365", "members": [ { "name": "node-id", @@ -21907,11 +21969,11 @@ }, { "name": "associativity", - "type": "467" + "type": "470" }, { "name": "policy", - "type": "468" + "type": "471" }, { "name": "line", @@ -21921,7 +21983,7 @@ "meta-type": "object" }, { - "name": "364", + "name": "366", "members": [ { "name": "name", @@ -21936,7 +21998,7 @@ "meta-type": "object" }, { - "name": "365", + "name": "367", "meta-type": "enum", "values": [ "incompatible", @@ -21946,7 +22008,7 @@ ] }, { - "name": "366", + "name": "368", "meta-type": "enum", "values": [ "static", @@ -21954,12 +22016,12 @@ ] }, { - "name": "[367]", - "element-type": "367", + "name": "[369]", + "element-type": "369", "meta-type": "array" }, { - "name": "367", + "name": "369", "members": [ { "name": "bus", @@ -21975,11 +22037,11 @@ }, { "name": "class_info", - "type": "469" + "type": "472" }, { "name": "id", - "type": "470" + "type": "473" }, { "name": "irq", @@ -21993,22 +22055,22 @@ { "name": "pci_bridge", "default": null, - "type": "471" + "type": "474" }, { "name": "regions", - "type": "[472]" + "type": "[475]" } ], "meta-type": "object" }, { - "name": "[368]", - "element-type": "368", + "name": "[370]", + "element-type": "370", "meta-type": "array" }, { - "name": "368", + "name": "370", "members": [ { "name": "fd", @@ -22023,12 +22085,12 @@ "meta-type": "object" }, { - "name": "[369]", - "element-type": "369", + "name": "[371]", + "element-type": "371", "meta-type": "array" }, { - "name": "369", + "name": "371", "members": [ { "name": "name", @@ -22036,7 +22098,7 @@ }, { "name": "type", - "type": "473" + "type": "476" }, { "name": "help", @@ -22052,7 +22114,7 @@ "meta-type": "object" }, { - "name": "370", + "name": "372", "meta-type": "enum", "values": [ "dimm", @@ -22061,27 +22123,27 @@ ] }, { - "name": "371", + "name": "373", "members": [ { "name": "data", - "type": "474" + "type": "477" } ], "meta-type": "object" }, { - "name": "372", + "name": "374", "members": [ { "name": "data", - "type": "475" + "type": "478" } ], "meta-type": "object" }, { - "name": "373", + "name": "375", "meta-type": "enum", "values": [ "DIMM", @@ -22089,7 +22151,7 @@ ] }, { - "name": "374", + "name": "376", "meta-type": "enum", "values": [ "uninit", @@ -22101,7 +22163,7 @@ ] }, { - "name": "375", + "name": "377", "meta-type": "enum", "values": [ "hyper-v", @@ -22109,7 +22171,7 @@ ] }, { - "name": "376", + "name": "378", "members": [ { "name": "arg1", @@ -22135,7 +22197,7 @@ "meta-type": "object" }, { - "name": "377", + "name": "379", "members": [ { "name": "core", @@ -22151,13 +22213,13 @@ }, { "name": "reason", - "type": "476" + "type": "479" } ], "meta-type": "object" }, { - "name": "378", + "name": "380", "meta-type": "enum", "values": [ "active", @@ -22168,12 +22230,12 @@ ] }, { - "name": "[379]", - "element-type": "379", + "name": "[381]", + "element-type": "381", "meta-type": "array" }, { - "name": "379", + "name": "381", "members": [ { "name": "interval_length", @@ -22227,7 +22289,7 @@ "meta-type": "object" }, { - "name": "380", + "name": "382", "members": [ { "name": "boundaries", @@ -22241,7 +22303,7 @@ "meta-type": "object" }, { - "name": "381", + "name": "383", "members": [ { "name": "discard-nb-ok", @@ -22259,37 +22321,37 @@ "meta-type": "object" }, { - "name": "[69]", - "element-type": "69", + "name": "[70]", + "element-type": "70", "meta-type": "array" }, { - "name": "382", + "name": "384", "tag": "type", "variants": [ { "case": "qcow2", - "type": "478" + "type": "481" }, { "case": "vmdk", - "type": "479" + "type": "482" }, { "case": "luks", - "type": "480" + "type": "483" } ], "members": [ { "name": "type", - "type": "477" + "type": "480" } ], "meta-type": "object" }, { - "name": "383", + "name": "385", "meta-type": "enum", "values": [ "block-backend", @@ -22298,12 +22360,12 @@ ] }, { - "name": "[384]", - "element-type": "384", + "name": "[386]", + "element-type": "386", "meta-type": "array" }, { - "name": "384", + "name": "386", "meta-type": "enum", "values": [ "consistent-read", @@ -22314,10 +22376,10 @@ ] }, { - "name": "385", + "name": "387", "members": [ { - "type": "48" + "type": "49" }, { "type": "str" @@ -22326,16 +22388,16 @@ "meta-type": "alternate" }, { - "name": "[386]", - "element-type": "386", + "name": "[388]", + "element-type": "388", "meta-type": "array" }, { - "name": "386", + "name": "388", "members": [ { "name": "event", - "type": "481" + "type": "484" }, { "name": "state", @@ -22345,7 +22407,7 @@ { "name": "iotype", "default": null, - "type": "482" + "type": "485" }, { "name": "errno", @@ -22371,16 +22433,16 @@ "meta-type": "object" }, { - "name": "[387]", - "element-type": "387", + "name": "[389]", + "element-type": "389", "meta-type": "array" }, { - "name": "387", + "name": "389", "members": [ { "name": "event", - "type": "481" + "type": "484" }, { "name": "state", @@ -22395,7 +22457,7 @@ "meta-type": "object" }, { - "name": "388", + "name": "390", "meta-type": "enum", "values": [ "auto", @@ -22404,7 +22466,7 @@ ] }, { - "name": "389", + "name": "391", "meta-type": "enum", "values": [ "threads", @@ -22413,7 +22475,7 @@ ] }, { - "name": "390", + "name": "392", "meta-type": "enum", "values": [ "tcp", @@ -22421,7 +22483,7 @@ ] }, { - "name": "391", + "name": "393", "meta-type": "enum", "values": [ "crc32c", @@ -22431,11 +22493,11 @@ ] }, { - "name": "392", + "name": "394", "members": [ { "name": "type", - "type": "483" + "type": "486" }, { "name": "host", @@ -22445,10 +22507,10 @@ "meta-type": "object" }, { - "name": "393", + "name": "395", "members": [ { - "type": "48" + "type": "49" }, { "type": "str" @@ -22460,62 +22522,62 @@ "meta-type": "alternate" }, { - "name": "394", + "name": "396", "members": [ { - "type": "484" + "type": "487" }, { - "type": "485" + "type": "488" } ], "meta-type": "alternate" }, { - "name": "395", + "name": "397", "tag": "format", "variants": [ { "case": "aes", - "type": "487" + "type": "490" }, { "case": "luks", - "type": "488" + "type": "491" } ], "members": [ { "name": "format", - "type": "486" + "type": "489" } ], "meta-type": "object" }, { - "name": "396", + "name": "398", "tag": "format", "variants": [ { "case": "aes", - "type": "487" + "type": "490" } ], "members": [ { "name": "format", - "type": "489" + "type": "492" } ], "meta-type": "object" }, { - "name": "[385]", - "element-type": "385", + "name": "[387]", + "element-type": "387", "meta-type": "array" }, { - "name": "397", + "name": "399", "meta-type": "enum", "values": [ "quorum", @@ -22523,12 +22585,12 @@ ] }, { - "name": "[398]", - "element-type": "398", + "name": "[400]", + "element-type": "400", "meta-type": "array" }, { - "name": "398", + "name": "400", "meta-type": "enum", "values": [ "cephx", @@ -22536,12 +22598,12 @@ ] }, { - "name": "[399]", - "element-type": "399", + "name": "[401]", + "element-type": "401", "meta-type": "array" }, { - "name": "399", + "name": "401", "members": [ { "name": "host", @@ -22555,7 +22617,7 @@ "meta-type": "object" }, { - "name": "400", + "name": "402", "meta-type": "enum", "values": [ "primary", @@ -22563,7 +22625,7 @@ ] }, { - "name": "401", + "name": "403", "members": [ { "name": "host", @@ -22602,12 +22664,12 @@ "meta-type": "object" }, { - "name": "402", + "name": "404", "tag": "mode", "variants": [ { "case": "hash", - "type": "491" + "type": "494" }, { "case": "none", @@ -22621,13 +22683,13 @@ "members": [ { "name": "mode", - "type": "490" + "type": "493" } ], "meta-type": "object" }, { - "name": "403", + "name": "405", "members": [ { "name": "filename", @@ -22640,7 +22702,7 @@ { "name": "preallocation", "default": null, - "type": "492" + "type": "495" }, { "name": "nocow", @@ -22651,11 +22713,11 @@ "meta-type": "object" }, { - "name": "404", + "name": "406", "members": [ { "name": "location", - "type": "256" + "type": "258" }, { "name": "size", @@ -22664,13 +22726,13 @@ { "name": "preallocation", "default": null, - "type": "492" + "type": "495" } ], "meta-type": "object" }, { - "name": "405", + "name": "407", "members": [ { "name": "key-secret", @@ -22680,27 +22742,27 @@ { "name": "cipher-alg", "default": null, - "type": "493" + "type": "496" }, { "name": "cipher-mode", "default": null, - "type": "494" + "type": "497" }, { "name": "ivgen-alg", "default": null, - "type": "495" + "type": "498" }, { "name": "ivgen-hash-alg", "default": null, - "type": "496" + "type": "499" }, { "name": "hash-alg", "default": null, - "type": "496" + "type": "499" }, { "name": "iter-time", @@ -22709,7 +22771,7 @@ }, { "name": "file", - "type": "385" + "type": "387" }, { "name": "size", @@ -22718,17 +22780,17 @@ { "name": "preallocation", "default": null, - "type": "492" + "type": "495" } ], "meta-type": "object" }, { - "name": "406", + "name": "408", "members": [ { "name": "location", - "type": "262" + "type": "264" }, { "name": "size", @@ -22738,11 +22800,11 @@ "meta-type": "object" }, { - "name": "407", + "name": "409", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "size", @@ -22757,11 +22819,11 @@ "meta-type": "object" }, { - "name": "408", + "name": "410", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "size", @@ -22775,22 +22837,22 @@ { "name": "encrypt", "default": null, - "type": "497" + "type": "500" } ], "meta-type": "object" }, { - "name": "409", + "name": "411", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "data-file", "default": null, - "type": "385" + "type": "387" }, { "name": "data-file-raw", @@ -22804,7 +22866,7 @@ { "name": "version", "default": null, - "type": "498" + "type": "501" }, { "name": "backing-file", @@ -22814,12 +22876,12 @@ { "name": "backing-fmt", "default": null, - "type": "245" + "type": "247" }, { "name": "encrypt", "default": null, - "type": "497" + "type": "500" }, { "name": "cluster-size", @@ -22829,7 +22891,7 @@ { "name": "preallocation", "default": null, - "type": "492" + "type": "495" }, { "name": "lazy-refcounts", @@ -22844,17 +22906,17 @@ { "name": "compression-type", "default": null, - "type": "499" + "type": "502" } ], "meta-type": "object" }, { - "name": "410", + "name": "412", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "size", @@ -22868,7 +22930,7 @@ { "name": "backing-fmt", "default": null, - "type": "245" + "type": "247" }, { "name": "cluster-size", @@ -22884,11 +22946,11 @@ "meta-type": "object" }, { - "name": "411", + "name": "413", "members": [ { "name": "location", - "type": "270" + "type": "272" }, { "name": "size", @@ -22903,11 +22965,11 @@ "meta-type": "object" }, { - "name": "412", + "name": "414", "members": [ { "name": "location", - "type": "272" + "type": "274" }, { "name": "size", @@ -22921,12 +22983,12 @@ { "name": "preallocation", "default": null, - "type": "492" + "type": "495" }, { "name": "redundancy", "default": null, - "type": "500" + "type": "503" }, { "name": "object-size", @@ -22937,11 +22999,11 @@ "meta-type": "object" }, { - "name": "413", + "name": "415", "members": [ { "name": "location", - "type": "273" + "type": "275" }, { "name": "size", @@ -22951,11 +23013,11 @@ "meta-type": "object" }, { - "name": "414", + "name": "416", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "size", @@ -22964,17 +23026,17 @@ { "name": "preallocation", "default": null, - "type": "492" + "type": "495" } ], "meta-type": "object" }, { - "name": "415", + "name": "417", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "size", @@ -22993,7 +23055,7 @@ { "name": "subformat", "default": null, - "type": "501" + "type": "504" }, { "name": "block-state-zero", @@ -23004,11 +23066,11 @@ "meta-type": "object" }, { - "name": "416", + "name": "418", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "size", @@ -23017,12 +23079,12 @@ { "name": "extents", "default": null, - "type": "[385]" + "type": "[387]" }, { "name": "subformat", "default": null, - "type": "502" + "type": "505" }, { "name": "backing-file", @@ -23032,7 +23094,7 @@ { "name": "adapter-type", "default": null, - "type": "503" + "type": "506" }, { "name": "hwversion", @@ -23048,11 +23110,11 @@ "meta-type": "object" }, { - "name": "417", + "name": "419", "members": [ { "name": "file", - "type": "385" + "type": "387" }, { "name": "size", @@ -23061,7 +23123,7 @@ { "name": "subformat", "default": null, - "type": "504" + "type": "507" }, { "name": "force-size", @@ -23077,7 +23139,7 @@ "meta-type": "builtin" }, { - "name": "418", + "name": "420", "meta-type": "enum", "values": [ "inet", @@ -23087,47 +23149,47 @@ ] }, { - "name": "419", + "name": "421", "members": [ { "name": "data", - "type": "401" + "type": "403" } ], "meta-type": "object" }, { - "name": "420", + "name": "422", "members": [ { "name": "data", - "type": "447" + "type": "449" } ], "meta-type": "object" }, { - "name": "421", + "name": "423", "members": [ { "name": "data", - "type": "448" + "type": "450" } ], "meta-type": "object" }, { - "name": "422", + "name": "424", "members": [ { "name": "data", - "type": "435" + "type": "437" } ], "meta-type": "object" }, { - "name": "423", + "name": "425", "meta-type": "enum", "values": [ "file", @@ -23153,122 +23215,122 @@ ] }, { - "name": "424", + "name": "426", "members": [ { "name": "data", - "type": "505" + "type": "508" } ], "meta-type": "object" }, { - "name": "425", + "name": "427", "members": [ { "name": "data", - "type": "506" + "type": "509" } ], "meta-type": "object" }, { - "name": "426", + "name": "428", "members": [ { "name": "data", - "type": "507" + "type": "510" } ], "meta-type": "object" }, { - "name": "427", + "name": "429", "members": [ { "name": "data", - "type": "508" + "type": "511" } ], "meta-type": "object" }, { - "name": "428", + "name": "430", "members": [ { "name": "data", - "type": "509" + "type": "512" } ], "meta-type": "object" }, { - "name": "429", + "name": "431", "members": [ { "name": "data", - "type": "510" + "type": "513" } ], "meta-type": "object" }, { - "name": "430", + "name": "432", "members": [ { "name": "data", - "type": "511" + "type": "514" } ], "meta-type": "object" }, { - "name": "431", + "name": "433", "members": [ { "name": "data", - "type": "512" + "type": "515" } ], "meta-type": "object" }, { - "name": "432", + "name": "434", "members": [ { "name": "data", - "type": "513" + "type": "516" } ], "meta-type": "object" }, { - "name": "433", + "name": "435", "members": [ { "name": "data", - "type": "514" + "type": "517" } ], "meta-type": "object" }, { - "name": "434", + "name": "436", "members": [ { "name": "data", - "type": "515" + "type": "518" } ], "meta-type": "object" }, { - "name": "[435]", - "element-type": "435", + "name": "[437]", + "element-type": "437", "meta-type": "array" }, { - "name": "435", + "name": "437", "members": [ { "name": "str", @@ -23278,7 +23340,7 @@ "meta-type": "object" }, { - "name": "436", + "name": "438", "meta-type": "enum", "values": [ "passthrough", @@ -23286,27 +23348,27 @@ ] }, { - "name": "437", + "name": "439", "members": [ { "name": "data", - "type": "516" + "type": "519" } ], "meta-type": "object" }, { - "name": "438", + "name": "440", "members": [ { "name": "data", - "type": "517" + "type": "520" } ], "meta-type": "object" }, { - "name": "439", + "name": "441", "meta-type": "enum", "values": [ "number", @@ -23314,7 +23376,7 @@ ] }, { - "name": "440", + "name": "442", "members": [ { "name": "data", @@ -23324,17 +23386,17 @@ "meta-type": "object" }, { - "name": "441", + "name": "443", "members": [ { "name": "data", - "type": "518" + "type": "521" } ], "meta-type": "object" }, { - "name": "442", + "name": "444", "meta-type": "enum", "values": [ "key", @@ -23344,37 +23406,37 @@ ] }, { - "name": "443", + "name": "445", "members": [ { "name": "data", - "type": "519" + "type": "522" } ], "meta-type": "object" }, { - "name": "444", + "name": "446", "members": [ { "name": "data", - "type": "520" + "type": "523" } ], "meta-type": "object" }, { - "name": "445", + "name": "447", "members": [ { "name": "data", - "type": "521" + "type": "524" } ], "meta-type": "object" }, { - "name": "446", + "name": "448", "meta-type": "enum", "values": [ "inet", @@ -23384,7 +23446,7 @@ ] }, { - "name": "447", + "name": "449", "members": [ { "name": "path", @@ -23404,7 +23466,7 @@ "meta-type": "object" }, { - "name": "448", + "name": "450", "members": [ { "name": "cid", @@ -23418,7 +23480,7 @@ "meta-type": "object" }, { - "name": "449", + "name": "451", "meta-type": "enum", "values": [ "abort", @@ -23428,6 +23490,7 @@ "block-dirty-bitmap-enable", "block-dirty-bitmap-disable", "block-dirty-bitmap-merge", + "block-dirty-bitmap-populate", "blockdev-backup", "blockdev-snapshot", "blockdev-snapshot-internal-sync", @@ -23436,17 +23499,17 @@ ] }, { - "name": "450", + "name": "452", "members": [ { "name": "data", - "type": "522" + "type": "525" } ], "meta-type": "object" }, { - "name": "451", + "name": "453", "members": [ { "name": "data", @@ -23456,7 +23519,7 @@ "meta-type": "object" }, { - "name": "452", + "name": "454", "members": [ { "name": "data", @@ -23466,7 +23529,7 @@ "meta-type": "object" }, { - "name": "453", + "name": "455", "members": [ { "name": "data", @@ -23476,7 +23539,17 @@ "meta-type": "object" }, { - "name": "454", + "name": "456", + "members": [ + { + "name": "data", + "type": "38" + } + ], + "meta-type": "object" + }, + { + "name": "457", "members": [ { "name": "data", @@ -23486,7 +23559,7 @@ "meta-type": "object" }, { - "name": "455", + "name": "458", "members": [ { "name": "data", @@ -23496,17 +23569,17 @@ "meta-type": "object" }, { - "name": "456", + "name": "459", "members": [ { "name": "data", - "type": "67" + "type": "68" } ], "meta-type": "object" }, { - "name": "457", + "name": "460", "members": [ { "name": "data", @@ -23516,7 +23589,7 @@ "meta-type": "object" }, { - "name": "458", + "name": "461", "members": [ { "name": "data", @@ -23526,7 +23599,7 @@ "meta-type": "object" }, { - "name": "459", + "name": "462", "meta-type": "enum", "values": [ "individual", @@ -23534,7 +23607,7 @@ ] }, { - "name": "460", + "name": "463", "meta-type": "enum", "values": [ "string", @@ -23548,12 +23621,12 @@ ] }, { - "name": "[461]", - "element-type": "461", + "name": "[464]", + "element-type": "464", "meta-type": "array" }, { - "name": "461", + "name": "464", "members": [ { "name": "name", @@ -23577,12 +23650,12 @@ "meta-type": "object" }, { - "name": "[462]", - "element-type": "462", + "name": "[465]", + "element-type": "465", "meta-type": "array" }, { - "name": "462", + "name": "465", "members": [ { "name": "case", @@ -23596,12 +23669,12 @@ "meta-type": "object" }, { - "name": "[463]", - "element-type": "463", + "name": "[466]", + "element-type": "466", "meta-type": "array" }, { - "name": "463", + "name": "466", "members": [ { "name": "type", @@ -23611,7 +23684,7 @@ "meta-type": "object" }, { - "name": "464", + "name": "467", "meta-type": "enum", "values": [ "uninitialized", @@ -23622,7 +23695,7 @@ ] }, { - "name": "465", + "name": "468", "meta-type": "enum", "values": [ "memory", @@ -23632,7 +23705,7 @@ ] }, { - "name": "466", + "name": "469", "meta-type": "enum", "values": [ "access-latency", @@ -23644,7 +23717,7 @@ ] }, { - "name": "467", + "name": "470", "meta-type": "enum", "values": [ "none", @@ -23653,7 +23726,7 @@ ] }, { - "name": "468", + "name": "471", "meta-type": "enum", "values": [ "none", @@ -23662,7 +23735,7 @@ ] }, { - "name": "469", + "name": "472", "members": [ { "name": "desc", @@ -23677,7 +23750,7 @@ "meta-type": "object" }, { - "name": "470", + "name": "473", "members": [ { "name": "device", @@ -23701,27 +23774,27 @@ "meta-type": "object" }, { - "name": "471", + "name": "474", "members": [ { "name": "bus", - "type": "523" + "type": "526" }, { "name": "devices", "default": null, - "type": "[367]" + "type": "[369]" } ], "meta-type": "object" }, { - "name": "[472]", - "element-type": "472", + "name": "[475]", + "element-type": "475", "meta-type": "array" }, { - "name": "472", + "name": "475", "members": [ { "name": "bar", @@ -23753,7 +23826,7 @@ "meta-type": "object" }, { - "name": "473", + "name": "476", "meta-type": "enum", "values": [ "string", @@ -23763,7 +23836,7 @@ ] }, { - "name": "474", + "name": "477", "members": [ { "name": "id", @@ -23802,7 +23875,7 @@ "meta-type": "object" }, { - "name": "475", + "name": "478", "members": [ { "name": "id", @@ -23825,7 +23898,7 @@ "meta-type": "object" }, { - "name": "476", + "name": "479", "meta-type": "enum", "values": [ "unknown", @@ -23836,7 +23909,7 @@ ] }, { - "name": "477", + "name": "480", "meta-type": "enum", "values": [ "qcow2", @@ -23845,37 +23918,37 @@ ] }, { - "name": "478", + "name": "481", "members": [ { "name": "data", - "type": "524" + "type": "527" } ], "meta-type": "object" }, { - "name": "479", + "name": "482", "members": [ { "name": "data", - "type": "525" + "type": "528" } ], "meta-type": "object" }, { - "name": "480", + "name": "483", "members": [ { "name": "data", - "type": "526" + "type": "529" } ], "meta-type": "object" }, { - "name": "481", + "name": "484", "meta-type": "enum", "values": [ "l1_update", @@ -23929,7 +24002,7 @@ ] }, { - "name": "482", + "name": "485", "meta-type": "enum", "values": [ "read", @@ -23941,19 +24014,19 @@ ] }, { - "name": "483", + "name": "486", "meta-type": "enum", "values": [ "inet" ] }, { - "name": "484", + "name": "487", "members": [ { "name": "template", "default": null, - "type": "485" + "type": "488" }, { "name": "main-header", @@ -24004,7 +24077,7 @@ "meta-type": "object" }, { - "name": "485", + "name": "488", "meta-type": "enum", "values": [ "none", @@ -24014,7 +24087,7 @@ ] }, { - "name": "486", + "name": "489", "meta-type": "enum", "values": [ "aes", @@ -24022,7 +24095,7 @@ ] }, { - "name": "487", + "name": "490", "members": [ { "name": "key-secret", @@ -24033,7 +24106,7 @@ "meta-type": "object" }, { - "name": "488", + "name": "491", "members": [ { "name": "key-secret", @@ -24044,14 +24117,14 @@ "meta-type": "object" }, { - "name": "489", + "name": "492", "meta-type": "enum", "values": [ "aes" ] }, { - "name": "490", + "name": "493", "meta-type": "enum", "values": [ "none", @@ -24060,11 +24133,11 @@ ] }, { - "name": "491", + "name": "494", "members": [ { "name": "type", - "type": "527" + "type": "530" }, { "name": "hash", @@ -24074,7 +24147,7 @@ "meta-type": "object" }, { - "name": "492", + "name": "495", "meta-type": "enum", "values": [ "off", @@ -24084,7 +24157,7 @@ ] }, { - "name": "493", + "name": "496", "meta-type": "enum", "values": [ "aes-128", @@ -24102,7 +24175,7 @@ ] }, { - "name": "494", + "name": "497", "meta-type": "enum", "values": [ "ecb", @@ -24112,7 +24185,7 @@ ] }, { - "name": "495", + "name": "498", "meta-type": "enum", "values": [ "plain", @@ -24121,7 +24194,7 @@ ] }, { - "name": "496", + "name": "499", "meta-type": "enum", "values": [ "md5", @@ -24134,28 +24207,28 @@ ] }, { - "name": "497", + "name": "500", "tag": "format", "variants": [ { "case": "qcow", - "type": "487" + "type": "490" }, { "case": "luks", - "type": "529" + "type": "532" } ], "members": [ { "name": "format", - "type": "528" + "type": "531" } ], "meta-type": "object" }, { - "name": "498", + "name": "501", "meta-type": "enum", "values": [ "v2", @@ -24163,35 +24236,35 @@ ] }, { - "name": "499", + "name": "502", "meta-type": "enum", "values": [ "zlib" ] }, { - "name": "500", + "name": "503", "tag": "type", "variants": [ { "case": "full", - "type": "531" + "type": "534" }, { "case": "erasure-coded", - "type": "532" + "type": "535" } ], "members": [ { "name": "type", - "type": "530" + "type": "533" } ], "meta-type": "object" }, { - "name": "501", + "name": "504", "meta-type": "enum", "values": [ "dynamic", @@ -24199,7 +24272,7 @@ ] }, { - "name": "502", + "name": "505", "meta-type": "enum", "values": [ "monolithicSparse", @@ -24210,7 +24283,7 @@ ] }, { - "name": "503", + "name": "506", "meta-type": "enum", "values": [ "ide", @@ -24220,7 +24293,7 @@ ] }, { - "name": "504", + "name": "507", "meta-type": "enum", "values": [ "dynamic", @@ -24228,7 +24301,7 @@ ] }, { - "name": "505", + "name": "508", "members": [ { "name": "logfile", @@ -24258,7 +24331,7 @@ "meta-type": "object" }, { - "name": "506", + "name": "509", "members": [ { "name": "logfile", @@ -24278,7 +24351,7 @@ "meta-type": "object" }, { - "name": "507", + "name": "510", "members": [ { "name": "logfile", @@ -24292,7 +24365,7 @@ }, { "name": "addr", - "type": "282" + "type": "284" }, { "name": "tls-creds", @@ -24343,7 +24416,7 @@ "meta-type": "object" }, { - "name": "508", + "name": "511", "members": [ { "name": "logfile", @@ -24357,18 +24430,18 @@ }, { "name": "remote", - "type": "282" + "type": "284" }, { "name": "local", "default": null, - "type": "282" + "type": "284" } ], "meta-type": "object" }, { - "name": "509", + "name": "512", "members": [ { "name": "logfile", @@ -24384,7 +24457,7 @@ "meta-type": "object" }, { - "name": "510", + "name": "513", "members": [ { "name": "logfile", @@ -24404,7 +24477,7 @@ "meta-type": "object" }, { - "name": "511", + "name": "514", "members": [ { "name": "logfile", @@ -24425,7 +24498,7 @@ "meta-type": "object" }, { - "name": "512", + "name": "515", "members": [ { "name": "logfile", @@ -24445,7 +24518,7 @@ "meta-type": "object" }, { - "name": "513", + "name": "516", "members": [ { "name": "logfile", @@ -24465,7 +24538,7 @@ "meta-type": "object" }, { - "name": "514", + "name": "517", "members": [ { "name": "logfile", @@ -24501,7 +24574,7 @@ "meta-type": "object" }, { - "name": "515", + "name": "518", "members": [ { "name": "logfile", @@ -24522,7 +24595,7 @@ "meta-type": "object" }, { - "name": "516", + "name": "519", "members": [ { "name": "path", @@ -24538,7 +24611,7 @@ "meta-type": "object" }, { - "name": "517", + "name": "520", "members": [ { "name": "chardev", @@ -24548,7 +24621,7 @@ "meta-type": "object" }, { - "name": "518", + "name": "521", "meta-type": "enum", "values": [ "unmapped", @@ -24702,11 +24775,11 @@ ] }, { - "name": "519", + "name": "522", "members": [ { "name": "key", - "type": "318" + "type": "320" }, { "name": "down", @@ -24716,11 +24789,11 @@ "meta-type": "object" }, { - "name": "520", + "name": "523", "members": [ { "name": "button", - "type": "533" + "type": "536" }, { "name": "down", @@ -24730,11 +24803,11 @@ "meta-type": "object" }, { - "name": "521", + "name": "524", "members": [ { "name": "axis", - "type": "534" + "type": "537" }, { "name": "value", @@ -24744,13 +24817,13 @@ "meta-type": "object" }, { - "name": "522", + "name": "525", "members": [ ], "meta-type": "object" }, { - "name": "523", + "name": "526", "members": [ { "name": "number", @@ -24766,21 +24839,21 @@ }, { "name": "io_range", - "type": "535" + "type": "538" }, { "name": "memory_range", - "type": "535" + "type": "538" }, { "name": "prefetchable_range", - "type": "535" + "type": "538" } ], "meta-type": "object" }, { - "name": "524", + "name": "527", "members": [ { "name": "compat", @@ -24813,22 +24886,22 @@ { "name": "encrypt", "default": null, - "type": "536" + "type": "539" }, { "name": "bitmaps", "default": null, - "type": "[537]" + "type": "[540]" }, { "name": "compression-type", - "type": "499" + "type": "502" } ], "meta-type": "object" }, { - "name": "525", + "name": "528", "members": [ { "name": "create-type", @@ -24844,34 +24917,34 @@ }, { "name": "extents", - "type": "[239]" + "type": "[240]" } ], "meta-type": "object" }, { - "name": "526", + "name": "529", "members": [ { "name": "cipher-alg", - "type": "493" + "type": "496" }, { "name": "cipher-mode", - "type": "494" + "type": "497" }, { "name": "ivgen-alg", - "type": "495" + "type": "498" }, { "name": "ivgen-hash-alg", "default": null, - "type": "496" + "type": "499" }, { "name": "hash-alg", - "type": "496" + "type": "499" }, { "name": "payload-offset", @@ -24887,13 +24960,13 @@ }, { "name": "slots", - "type": "[538]" + "type": "[541]" } ], "meta-type": "object" }, { - "name": "527", + "name": "530", "meta-type": "enum", "values": [ "md5", @@ -24901,7 +24974,7 @@ ] }, { - "name": "528", + "name": "531", "meta-type": "enum", "values": [ "qcow", @@ -24909,7 +24982,7 @@ ] }, { - "name": "529", + "name": "532", "members": [ { "name": "key-secret", @@ -24919,27 +24992,27 @@ { "name": "cipher-alg", "default": null, - "type": "493" + "type": "496" }, { "name": "cipher-mode", "default": null, - "type": "494" + "type": "497" }, { "name": "ivgen-alg", "default": null, - "type": "495" + "type": "498" }, { "name": "ivgen-hash-alg", "default": null, - "type": "496" + "type": "499" }, { "name": "hash-alg", "default": null, - "type": "496" + "type": "499" }, { "name": "iter-time", @@ -24950,7 +25023,7 @@ "meta-type": "object" }, { - "name": "530", + "name": "533", "meta-type": "enum", "values": [ "full", @@ -24958,7 +25031,7 @@ ] }, { - "name": "531", + "name": "534", "members": [ { "name": "copies", @@ -24968,7 +25041,7 @@ "meta-type": "object" }, { - "name": "532", + "name": "535", "members": [ { "name": "data-strips", @@ -24982,7 +25055,7 @@ "meta-type": "object" }, { - "name": "533", + "name": "536", "meta-type": "enum", "values": [ "left", @@ -24995,7 +25068,7 @@ ] }, { - "name": "534", + "name": "537", "meta-type": "enum", "values": [ "x", @@ -25003,7 +25076,7 @@ ] }, { - "name": "535", + "name": "538", "members": [ { "name": "base", @@ -25017,12 +25090,12 @@ "meta-type": "object" }, { - "name": "536", + "name": "539", "tag": "format", "variants": [ { "case": "luks", - "type": "526" + "type": "529" }, { "case": "aes", @@ -25032,18 +25105,18 @@ "members": [ { "name": "format", - "type": "486" + "type": "489" } ], "meta-type": "object" }, { - "name": "[537]", - "element-type": "537", + "name": "[540]", + "element-type": "540", "meta-type": "array" }, { - "name": "537", + "name": "540", "members": [ { "name": "name", @@ -25055,23 +25128,23 @@ }, { "name": "flags", - "type": "[539]" + "type": "[542]" } ], "meta-type": "object" }, { - "name": "[239]", - "element-type": "239", + "name": "[240]", + "element-type": "240", "meta-type": "array" }, { - "name": "[538]", - "element-type": "538", + "name": "[541]", + "element-type": "541", "meta-type": "array" }, { - "name": "538", + "name": "541", "members": [ { "name": "active", @@ -25095,12 +25168,12 @@ "meta-type": "object" }, { - "name": "[539]", - "element-type": "539", + "name": "[542]", + "element-type": "542", "meta-type": "array" }, { - "name": "539", + "name": "542", "meta-type": "enum", "values": [ "in-use", diff --git a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml index 3f538628b3..618f04bf5c 100644 --- a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml @@ -237,7 +237,7 @@ <version>5000050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100242</microcodeVersion> - <package>v5.0.0-870-g5cc7a54c2e</package> + <package>v5.0.0-966-gdcfd91ce51</package> <arch>x86_64</arch> <hostCPU type='kvm' model='base' migratability='yes'> <property name='vmx-entry-load-rtit-ctl' type='boolean' value='false'/> -- 2.26.2

On 6/9/20 10:00 AM, Peter Krempa wrote:
Note that this is not the final version and will be updated once qemu pushes the patches. --- .../caps_5.1.0.x86_64.replies | 2737 +++++++++-------- .../caps_5.1.0.x86_64.xml | 2 +- 2 files changed, 1406 insertions(+), 1333 deletions(-)
Latest version of the qemu patches (including a question of whether qemu should start with an x- prefix) at: https://lists.gnu.org/archive/html/qemu-devel/2020-06/msg06258.html For testing purposes, you can also get it at: https://repo.or.cz/qemu/ericb.git/shortlog/refs/tags/bitmap-pop-v3 -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org

Add monitor code for driving the block-dirty-bitmap-populate blockjob. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 11 +++++++++++ src/qemu/qemu_monitor.h | 7 +++++++ src/qemu/qemu_monitor_json.c | 18 ++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++++++ tests/qemumonitorjsontest.c | 3 ++- 5 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 3ec22b939f..623730154d 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -4617,3 +4617,14 @@ qemuMonitorTransactionBackup(virJSONValuePtr actions, return qemuMonitorJSONTransactionBackup(actions, device, jobname, target, bitmap, syncmode); } + + +int +qemuMonitorTransactionBitmapPopulate(virJSONValuePtr actions, + const char *nodename, + const char *bitmapname, + const char *jobname) +{ + return qemuMonitorJSONTransactionBitmapPopulate(actions, nodename, + bitmapname, jobname); +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 50a337715d..ccc946108a 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1431,3 +1431,10 @@ qemuMonitorTransactionBackup(virJSONValuePtr actions, const char *target, const char *bitmap, qemuMonitorTransactionBackupSyncMode syncmode); + + +int +qemuMonitorTransactionBitmapPopulate(virJSONValuePtr actions, + const char *nodename, + const char *bitmapname, + const char *jobname); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 3070c1e6b3..2ed3358252 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -9261,6 +9261,24 @@ qemuMonitorJSONTransactionBitmapMergeSourceAddBitmap(virJSONValuePtr sources, } +int +qemuMonitorJSONTransactionBitmapPopulate(virJSONValuePtr actions, + const char *nodename, + const char *bitmapname, + const char *jobname) +{ + return qemuMonitorJSONTransactionAdd(actions, + "block-dirty-bitmap-populate", + "s:node", nodename, + "s:name", bitmapname, + "s:job-id", jobname, + "s:pattern", "allocation-top", + "T:auto-finalize", VIR_TRISTATE_BOOL_YES, + "T:auto-dismiss", VIR_TRISTATE_BOOL_NO, + NULL); +} + + int qemuMonitorJSONTransactionSnapshotLegacy(virJSONValuePtr actions, const char *device, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 83c5e25ca5..7ae4857672 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -667,6 +667,12 @@ qemuMonitorJSONTransactionBitmapMergeSourceAddBitmap(virJSONValuePtr sources, const char *sourcenode, const char *sourcebitmap); +int +qemuMonitorJSONTransactionBitmapPopulate(virJSONValuePtr actions, + const char *nodename, + const char *bitmapname, + const char *jobname); + int qemuMonitorJSONTransactionSnapshotLegacy(virJSONValuePtr actions, const char *device, diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 6d5a1d5fe2..befd41fd25 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -2992,7 +2992,8 @@ testQemuMonitorJSONTransaction(const void *opaque) qemuMonitorTransactionBackup(actions, "dev9", "job9", "target9", "bitmap9", QEMU_MONITOR_TRANSACTION_BACKUP_SYNC_MODE_INCREMENTAL) < 0 || qemuMonitorTransactionBackup(actions, "devA", "jobA", "targetA", "bitmapA", - QEMU_MONITOR_TRANSACTION_BACKUP_SYNC_MODE_FULL) < 0) + QEMU_MONITOR_TRANSACTION_BACKUP_SYNC_MODE_FULL) < 0 || + qemuMonitorJSONTransactionBitmapPopulate(actions, "nodeB", "bitmapB", "jobB") < 0) return -1; if (qemuMonitorTestAddItem(test, "transaction", "{\"return\":{}}") < 0) -- 2.26.2

We'll need to track multiple blockjobs for populating bitmaps per storage source for internal use. Add a variable into the storage source private data for this purpose. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3239ac1a52..0cd9cf8582 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1230,6 +1230,7 @@ qemuDomainStorageSourcePrivateDispose(void *obj) g_clear_pointer(&priv->secinfo, qemuDomainSecretInfoFree); g_clear_pointer(&priv->encinfo, qemuDomainSecretInfoFree); g_clear_pointer(&priv->httpcookie, qemuDomainSecretInfoFree); + virObjectUnref(priv->blockjob); } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 41d3f1561d..821832c986 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -483,6 +483,10 @@ struct _qemuDomainStorageSourcePrivate { /* secure passthrough of the http cookie */ qemuDomainSecretInfoPtr httpcookie; + + /* Optional per-source internal blockjob. Regular blockjobs are sill tracked + * at 'disk' level */ + qemuBlockJobDataPtr blockjob; }; virObjectPtr qemuDomainStorageSourcePrivateNew(void); -- 2.26.2

On 6/9/20 10:00 AM, Peter Krempa wrote:
We'll need to track multiple blockjobs for populating bitmaps per storage source for internal use. Add a variable into the storage source private data for this purpose.
Hmm. If the domain has two disks as well as two active bitmaps per disk, does that really mean we are tracking four independent blockjobs when merging in allocation data into all four bitmaps?
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 4 ++++ 2 files changed, 5 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3239ac1a52..0cd9cf8582 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1230,6 +1230,7 @@ qemuDomainStorageSourcePrivateDispose(void *obj) g_clear_pointer(&priv->secinfo, qemuDomainSecretInfoFree); g_clear_pointer(&priv->encinfo, qemuDomainSecretInfoFree); g_clear_pointer(&priv->httpcookie, qemuDomainSecretInfoFree); + virObjectUnref(priv->blockjob); }
Or are you planning on only using one blockjob per disk, and then when it is complete, merging that bitmap into multiple other bitmaps? Should the blockjob-populate command allow multiple destination bitmaps grouped into one job? Or is that just trading reduced libvirt complexity for too much QMP complexity? -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org

On Fri, Jun 19, 2020 at 15:08:14 -0500, Eric Blake wrote:
On 6/9/20 10:00 AM, Peter Krempa wrote:
We'll need to track multiple blockjobs for populating bitmaps per storage source for internal use. Add a variable into the storage source private data for this purpose.
Hmm. If the domain has two disks as well as two active bitmaps per disk, does that really mean we are tracking four independent blockjobs when merging in allocation data into all four bitmaps?
No. The idea is to have 1 blockjob per 'format' node. If you are doing a backup of 2 disks which both have 3 images, you'd as a worst case scenario get 4 blockjobs. (the bottom-most images already contain the partial bitmap so they don't need a bitmap populated from allocation data.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 4 ++++ 2 files changed, 5 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3239ac1a52..0cd9cf8582 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1230,6 +1230,7 @@ qemuDomainStorageSourcePrivateDispose(void *obj) g_clear_pointer(&priv->secinfo, qemuDomainSecretInfoFree); g_clear_pointer(&priv->encinfo, qemuDomainSecretInfoFree); g_clear_pointer(&priv->httpcookie, qemuDomainSecretInfoFree); + virObjectUnref(priv->blockjob); }
Or are you planning on only using one blockjob per disk, and then when it is complete, merging that bitmap into multiple other bitmaps?
No. One bitmap per backing chain layer where it's necessary. The above struct is virStorageSource. Rest of the blockjobs is tracked per-disk though.
Should the blockjob-populate command allow multiple destination bitmaps grouped into one job? Or is that just trading reduced libvirt complexity for too much QMP complexity?
That doesn't matter that much, at least not from the point of view of the blockjob. It does matter later where we merge this bitmap into multiple destinations. Whether it's worth I'm not sure as we need to be doing the merge anyways, so it's not that much different if we add one more or one less bitmap.

This is a helper blockjob which uses the 'block-dirty-bitmap-populate' command to convert the allocation map of a qcow2 image into a dirty bitmap. Internally it's a blockjob so we need to treat it as such. We only care about the results when there's a sync thread waiting for it, otherwise we clean up the created bitmap. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_blockjob.c | 69 ++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_blockjob.h | 13 ++++++++ src/qemu/qemu_domain.c | 13 ++++++++ src/qemu/qemu_driver.c | 1 + 4 files changed, 96 insertions(+) diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 17dc08476b..79820c6ca8 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -69,6 +69,7 @@ VIR_ENUM_IMPL(qemuBlockjob, "backup", "", "create", + "populate", "broken"); static virClassPtr qemuBlockJobDataClass; @@ -356,6 +357,38 @@ qemuBlockJobNewCreate(virDomainObjPtr vm, } +/** + * qemuBlockJobNewPopulate: + * @vm: domain object + * @src: storage source the populate job is running on + * + * Instantiate block job data for running a 'dirty-bitmap-populate' blockjob. + * Note that this job is expected to run as part of a single 'modify' qemu + * domain job as this job is not registered with the disk itself and @src must + * be valid for the whole time the job is running. + */ +qemuBlockJobDataPtr +qemuBlockJobNewPopulate(virDomainObjPtr vm, + virStorageSourcePtr src) +{ + g_autoptr(qemuBlockJobData) job = NULL; + g_autofree char *jobname = NULL; + const char *nodename = src->nodeformat; + + jobname = g_strdup_printf("bitmap-populate-%s", nodename); + + if (!(job = qemuBlockJobDataNew(QEMU_BLOCKJOB_TYPE_POPULATE, jobname))) + return NULL; + + job->data.populate.src = src; + + if (qemuBlockJobRegister(job, vm, NULL, true) < 0) + return NULL; + + return g_steal_pointer(&job); +} + + qemuBlockJobDataPtr qemuBlockJobDiskNewCopy(virDomainObjPtr vm, virDomainDiskDefPtr disk, @@ -1478,6 +1511,38 @@ qemuBlockJobProcessEventConcludedBackup(virQEMUDriverPtr driver, } +static void +qemuBlockJobProcessEventConcludedPopulate(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuBlockJobDataPtr job, + qemuDomainAsyncJob asyncJob) +{ + g_autoptr(virJSONValue) actions = NULL; + + /* On successful completion there must be a synchronous handler waiting for + * this job. If there isn't one we need to clean up the associated bitmap. + */ + if (job->newstate == QEMU_BLOCKJOB_STATE_COMPLETED && + job->synchronous) + return; + + if (qemuMonitorTransactionBitmapRemove(actions, + job->data.populate.src->nodeformat, + "libvirt-tmp-bitmap") < 0) + return; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return; + + qemuMonitorTransaction(qemuDomainGetMonitor(vm), &actions); + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + return; + + return; +} + + static void qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job, virQEMUDriverPtr driver, @@ -1527,6 +1592,10 @@ qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job, progressTotal); break; + case QEMU_BLOCKJOB_TYPE_POPULATE: + qemuBlockJobProcessEventConcludedPopulate(driver, vm, job, asyncJob); + break; + case QEMU_BLOCKJOB_TYPE_BROKEN: case QEMU_BLOCKJOB_TYPE_NONE: case QEMU_BLOCKJOB_TYPE_INTERNAL: diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h index 19498b5bd8..0b9da7dd5b 100644 --- a/src/qemu/qemu_blockjob.h +++ b/src/qemu/qemu_blockjob.h @@ -64,6 +64,7 @@ typedef enum { /* Additional enum values local to qemu */ QEMU_BLOCKJOB_TYPE_INTERNAL, QEMU_BLOCKJOB_TYPE_CREATE, + QEMU_BLOCKJOB_TYPE_POPULATE, QEMU_BLOCKJOB_TYPE_BROKEN, QEMU_BLOCKJOB_TYPE_LAST } qemuBlockJobType; @@ -119,6 +120,13 @@ struct _qemuBlockJobBackupData { }; +typedef struct _qemuBlockJobBitmapPopulateData qemuBlockJobBitmapPopulateData; +typedef qemuBlockJobBitmapPopulateData *qemuBlockJobDataBitmapPopulatePtr; + +struct _qemuBlockJobBitmapPopulateData { + virStorageSourcePtr src; +}; + typedef struct _qemuBlockJobData qemuBlockJobData; typedef qemuBlockJobData *qemuBlockJobDataPtr; @@ -140,6 +148,7 @@ struct _qemuBlockJobData { qemuBlockJobCreateData create; qemuBlockJobCopyData copy; qemuBlockJobBackupData backup; + qemuBlockJobBitmapPopulateData populate; } data; int type; /* qemuBlockJobType */ @@ -197,6 +206,10 @@ qemuBlockJobNewCreate(virDomainObjPtr vm, virStorageSourcePtr chain, bool storage); +qemuBlockJobDataPtr +qemuBlockJobNewPopulate(virDomainObjPtr vm, + virStorageSourcePtr src); + qemuBlockJobDataPtr qemuBlockJobDiskNewCopy(virDomainObjPtr vm, virDomainDiskDefPtr disk, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0cd9cf8582..80d1d14e4f 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2737,6 +2737,12 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload, } break; + case QEMU_BLOCKJOB_TYPE_POPULATE: + if (job->data.populate.src) + virBufferAsprintf(&childBuf, "<src node='%s'/>\n", job->data.populate.src->nodeformat); + + break; + case QEMU_BLOCKJOB_TYPE_BROKEN: case QEMU_BLOCKJOB_TYPE_NONE: case QEMU_BLOCKJOB_TYPE_INTERNAL: @@ -3364,6 +3370,13 @@ qemuDomainObjPrivateXMLParseBlockjobDataSpecific(qemuBlockJobDataPtr job, goto broken; break; + case QEMU_BLOCKJOB_TYPE_POPULATE: + qemuDomainObjPrivateXMLParseBlockjobNodename(job, + "string(./src/@node)", + &job->data.populate.src, + ctxt); + break; + case QEMU_BLOCKJOB_TYPE_BROKEN: case QEMU_BLOCKJOB_TYPE_NONE: case QEMU_BLOCKJOB_TYPE_INTERNAL: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5a3b3bb35b..febe417faf 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17263,6 +17263,7 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver, case QEMU_BLOCKJOB_TYPE_BACKUP: case QEMU_BLOCKJOB_TYPE_INTERNAL: case QEMU_BLOCKJOB_TYPE_CREATE: + case QEMU_BLOCKJOB_TYPE_POPULATE: case QEMU_BLOCKJOB_TYPE_BROKEN: virReportError(VIR_ERR_OPERATION_INVALID, _("job type '%s' does not support pivot"), -- 2.26.2

Add a helper which will always return the storage source private data even if it was not allocated before. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 10 ++++++++++ src/qemu/qemu_domain.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 80d1d14e4f..bceeaf0342 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1234,6 +1234,16 @@ qemuDomainStorageSourcePrivateDispose(void *obj) } +qemuDomainStorageSourcePrivatePtr +qemuDomainStorageSourcePrivateFetch(virStorageSourcePtr src) +{ + if (!src->privateData) + src->privateData = qemuDomainStorageSourcePrivateNew(); + + return QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src); +} + + static virClassPtr qemuDomainVcpuPrivateClass; static void qemuDomainVcpuPrivateDispose(void *obj); diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 821832c986..7b4e6bbd84 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -490,6 +490,8 @@ struct _qemuDomainStorageSourcePrivate { }; virObjectPtr qemuDomainStorageSourcePrivateNew(void); +qemuDomainStorageSourcePrivatePtr +qemuDomainStorageSourcePrivateFetch(virStorageSourcePtr src); typedef struct _qemuDomainVcpuPrivate qemuDomainVcpuPrivate; typedef qemuDomainVcpuPrivate *qemuDomainVcpuPrivatePtr; -- 2.26.2

qemuBlockBitmapTemporaryAdd uses the 'block-dirty-bitmap-populate' qemu blockjob to fill a new bitmap from the allocation layer. This is useful to restore bitmaps for backing chain layers where a specific bitmap is not necessary or the layer was created outside of libvirt. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 190 +++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_block.h | 11 +++ src/qemu/qemu_blockjob.c | 2 +- 3 files changed, 202 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index f42fd200a3..69578e861c 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3434,3 +3434,193 @@ qemuBlockUpdateRelativeBacking(virDomainObjPtr vm, return 0; } + + +static void +qemuBlockBitmapTemporaryRemoveDuplicates(GSList *images) +{ + g_autoptr(virHashTable) duplicates = virHashNew(NULL); + GSList *next; + GSList *prev = NULL; + + for (next = images; next; next = next->next) { + virStorageSourcePtr img = next->data; + + if (virHashHasEntry(duplicates, img->nodeformat)) { + next = g_slist_delete_link(prev, next); + continue; + } + + virHashAddEntry(duplicates, img->nodeformat, NULL); + + prev = next; + } +} + + +/** + * qemuBlockBitmapTemporaryAdd: + * @vm: domain object + * @blockNamedNodeData: hash table filled with qemuBlockNamedNodeData + * @images: a GSList of virStorageSources to add the temporary bitmaps for + * @asyncJob: qemu asynchronous job type + * + * Add temporary block dirty bitmaps populated from the allocation map of + * images for list of virStorageSources @images. The bitmaps added are called + * "libvirt-tmp-allocation" and are not made persistent. After this function + * returns @images is updated to the actual list of bitmaps which were added and + * qemuBlockBitmapTemporaryRemove can be used to undo the changes. + */ +int +qemuBlockBitmapTemporaryAdd(virDomainObjPtr vm, + virHashTablePtr blockNamedNodeData, + GSList **images, + qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + g_autoptr(virJSONValue) actions = virJSONValueNewArray(); + bool failed = false; + GSList *next; + int rc; + + if (!*images) + return 0; + + qemuBlockBitmapTemporaryRemoveDuplicates(*images); + + for (next = *images; next; next = next->next) { + virStorageSourcePtr img = next->data; + qemuBlockNamedNodeDataBitmapPtr tmpbitmap; + qemuDomainStorageSourcePrivatePtr srcPriv; + + if ((tmpbitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, img, + "libvirt-tmp-allocation"))) { + if (!tmpbitmap->recording || tmpbitmap->persistent || tmpbitmap->inconsistent) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("internal bitmap in unexpected state")); + return -1; + } + } else { + if (qemuMonitorTransactionBitmapAdd(actions, + img->nodeformat, + "libvirt-tmp-allocation", + false, false, 0) < 0) + return -1; + } + + if (!(srcPriv = qemuDomainStorageSourcePrivateFetch(img))) + return -1; + + if (!(srcPriv->blockjob = qemuBlockJobNewPopulate(vm, img))) + return -1; + + qemuBlockJobSyncBegin(srcPriv->blockjob); + + if (qemuMonitorTransactionBitmapPopulate(actions, + img->nodeformat, + "libvirt-tmp-allocation", + srcPriv->blockjob->name) < 0) + return -1; + } + + if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0) + return -1; + + rc = qemuMonitorTransaction(priv->mon, &actions); + + if (qemuDomainObjExitMonitor(priv->driver, vm) < 0 || rc < 0) + return -1; + + while (true) { + bool update = false; + bool running = false; + + for (next = *images; next; next = next->next) { + virStorageSourcePtr img = next->data; + qemuDomainStorageSourcePrivatePtr srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(img); + + if (!srcPriv->blockjob) + continue; + + if (srcPriv->blockjob->newstate != -1) + update = true; + + qemuBlockJobUpdate(vm, srcPriv->blockjob, asyncJob); + + switch ((qemuBlockjobState) srcPriv->blockjob->state) { + case QEMU_BLOCKJOB_STATE_NEW: + case QEMU_BLOCKJOB_STATE_RUNNING: + running = true; + break; + + case QEMU_BLOCKJOB_STATE_FAILED: + case QEMU_BLOCKJOB_STATE_CANCELLED: + failed = true; + G_GNUC_FALLTHROUGH; + /* completed is assumed once no job has failed and no job is running */ + case QEMU_BLOCKJOB_STATE_COMPLETED: + virObjectUnref(srcPriv->blockjob); + srcPriv->blockjob = NULL; + break; + + /* other states are impossible in this case */ + case QEMU_BLOCKJOB_STATE_READY: + case QEMU_BLOCKJOB_STATE_CONCLUDED: + case QEMU_BLOCKJOB_STATE_ABORTING: + case QEMU_BLOCKJOB_STATE_PIVOTING: + case QEMU_BLOCKJOB_STATE_LAST: + break; + } + } + + /* Updating job will cause monitor access which in turn allows other + * events to be processed. We must ensure to re-process the list before + * waiting to prevent getting stuck */ + if (update) + continue; + + if (!running) + break; + + if (virDomainObjWait(vm) < 0) + return -1; + } + + if (failed) { + qemuBlockBitmapTemporaryRemove(vm, *images, asyncJob); + g_slist_free(*images); + *images = NULL; + return -1; + } + + return 0; +} + + +void +qemuBlockBitmapTemporaryRemove(virDomainObjPtr vm, + GSList *images, + qemuDomainAsyncJob asyncJob) + +{ + VIR_ERROR_AUTOPRESERVE_LAST; + qemuDomainObjPrivatePtr priv = vm->privateData; + g_autoptr(virJSONValue) actions = virJSONValueNewArray(); + + if (!images) + return; + + for (; images; images = images->next) { + virStorageSourcePtr img = images->data; + + if (qemuMonitorTransactionBitmapRemove(actions, img->nodeformat, "libvirt-tmp-allocation") < 0) + return; + } + + if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0) + return; + + qemuMonitorTransaction(priv->mon, &actions); + + ignore_value(qemuDomainObjExitMonitor(priv->driver, vm)); +} diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 2ad2ce1a1f..ccd6f57440 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -266,3 +266,14 @@ int qemuBlockUpdateRelativeBacking(virDomainObjPtr vm, virStorageSourcePtr src, virStorageSourcePtr topsrc); + +int +qemuBlockBitmapTemporaryAdd(virDomainObjPtr vm, + virHashTablePtr blockNamedNodeData, + GSList **images, + qemuDomainAsyncJob asyncJob); + +void +qemuBlockBitmapTemporaryRemove(virDomainObjPtr vm, + GSList *images, + qemuDomainAsyncJob asyncJob); diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 79820c6ca8..b19d96b312 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -1528,7 +1528,7 @@ qemuBlockJobProcessEventConcludedPopulate(virQEMUDriverPtr driver, if (qemuMonitorTransactionBitmapRemove(actions, job->data.populate.src->nodeformat, - "libvirt-tmp-bitmap") < 0) + "libvirt-tmp-allocation") < 0) return; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) -- 2.26.2

Add a function which allows to merge bitmaps according to the new semantics and will allow to replace all the specific ad-hoc functions currently in use for 'backup', 'block commit', 'block copy' and will also be usable in the future for 'block pull' and non-shared storage migration. The semantics are a bit quirky for the 'backup' case but these quirks are documented and will prevent us from having two slightly different algorithms. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 151 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_block.h | 11 +++ 2 files changed, 162 insertions(+) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 69578e861c..6eab9cb4e2 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -2847,6 +2847,157 @@ qemuBlockGetNamedNodeData(virDomainObjPtr vm, } +/** + * qemuBlockGetBitmapMergeActions: + * @topsrc: top of the chain to merge bitmaps in + * @basesrc: bottom of the chain to merge bitmaps in (NULL for full chain) + * @target: destination storage source of the merge (may be part of original chain) + * @bitmapname: name of bitmap to perform the merge (NULL for all bitmaps) + * @dstbitmapname: name of destination bitmap of the merge (see below for caveats) + * @writebitmapsrc: storage source corresponding to the node containing the write temporary bitmap + * @actions: returns actions for a 'transaction' QMP command for executing the merge + * @allocationbitmapnodes: list of storage sources which will require an allocation bitmap + * @blockNamedNodeData: hash table filled with qemuBlockNamedNodeData + * + * Calculate handling of dirty block bitmaps between @topsrc and @basesrc. If + * @basesrc is NULL the end of the chain is considered. @target is the destination + * storage source definition of the merge and may or may not be part of the + * merged chain. + * + * Specifically the merging algorithm ensures that each considered bitmap is + * merged with the appropriate allocation bitmaps so that it properly describes + * the state of dirty blocks when looked at from @topsrc based on the depth + * of the backing chain where the bitmap is placed. + * + * If @bitmapname is non-NULL only bitmaps with that name are handled, otherwise + * all bitmaps are considered. + * + * If @dstbitmap is non-NULL everything is merged into a bitmap with that name, + * otherwise each bitmap is merged into a bitmap with the same name into @target. + * Additionally if @dstbitmap is non-NULL the target bitmap is created as 'inactive' + * and 'transient' as a special case for the backup operation. + * + * If @writebitmapsrc is non-NULL, the 'libvirt-tmp-activewrite' bitmap from + * given node is merged along with others. This bitmap corresponds to the writes + * which occured between an active layer job finished and the rest of the bitmap + * merging. + * + * If the bitmap is not valid somehow (see qemuBlockBitmapChainIsValid) given + * bitmap is silently skipped, so callers must ensure that given bitmap is valid + * if they care about it. + * + * The resulting 'transacion' QMP command actions are filled in and returned via + * @actions. In cases when the merging requires use of bitmap created from the + * allocation map of certain parts of the chain the @allocationbitmapnodes list + * is filled with pointers to the virStorageSource structure of the backing + * chain members where the allocation bitmap must be added prior to the merge. + * + * Note that @actions and @allocationbitmapnodes may be NULL if no merging is + * required. + */ +int +qemuBlockGetBitmapMergeActions(virStorageSourcePtr topsrc, + virStorageSourcePtr basesrc, + virStorageSourcePtr target, + const char *bitmapname, + const char *dstbitmapname, + virStorageSourcePtr writebitmapsrc, + virJSONValuePtr *actions, + GSList **allocationbitmapnodes, + virHashTablePtr blockNamedNodeData) +{ + g_autoptr(virJSONValue) act = virJSONValueNewArray(); + virStorageSourcePtr n; + qemuBlockNamedNodeDataPtr entry; + g_autoptr(virJSONValue) tmpbitmaps = virJSONValueNewArray(); + g_autoptr(GSList) tmpbitmapnodes = NULL; + g_autoptr(GSList) tmpbitmapnodesused = NULL; + size_t i; + + for (n = topsrc; virStorageSourceIsBacking(n) && n != basesrc; n = n->backingStore) { + bool copytmpbitmapnodes = false; + + if (!(entry = virHashLookup(blockNamedNodeData, n->nodeformat))) + continue; + + for (i = 0; i < entry->nbitmaps; i++) { + qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i]; + g_autoptr(virJSONValue) merge = NULL; + const char *mergebitmapname = dstbitmapname; + bool mergebitmappersistent = false; + bool mergebitmapdisabled = true; + + if (bitmapname && + STRNEQ(bitmapname, bitmap->name)) + continue; + + if (!qemuBlockBitmapChainIsValid(topsrc, bitmap->name, blockNamedNodeData)) + continue; + + /* explicitly named destinations mean that we want a temporary + * disabled bitmap only, so undo the default for non-explicit cases */ + if (!mergebitmapname) { + mergebitmapname = bitmap->name; + mergebitmappersistent = true; + mergebitmapdisabled = false; + } + + if (qemuMonitorTransactionBitmapAdd(act, target->nodeformat, + mergebitmapname, + mergebitmappersistent, + mergebitmapdisabled, + bitmap->granularity) < 0) + return -1; + + if (!(merge = virJSONValueCopy(tmpbitmaps))) + return -1; + + copytmpbitmapnodes = true; + + if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(merge, + n->nodeformat, + bitmap->name) < 0) + return -1; + + if (writebitmapsrc && + qemuMonitorTransactionBitmapMergeSourceAddBitmap(merge, + writebitmapsrc->nodeformat, + "libvirt-tmp-activewrite") < 0) + return -1; + + if (qemuMonitorTransactionBitmapMerge(act, target->nodeformat, + mergebitmapname, &merge) < 0) + return -1; + } + + if (copytmpbitmapnodes && tmpbitmapnodes) { + g_slist_free(tmpbitmapnodesused); + tmpbitmapnodesused = g_slist_copy(tmpbitmapnodes); + } + + tmpbitmapnodes = g_slist_prepend(tmpbitmapnodes, n); + + if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(tmpbitmaps, + n->nodeformat, + "libvirt-tmp-allocation") < 0) + return -1; + } + + if (virJSONValueArraySize(act) > 0) { + if (writebitmapsrc && + qemuMonitorTransactionBitmapRemove(act, writebitmapsrc->nodeformat, + "libvirt-tmp-activewrite") < 0) + return -1; + + *actions = g_steal_pointer(&act); + } + + *allocationbitmapnodes = g_steal_pointer(&tmpbitmapnodesused); + + return 0; +} + + /** * qemuBlockBitmapChainIsValid: * diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index ccd6f57440..6bec1e2e29 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -221,6 +221,17 @@ virHashTablePtr qemuBlockGetNamedNodeData(virDomainObjPtr vm, qemuDomainAsyncJob asyncJob); +int +qemuBlockGetBitmapMergeActions(virStorageSourcePtr topsrc, + virStorageSourcePtr basesrc, + virStorageSourcePtr target, + const char *bitmapname, + const char *dstbitmapname, + virStorageSourcePtr writebitmapsrc, + virJSONValuePtr *actions, + GSList **allocationbitmapnodes, + virHashTablePtr blockNamedNodeData); + bool qemuBlockBitmapChainIsValid(virStorageSourcePtr src, const char *bitmapname, -- 2.26.2

Reuse qemuBlockGetBitmapMergeActions which allows to remove the ad-hoc iplementatio of bitmap merging for backup. The new approach is simpler and also more robust in case some of the bitmaps break as they remove the dependancy on the whole chain of bitmaps working. The new approach also allows backups if a snapshot is created outside of libvirt. Additionally the code is greatly simplified. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_backup.c | 239 +++++------------- src/qemu/qemu_backup.h | 13 +- tests/qemublocktest.c | 90 ++----- .../backupmerge/empty-out.json | 4 +- 4 files changed, 88 insertions(+), 258 deletions(-) diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index 5729aac858..242a75431b 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -170,199 +170,68 @@ qemuBackupDiskDataCleanup(virDomainObjPtr vm, } -/** - * qemuBackupBeginCollectIncrementalCheckpoints: - * @vm: domain object - * @incrFrom: name of checkpoint representing starting point of incremental backup - * - * Returns a NULL terminated list of pointers to checkpoint definitions in - * chronological order starting from the 'current' checkpoint until reaching - * @incrFrom. - */ -static virDomainMomentDefPtr * -qemuBackupBeginCollectIncrementalCheckpoints(virDomainObjPtr vm, - const char *incrFrom) -{ - virDomainMomentObjPtr n = virDomainCheckpointGetCurrent(vm->checkpoints); - g_autofree virDomainMomentDefPtr *incr = NULL; - size_t nincr = 0; - - while (n) { - virDomainMomentDefPtr def = n->def; - - if (VIR_APPEND_ELEMENT_COPY(incr, nincr, def) < 0) - return NULL; - - if (STREQ(def->name, incrFrom)) { - def = NULL; - if (VIR_APPEND_ELEMENT_COPY(incr, nincr, def) < 0) - return NULL; - - return g_steal_pointer(&incr); - } - - if (!n->def->parent_name) - break; - - n = virDomainCheckpointFindByName(vm->checkpoints, n->def->parent_name); - } - - virReportError(VIR_ERR_OPERATION_INVALID, - _("could not locate checkpoint '%s' for incremental backup"), - incrFrom); - return NULL; -} - - -static int -qemuBackupGetBitmapMergeRange(virStorageSourcePtr from, - const char *bitmapname, - virJSONValuePtr *actions, - virStorageSourcePtr *to, - const char *diskdst, - virHashTablePtr blockNamedNodeData) +int +qemuBackupDiskPrepareOneBitmapsChain(virStorageSourcePtr backingChain, + virStorageSourcePtr targetsrc, + const char *targetbitmap, + const char *incremental, + virJSONValuePtr actions, + GSList **allocationbitmapnodes, + virHashTablePtr blockNamedNodeData) { - g_autoptr(virJSONValue) ret = virJSONValueNewArray(); - virStorageSourcePtr tmpsrc = NULL; - virStorageSourcePtr n; - bool foundbitmap = false; - - for (n = from; virStorageSourceIsBacking(n); n = n->backingStore) { - qemuBlockNamedNodeDataBitmapPtr bitmap = NULL; - - if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, - n, - bitmapname))) - break; - - foundbitmap = true; - - if (bitmap->inconsistent) { - virReportError(VIR_ERR_INVALID_ARG, - _("bitmap '%s' for image '%s%u' is inconsistent"), - bitmap->name, diskdst, n->id); - return -1; - } - - if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(ret, - n->nodeformat, - bitmapname) < 0) - return -1; - - tmpsrc = n; - } + g_autoptr(virJSONValue) tmpactions = NULL; + g_autoptr(GSList) tmpallocbitmapnodes = NULL; - if (!foundbitmap) { - virReportError(VIR_ERR_INVALID_ARG, - _("failed to find bitmap '%s' in image '%s%u'"), - bitmapname, diskdst, from->id); + if (qemuBlockGetBitmapMergeActions(backingChain, NULL, targetsrc, + incremental, targetbitmap, NULL, + &tmpactions, &tmpallocbitmapnodes, + blockNamedNodeData) < 0) return -1; - } - *actions = g_steal_pointer(&ret); - *to = tmpsrc; - - return 0; -} - - -virJSONValuePtr -qemuBackupDiskPrepareOneBitmapsChain(virDomainMomentDefPtr *incremental, - virStorageSourcePtr backingChain, - virHashTablePtr blockNamedNodeData, - const char *diskdst) -{ - g_autoptr(virJSONValue) ret = NULL; - size_t incridx = 0; - virStorageSourcePtr n = backingChain; - - ret = virJSONValueNewArray(); - - for (incridx = 0; incremental[incridx]; incridx++) { - g_autoptr(virJSONValue) tmp = virJSONValueNewArray(); - virStorageSourcePtr tmpsrc = NULL; - virDomainCheckpointDefPtr chkdef = (virDomainCheckpointDefPtr) incremental[incridx]; - bool checkpoint_has_disk = false; - size_t i; - - for (i = 0; i < chkdef->ndisks; i++) { - if (STRNEQ_NULLABLE(diskdst, chkdef->disks[i].name)) - continue; - - if (chkdef->disks[i].type == VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP) - checkpoint_has_disk = true; - - break; - } - - if (!checkpoint_has_disk) { - if (!incremental[incridx + 1]) { - virReportError(VIR_ERR_INVALID_ARG, - _("disk '%s' not found in checkpoint '%s'"), - diskdst, incremental[incridx]->name); - return NULL; - } - - continue; - } - - if (qemuBackupGetBitmapMergeRange(n, incremental[incridx]->name, - &tmp, &tmpsrc, diskdst, - blockNamedNodeData) < 0) - return NULL; - - if (virJSONValueArrayConcat(ret, tmp) < 0) - return NULL; + if (tmpactions && + virJSONValueArrayConcat(actions, tmpactions) < 0) + return -1; - n = tmpsrc; + if (allocationbitmapnodes) { + *allocationbitmapnodes = g_slist_concat(*allocationbitmapnodes, tmpallocbitmapnodes); + tmpallocbitmapnodes = NULL; } - return g_steal_pointer(&ret); + return 0; } static int qemuBackupDiskPrepareOneBitmaps(struct qemuBackupDiskData *dd, virJSONValuePtr actions, - virDomainMomentDefPtr *incremental, + GSList **allocationbitmapnodes, virHashTablePtr blockNamedNodeData) { - g_autoptr(virJSONValue) mergebitmaps = NULL; - g_autoptr(virJSONValue) mergebitmapsstore = NULL; - - if (!(mergebitmaps = qemuBackupDiskPrepareOneBitmapsChain(incremental, - dd->domdisk->src, - blockNamedNodeData, - dd->domdisk->dst))) - return -1; - - if (!(mergebitmapsstore = virJSONValueCopy(mergebitmaps))) - return -1; - - if (qemuMonitorTransactionBitmapAdd(actions, - dd->domdisk->src->nodeformat, - dd->incrementalBitmap, - false, - true, 0) < 0) - return -1; - - if (qemuMonitorTransactionBitmapMerge(actions, - dd->domdisk->src->nodeformat, - dd->incrementalBitmap, - &mergebitmaps) < 0) + if (!qemuBlockBitmapChainIsValid(dd->domdisk->src, + dd->backupdisk->incremental, + blockNamedNodeData)) { + virReportError(VIR_ERR_INVALID_ARG, + _("missing or broken bitmap '%s' for disk '%s'"), + dd->backupdisk->incremental, dd->domdisk->dst); return -1; + } - if (qemuMonitorTransactionBitmapAdd(actions, - dd->store->nodeformat, - dd->incrementalBitmap, - false, - true, 0) < 0) + if (qemuBackupDiskPrepareOneBitmapsChain(dd->domdisk->src, + dd->domdisk->src, + dd->incrementalBitmap, + dd->backupdisk->incremental, + actions, + allocationbitmapnodes, + blockNamedNodeData) < 0) return -1; - if (qemuMonitorTransactionBitmapMerge(actions, - dd->store->nodeformat, - dd->incrementalBitmap, - &mergebitmapsstore) < 0) + if (qemuBackupDiskPrepareOneBitmapsChain(dd->domdisk->src, + dd->store, + dd->incrementalBitmap, + dd->backupdisk->incremental, + actions, + allocationbitmapnodes, + blockNamedNodeData) < 0) return -1; return 0; @@ -374,12 +243,12 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm, virDomainBackupDiskDefPtr backupdisk, struct qemuBackupDiskData *dd, virJSONValuePtr actions, + GSList **allocationbitmapnodes, bool pull, virHashTablePtr blockNamedNodeData, virQEMUDriverConfigPtr cfg) { qemuDomainObjPrivatePtr priv = vm->privateData; - g_autofree virDomainMomentDefPtr *incremental = NULL; /* set data structure */ dd->backupdisk = backupdisk; @@ -417,15 +286,12 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm, return -1; if (dd->backupdisk->incremental) { - if (!(incremental = qemuBackupBeginCollectIncrementalCheckpoints(vm, dd->backupdisk->incremental))) - return -1; - if (dd->backupdisk->exportbitmap) dd->incrementalBitmap = g_strdup(dd->backupdisk->exportbitmap); else dd->incrementalBitmap = g_strdup_printf("backup-%s", dd->domdisk->dst); - if (qemuBackupDiskPrepareOneBitmaps(dd, actions, incremental, + if (qemuBackupDiskPrepareOneBitmaps(dd, actions, allocationbitmapnodes, blockNamedNodeData) < 0) return -1; } @@ -490,6 +356,7 @@ qemuBackupDiskPrepareData(virDomainObjPtr vm, virDomainBackupDefPtr def, virHashTablePtr blockNamedNodeData, virJSONValuePtr actions, + GSList **allocationbitmapnodes, virQEMUDriverConfigPtr cfg, struct qemuBackupDiskData **rdd) { @@ -509,7 +376,8 @@ qemuBackupDiskPrepareData(virDomainObjPtr vm, ndisks++; - if (qemuBackupDiskPrepareDataOne(vm, backupdisk, dd, actions, pull, + if (qemuBackupDiskPrepareDataOne(vm, backupdisk, dd, actions, + allocationbitmapnodes, pull, blockNamedNodeData, cfg) < 0) goto error; @@ -809,6 +677,7 @@ qemuBackupBegin(virDomainObjPtr vm, bool reuse = (flags & VIR_DOMAIN_BACKUP_BEGIN_REUSE_EXTERNAL); int rc = 0; int ret = -1; + g_autoptr(GSList) allocationbitmapnodes = NULL; virCheckFlags(VIR_DOMAIN_BACKUP_BEGIN_REUSE_EXTERNAL, -1); @@ -880,8 +749,8 @@ qemuBackupBegin(virDomainObjPtr vm, if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_BACKUP))) goto endjob; - if ((ndd = qemuBackupDiskPrepareData(vm, def, blockNamedNodeData, - actions, cfg, &dd)) <= 0) { + if ((ndd = qemuBackupDiskPrepareData(vm, def, blockNamedNodeData, actions, + &allocationbitmapnodes, cfg, &dd)) <= 0) { if (ndd == 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("no disks selected for backup")); @@ -893,6 +762,10 @@ qemuBackupBegin(virDomainObjPtr vm, if (qemuBackupDiskPrepareStorage(vm, dd, ndd, blockNamedNodeData, reuse) < 0) goto endjob; + if (qemuBlockBitmapTemporaryAdd(vm, blockNamedNodeData, &allocationbitmapnodes, + QEMU_ASYNC_JOB_BACKUP) < 0) + goto endjob; + priv->backup = g_steal_pointer(&def); if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, QEMU_ASYNC_JOB_BACKUP) < 0) @@ -939,6 +812,8 @@ qemuBackupBegin(virDomainObjPtr vm, endjob: qemuBackupDiskDataCleanup(vm, dd, ndd); + qemuBlockBitmapTemporaryRemove(vm, allocationbitmapnodes, QEMU_ASYNC_JOB_BACKUP); + /* if 'chk' is non-NULL here it's a failure and it must be rolled back */ qemuCheckpointRollbackMetadata(vm, chk); diff --git a/src/qemu/qemu_backup.h b/src/qemu/qemu_backup.h index b19c3bf1c9..be280f1f3f 100644 --- a/src/qemu/qemu_backup.h +++ b/src/qemu/qemu_backup.h @@ -53,8 +53,11 @@ qemuBackupGetJobInfoStats(virQEMUDriverPtr driver, qemuDomainJobInfoPtr jobInfo); /* exported for testing */ -virJSONValuePtr -qemuBackupDiskPrepareOneBitmapsChain(virDomainMomentDefPtr *incremental, - virStorageSourcePtr backingChain, - virHashTablePtr blockNamedNodeData, - const char *diskdst); +int +qemuBackupDiskPrepareOneBitmapsChain(virStorageSourcePtr backingChain, + virStorageSourcePtr targetsrc, + const char *targetbitmap, + const char *incremental, + virJSONValuePtr actions, + GSList **allocationbitmapnodes, + virHashTablePtr blockNamedNodeData); diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index c10eabb6a0..2488aa2200 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -716,65 +716,6 @@ testQemuBitmapGetFakeChainEntry(virStorageSourcePtr src, } -typedef virDomainMomentDefPtr testMomentList; - -static void -testMomentListFree(testMomentList *list) -{ - testMomentList *tmp = list; - - if (!list) - return; - - while (*tmp) { - virObjectUnref(*tmp); - tmp++; - } - - g_free(list); -} - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(testMomentList, testMomentListFree); - -static virDomainMomentDefPtr -testQemuBackupGetIncrementalMoment(const char *name) -{ - virDomainCheckpointDefPtr checkpoint = NULL; - - if (!(checkpoint = virDomainCheckpointDefNew())) - abort(); - - checkpoint->disks = g_new0(virDomainCheckpointDiskDef, 1); - checkpoint->ndisks = 1; - - checkpoint->disks[0].name = g_strdup("testdisk"); - checkpoint->disks[0].type = VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP; - - checkpoint->parent.name = g_strdup(name); - - return (virDomainMomentDefPtr) checkpoint; -} - - -static virDomainMomentDefPtr * -testQemuBackupGetIncremental(const char *incFrom) -{ - const char *checkpoints[] = {"current", "d", "c", "b", "a"}; - virDomainMomentDefPtr *incr; - size_t i; - - incr = g_new0(virDomainMomentDefPtr, G_N_ELEMENTS(checkpoints) + 1); - - for (i = 0; i < G_N_ELEMENTS(checkpoints); i++) { - incr[i] = testQemuBackupGetIncrementalMoment(checkpoints[i]); - - if (STREQ(incFrom, checkpoints[i])) - break; - } - - return incr; -} - static const char *backupDataPrefix = "qemublocktestdata/backupmerge/"; struct testQemuBackupIncrementalBitmapCalculateData { @@ -791,10 +732,11 @@ testQemuBackupIncrementalBitmapCalculate(const void *opaque) const struct testQemuBackupIncrementalBitmapCalculateData *data = opaque; g_autoptr(virJSONValue) nodedatajson = NULL; g_autoptr(virHashTable) nodedata = NULL; - g_autoptr(virJSONValue) mergebitmaps = NULL; - g_autofree char *actual = NULL; + g_autoptr(virJSONValue) actions = virJSONValueNewArray(); g_autofree char *expectpath = NULL; - g_autoptr(testMomentList) incremental = NULL; + g_autoptr(GSList) allocationbitmapnodes = NULL; + g_autoptr(virStorageSource) target = NULL; + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; expectpath = g_strdup_printf("%s/%s%s-out.json", abs_srcdir, backupDataPrefix, data->name); @@ -808,19 +750,27 @@ testQemuBackupIncrementalBitmapCalculate(const void *opaque) return -1; } - incremental = testQemuBackupGetIncremental(data->incremental); + if (!(target = virStorageSourceNew())) + return -1; + + target->nodeformat = g_strdup_printf("target_node"); - if ((mergebitmaps = qemuBackupDiskPrepareOneBitmapsChain(incremental, - data->chain, - nodedata, - "testdisk"))) { - if (!(actual = virJSONValueToString(mergebitmaps, true))) + if (qemuBackupDiskPrepareOneBitmapsChain(data->chain, + target, + "target-bitmap-name", + data->incremental, + actions, + &allocationbitmapnodes, + nodedata) >= 0) { + if (virJSONValueToBuffer(actions, &buf, true) < 0) return -1; } else { - actual = g_strdup("NULL\n"); + virBufferAddLit(&buf, "NULL\n"); } - return virTestCompareToFile(actual, expectpath); + testQemuBitmapListPrint("allocation bitmap:", allocationbitmapnodes, &buf); + + return virTestCompareToFile(virBufferCurrentContent(&buf), expectpath); } diff --git a/tests/qemublocktestdata/backupmerge/empty-out.json b/tests/qemublocktestdata/backupmerge/empty-out.json index 7951defec1..41b42e677b 100644 --- a/tests/qemublocktestdata/backupmerge/empty-out.json +++ b/tests/qemublocktestdata/backupmerge/empty-out.json @@ -1 +1,3 @@ -NULL +[ + +] -- 2.26.2

The 'basic' case is just a single backing store layer containing the bitmaps so we just copy the bitmaps over to the backup bitmap. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 4 +++ .../backupmerge/basic-deep-out.json | 25 +++++++++++++++++++ .../backupmerge/basic-flat-out.json | 25 +++++++++++++++++++ .../backupmerge/basic-intermediate-out.json | 25 +++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 tests/qemublocktestdata/backupmerge/basic-deep-out.json create mode 100644 tests/qemublocktestdata/backupmerge/basic-flat-out.json create mode 100644 tests/qemublocktestdata/backupmerge/basic-intermediate-out.json diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 2488aa2200..5cdc4d4be6 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1267,6 +1267,10 @@ mymain(void) TEST_BACKUP_BITMAP_CALCULATE("empty", bitmapSourceChain, "a", "empty"); + TEST_BACKUP_BITMAP_CALCULATE("basic-flat", bitmapSourceChain, "current", "basic"); + TEST_BACKUP_BITMAP_CALCULATE("basic-intermediate", bitmapSourceChain, "d", "basic"); + TEST_BACKUP_BITMAP_CALCULATE("basic-deep", bitmapSourceChain, "a", "basic"); + #define TEST_CHECKPOINT_DELETE(testname, delbmp, named) \ do { \ checkpointdeletedata.name = testname; \ diff --git a/tests/qemublocktestdata/backupmerge/basic-deep-out.json b/tests/qemublocktestdata/backupmerge/basic-deep-out.json new file mode 100644 index 0000000000..ff77af789b --- /dev/null +++ b/tests/qemublocktestdata/backupmerge/basic-deep-out.json @@ -0,0 +1,25 @@ +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "target_node", + "name": "target-bitmap-name", + "persistent": false, + "disabled": true, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "target_node", + "target": "target-bitmap-name", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "a" + } + ] + } + } +] diff --git a/tests/qemublocktestdata/backupmerge/basic-flat-out.json b/tests/qemublocktestdata/backupmerge/basic-flat-out.json new file mode 100644 index 0000000000..4637bbc377 --- /dev/null +++ b/tests/qemublocktestdata/backupmerge/basic-flat-out.json @@ -0,0 +1,25 @@ +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "target_node", + "name": "target-bitmap-name", + "persistent": false, + "disabled": true, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "target_node", + "target": "target-bitmap-name", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + } + ] + } + } +] diff --git a/tests/qemublocktestdata/backupmerge/basic-intermediate-out.json b/tests/qemublocktestdata/backupmerge/basic-intermediate-out.json new file mode 100644 index 0000000000..f2f3b3f568 --- /dev/null +++ b/tests/qemublocktestdata/backupmerge/basic-intermediate-out.json @@ -0,0 +1,25 @@ +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "target_node", + "name": "target-bitmap-name", + "persistent": false, + "disabled": true, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "target_node", + "target": "target-bitmap-name", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "d" + } + ] + } + } +] -- 2.26.2

The 'snapshots' case has multiple layers so we need to make sure that the bitmaps are merged with the appropriate temporary bitmaps formatted from the allocation bitmap for any backing chain layer above. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 4 ++ .../backupmerge/snapshots-deep-out.json | 46 +++++++++++++++++++ .../backupmerge/snapshots-flat-out.json | 25 ++++++++++ .../snapshots-intermediate-out.json | 31 +++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 tests/qemublocktestdata/backupmerge/snapshots-deep-out.json create mode 100644 tests/qemublocktestdata/backupmerge/snapshots-flat-out.json create mode 100644 tests/qemublocktestdata/backupmerge/snapshots-intermediate-out.json diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 5cdc4d4be6..a04719b2df 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1271,6 +1271,10 @@ mymain(void) TEST_BACKUP_BITMAP_CALCULATE("basic-intermediate", bitmapSourceChain, "d", "basic"); TEST_BACKUP_BITMAP_CALCULATE("basic-deep", bitmapSourceChain, "a", "basic"); + TEST_BACKUP_BITMAP_CALCULATE("snapshots-flat", bitmapSourceChain, "current", "snapshots"); + TEST_BACKUP_BITMAP_CALCULATE("snapshots-intermediate", bitmapSourceChain, "d", "snapshots"); + TEST_BACKUP_BITMAP_CALCULATE("snapshots-deep", bitmapSourceChain, "a", "snapshots"); + #define TEST_CHECKPOINT_DELETE(testname, delbmp, named) \ do { \ checkpointdeletedata.name = testname; \ diff --git a/tests/qemublocktestdata/backupmerge/snapshots-deep-out.json b/tests/qemublocktestdata/backupmerge/snapshots-deep-out.json new file mode 100644 index 0000000000..0cd4ec2b8a --- /dev/null +++ b/tests/qemublocktestdata/backupmerge/snapshots-deep-out.json @@ -0,0 +1,46 @@ +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "target_node", + "name": "target-bitmap-name", + "persistent": false, + "disabled": true, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "target_node", + "target": "target-bitmap-name", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-4-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-5-format", + "name": "a" + } + ] + } + } +] +allocation bitmap: +libvirt-4-format +libvirt-3-format +libvirt-2-format +libvirt-1-format diff --git a/tests/qemublocktestdata/backupmerge/snapshots-flat-out.json b/tests/qemublocktestdata/backupmerge/snapshots-flat-out.json new file mode 100644 index 0000000000..4637bbc377 --- /dev/null +++ b/tests/qemublocktestdata/backupmerge/snapshots-flat-out.json @@ -0,0 +1,25 @@ +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "target_node", + "name": "target-bitmap-name", + "persistent": false, + "disabled": true, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "target_node", + "target": "target-bitmap-name", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + } + ] + } + } +] diff --git a/tests/qemublocktestdata/backupmerge/snapshots-intermediate-out.json b/tests/qemublocktestdata/backupmerge/snapshots-intermediate-out.json new file mode 100644 index 0000000000..d6cf4e3a17 --- /dev/null +++ b/tests/qemublocktestdata/backupmerge/snapshots-intermediate-out.json @@ -0,0 +1,31 @@ +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "target_node", + "name": "target-bitmap-name", + "persistent": false, + "disabled": true, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "target_node", + "target": "target-bitmap-name", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "d" + } + ] + } + } +] +allocation bitmap: +libvirt-1-format -- 2.26.2

Reuse qemuBlockGetBitmapMergeActions which allows to remove the ad-hoc implementatio of bitmap merging for block commit. The new approach is way simpler and more robust and also allows us to get rid of the disabling of bitmaps done prior to the start as we actually do want to update the bitmaps in the base. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 203 +----------------- src/qemu/qemu_block.h | 10 +- src/qemu/qemu_blockjob.c | 24 ++- src/qemu/qemu_driver.c | 56 +---- tests/qemublocktest.c | 21 +- .../qemublocktestdata/bitmapblockcommit/empty | 1 - 6 files changed, 47 insertions(+), 268 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 6eab9cb4e2..fd3fe4c354 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3176,117 +3176,7 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src, /** * @topsrc: virStorageSource representing 'top' of the job * @basesrc: virStorageSource representing 'base' of the job - * @blockNamedNodeData: hash table containing data about bitmaps - * @actions: filled with arguments for a 'transaction' command - * @disabledBitmapsBase: filled with a list of bitmap names which must be disabled - * - * Prepares data for correctly handling bitmaps during the start of a commit - * job. The bitmaps in the 'base' image must be disabled, so that the writes - * done by the blockjob don't dirty the enabled bitmaps. - * - * @actions and @disabledBitmapsBase are untouched if no bitmaps need - * to be disabled. - */ -int -qemuBlockBitmapsHandleCommitStart(virStorageSourcePtr topsrc, - virStorageSourcePtr basesrc, - virHashTablePtr blockNamedNodeData, - virJSONValuePtr *actions, - char ***disabledBitmapsBase) -{ - g_autoptr(virJSONValue) act = virJSONValueNewArray(); - VIR_AUTOSTRINGLIST bitmaplist = NULL; - size_t curbitmapstr = 0; - qemuBlockNamedNodeDataPtr entry; - bool disable_bitmaps = false; - size_t i; - - if (!(entry = virHashLookup(blockNamedNodeData, basesrc->nodeformat))) - return 0; - - bitmaplist = g_new0(char *, entry->nbitmaps + 1); - - for (i = 0; i < entry->nbitmaps; i++) { - qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i]; - - if (!bitmap->recording || bitmap->inconsistent || - !qemuBlockBitmapChainIsValid(topsrc, bitmap->name, blockNamedNodeData)) - continue; - - disable_bitmaps = true; - - if (qemuMonitorTransactionBitmapDisable(act, basesrc->nodeformat, - bitmap->name) < 0) - return -1; - - bitmaplist[curbitmapstr++] = g_strdup(bitmap->name); - } - - if (disable_bitmaps) { - *actions = g_steal_pointer(&act); - *disabledBitmapsBase = g_steal_pointer(&bitmaplist); - } - - return 0; -} - - -struct qemuBlockBitmapsHandleCommitData { - bool skip; - bool create; - bool enable; - const char *basenode; - virJSONValuePtr merge; - unsigned long long granularity; - bool persistent; -}; - - -static void -qemuBlockBitmapsHandleCommitDataFree(void *opaque) -{ - struct qemuBlockBitmapsHandleCommitData *data = opaque; - - virJSONValueFree(data->merge); - g_free(data); -} - - -static int -qemuBlockBitmapsHandleCommitFinishIterate(void *payload, - const void *entryname, - void *opaque) -{ - struct qemuBlockBitmapsHandleCommitData *data = payload; - const char *bitmapname = entryname; - virJSONValuePtr actions = opaque; - - if (data->skip) - return 0; - - if (data->create) { - if (qemuMonitorTransactionBitmapAdd(actions, data->basenode, bitmapname, - data->persistent, !data->enable, - data->granularity) < 0) - return -1; - } else { - if (data->enable && - qemuMonitorTransactionBitmapEnable(actions, data->basenode, bitmapname) < 0) - return -1; - } - - if (data->merge && - qemuMonitorTransactionBitmapMerge(actions, data->basenode, bitmapname, - &data->merge) < 0) - return -1; - - return 0; -} - - -/** - * @topsrc: virStorageSource representing 'top' of the job - * @basesrc: virStorageSource representing 'base' of the job + * @active: commit job is an active layer block-commit * @blockNamedNodeData: hash table containing data about bitmaps * @actions: filled with arguments for a 'transaction' command * @disabledBitmapsBase: bitmap names which were disabled @@ -3299,95 +3189,22 @@ qemuBlockBitmapsHandleCommitFinishIterate(void *payload, int qemuBlockBitmapsHandleCommitFinish(virStorageSourcePtr topsrc, virStorageSourcePtr basesrc, + bool active, virHashTablePtr blockNamedNodeData, virJSONValuePtr *actions, - char **disabledBitmapsBase) + GSList **allocationbitmapnodes) { - g_autoptr(virJSONValue) act = virJSONValueNewArray(); - virStorageSourcePtr n; - qemuBlockNamedNodeDataPtr entry; - g_autoptr(virHashTable) commitdata = NULL; - struct qemuBlockBitmapsHandleCommitData *bitmapdata; - size_t i; - - commitdata = virHashNew(qemuBlockBitmapsHandleCommitDataFree); - - for (n = topsrc; n != basesrc; n = n->backingStore) { - if (!(entry = virHashLookup(blockNamedNodeData, n->nodeformat))) - continue; - - for (i = 0; i < entry->nbitmaps; i++) { - qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i]; - - if (!(bitmapdata = virHashLookup(commitdata, bitmap->name))) { - bitmapdata = g_new0(struct qemuBlockBitmapsHandleCommitData, 1); + virStorageSourcePtr writebitmapsrc = NULL; - /* we must mirror the state of the topmost bitmap and merge - * everything else */ - bitmapdata->create = true; - bitmapdata->enable = bitmap->recording; - bitmapdata->basenode = basesrc->nodeformat; - bitmapdata->merge = virJSONValueNewArray(); - bitmapdata->granularity = bitmap->granularity; - bitmapdata->persistent = bitmap->persistent; + if (active) + writebitmapsrc = basesrc; - if (virHashAddEntry(commitdata, bitmap->name, bitmapdata) < 0) { - qemuBlockBitmapsHandleCommitDataFree(bitmapdata); - return -1; - } - } - - if (bitmap->inconsistent || - !qemuBlockBitmapChainIsValid(topsrc, bitmap->name, blockNamedNodeData)) - bitmapdata->skip = true; - - if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(bitmapdata->merge, - n->nodeformat, - bitmap->name) < 0) - return -1; - } - } - - if ((entry = virHashLookup(blockNamedNodeData, basesrc->nodeformat))) { - /* note that all bitmaps in 'base' were disabled when commit was started */ - for (i = 0; i < entry->nbitmaps; i++) { - qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i]; - - if ((bitmapdata = virHashLookup(commitdata, bitmap->name))) { - bitmapdata->create = false; - } else { - if (disabledBitmapsBase) { - char **disabledbitmaps; - - for (disabledbitmaps = disabledBitmapsBase; *disabledbitmaps; disabledbitmaps++) { - if (STREQ(*disabledbitmaps, bitmap->name)) { - bitmapdata = g_new0(struct qemuBlockBitmapsHandleCommitData, 1); - - bitmapdata->create = false; - bitmapdata->enable = true; - bitmapdata->basenode = basesrc->nodeformat; - bitmapdata->granularity = bitmap->granularity; - bitmapdata->persistent = bitmap->persistent; - - if (virHashAddEntry(commitdata, bitmap->name, bitmapdata) < 0) { - qemuBlockBitmapsHandleCommitDataFree(bitmapdata); - return -1; - } - - break; - } - } - } - } - } - } - - if (virHashForEach(commitdata, qemuBlockBitmapsHandleCommitFinishIterate, act) < 0) + if (qemuBlockGetBitmapMergeActions(topsrc, basesrc, basesrc, NULL, NULL, + writebitmapsrc, actions, + allocationbitmapnodes, + blockNamedNodeData) < 0) return -1; - if (virJSONValueArraySize(act) > 0) - *actions = g_steal_pointer(&act); - return 0; } diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 6bec1e2e29..5d98f7ce6b 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -244,19 +244,13 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src, bool shallow, virJSONValuePtr *actions); -int -qemuBlockBitmapsHandleCommitStart(virStorageSourcePtr topsrc, - virStorageSourcePtr basesrc, - virHashTablePtr blockNamedNodeData, - virJSONValuePtr *actions, - char ***disabledBitmapsBase); - int qemuBlockBitmapsHandleCommitFinish(virStorageSourcePtr topsrc, virStorageSourcePtr basesrc, + bool active, virHashTablePtr blockNamedNodeData, virJSONValuePtr *actions, - char **disabledBitmapsBase); + GSList **r_tmpbitmapnodes); int qemuBlockReopenReadWrite(virDomainObjPtr vm, diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index b19d96b312..ef22bc60ab 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -1102,6 +1102,8 @@ qemuBlockJobProcessEventCompletedCommitBitmaps(virDomainObjPtr vm, qemuDomainObjPrivatePtr priv = vm->privateData; g_autoptr(virHashTable) blockNamedNodeData = NULL; g_autoptr(virJSONValue) actions = NULL; + g_autoptr(GSList) allocationbitmapnodes = NULL; + bool active = job->type == QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT; if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) return 0; @@ -1111,15 +1113,22 @@ qemuBlockJobProcessEventCompletedCommitBitmaps(virDomainObjPtr vm, if (qemuBlockBitmapsHandleCommitFinish(job->data.commit.top, job->data.commit.base, + active, blockNamedNodeData, &actions, - job->data.commit.disabledBitmapsBase) < 0) + &allocationbitmapnodes) < 0) return 0; if (!actions) return 0; - if (qemuBlockReopenReadWrite(vm, job->data.commit.base, asyncJob) < 0) + if (!active) { + if (qemuBlockReopenReadWrite(vm, job->data.commit.base, asyncJob) < 0) + return -1; + } + + if (qemuBlockBitmapTemporaryAdd(vm, blockNamedNodeData, + &allocationbitmapnodes, asyncJob) < 0) return -1; if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0) @@ -1130,8 +1139,12 @@ qemuBlockJobProcessEventCompletedCommitBitmaps(virDomainObjPtr vm, if (qemuDomainObjExitMonitor(priv->driver, vm) < 0) return -1; - if (qemuBlockReopenReadOnly(vm, job->data.commit.base, asyncJob) < 0) - return -1; + qemuBlockBitmapTemporaryRemove(vm, allocationbitmapnodes, asyncJob); + + if (!active) { + if (qemuBlockReopenReadOnly(vm, job->data.commit.base, asyncJob) < 0) + return -1; + } return 0; } @@ -1301,6 +1314,9 @@ qemuBlockJobProcessEventCompletedActiveCommit(virQEMUDriverPtr driver, job->disk->src = job->data.commit.base; job->disk->src->readonly = job->data.commit.top->readonly; + if (qemuBlockJobProcessEventCompletedCommitBitmaps(vm, job, asyncJob) < 0) + return; + qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, job->data.commit.top); if (job->data.commit.deleteCommittedImages) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index febe417faf..98a60ec2e2 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17272,9 +17272,9 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver, case QEMU_BLOCKJOB_TYPE_COPY: if (blockdev && !job->jobflagsmissing) { - g_autoptr(virHashTable) blockNamedNodeData = NULL; bool shallow = job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW; bool reuse = job->jobflags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT; + g_autoptr(virHashTable) blockNamedNodeData = NULL; if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE))) return -1; @@ -17312,16 +17312,15 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver, * the bitmaps if it wasn't present thus must skip this */ if (blockdev && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) { - g_autoptr(virHashTable) blockNamedNodeData = NULL; - if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE))) - return -1; + actions = virJSONValueNewArray(); - if (qemuBlockBitmapsHandleCommitFinish(job->data.commit.top, - job->data.commit.base, - blockNamedNodeData, - &actions, - job->data.commit.disabledBitmapsBase) < 0) + if (qemuMonitorTransactionBitmapAdd(actions, + job->data.commit.base->nodeformat, + "libvirt-tmp-activewrite", + false, + false, + 0) < 0) return -1; } @@ -18442,7 +18441,6 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *nodebase = NULL; bool persistjob = false; bool blockdev = false; - g_autoptr(virJSONValue) bitmapDisableActions = NULL; VIR_AUTOSTRINGLIST bitmapDisableList = NULL; virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW | @@ -18607,27 +18605,6 @@ qemuDomainBlockCommit(virDomainPtr dom, goto endjob; } - if (blockdev && - virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) { - g_autoptr(virHashTable) blockNamedNodeData = NULL; - if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE))) - goto endjob; - - if (qemuBlockBitmapsHandleCommitStart(topSource, baseSource, - blockNamedNodeData, - &bitmapDisableActions, - &bitmapDisableList) < 0) - goto endjob; - - /* if we don't have terminator on 'base' we can't reopen it */ - if (bitmapDisableActions && !baseSource->backingStore) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("can't handle bitmaps on unterminated backing image '%s'"), - base); - goto endjob; - } - } - if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource, baseSource, &bitmapDisableList, flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE, @@ -18652,23 +18629,6 @@ qemuDomainBlockCommit(virDomainPtr dom, !(backingPath = qemuBlockGetBackingStoreString(baseSource, false))) goto endjob; - if (bitmapDisableActions) { - int rc; - - if (qemuBlockReopenReadWrite(vm, baseSource, QEMU_ASYNC_JOB_NONE) < 0) - goto endjob; - - qemuDomainObjEnterMonitor(driver, vm); - rc = qemuMonitorTransaction(priv->mon, &bitmapDisableActions); - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto endjob; - - if (qemuBlockReopenReadOnly(vm, baseSource, QEMU_ASYNC_JOB_NONE) < 0) - goto endjob; - - if (rc < 0) - goto endjob; - } } else { device = job->name; } diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index a04719b2df..5624c96d5f 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -932,12 +932,12 @@ testQemuBlockBitmapBlockcommit(const void *opaque) g_autofree char *actual = NULL; g_autofree char *expectpath = NULL; - g_autoptr(virJSONValue) actionsDisable = NULL; g_autoptr(virJSONValue) actionsMerge = NULL; g_autoptr(virJSONValue) nodedatajson = NULL; g_autoptr(virHashTable) nodedata = NULL; g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; - VIR_AUTOSTRINGLIST bitmapsDisable = NULL; + g_autoptr(GSList) allocationbitmapnodes = NULL; + bool active = data->top == data->chain; expectpath = g_strdup_printf("%s/%s%s", abs_srcdir, blockcommitPrefix, data->name); @@ -951,26 +951,18 @@ testQemuBlockBitmapBlockcommit(const void *opaque) return -1; } - if (qemuBlockBitmapsHandleCommitStart(data->top, data->base, nodedata, - &actionsDisable, &bitmapsDisable) < 0) - return -1; - - virBufferAddLit(&buf, "pre job bitmap disable:\n"); - - if (actionsDisable && - virJSONValueToBuffer(actionsDisable, &buf, true) < 0) - return -1; - virBufferAddLit(&buf, "merge bitmpas:\n"); - if (qemuBlockBitmapsHandleCommitFinish(data->top, data->base, nodedata, - &actionsMerge, bitmapsDisable) < 0) + if (qemuBlockBitmapsHandleCommitFinish(data->top, data->base, active, nodedata, + &actionsMerge, &allocationbitmapnodes) < 0) return -1; if (actionsMerge && virJSONValueToBuffer(actionsMerge, &buf, true) < 0) return -1; + testQemuBitmapListPrint("allocation bitmap:", allocationbitmapnodes, &buf); + actual = virBufferContentAndReset(&buf); return virTestCompareToFile(actual, expectpath); @@ -1361,6 +1353,7 @@ mymain(void) #define TEST_BITMAP_BLOCKCOMMIT(testname, topimg, baseimg, ndf) \ do {\ blockbitmapblockcommitdata.name = testname; \ + blockbitmapblockcommitdata.chain = bitmapSourceChain; \ blockbitmapblockcommitdata.top = testQemuBitmapGetFakeChainEntry(bitmapSourceChain, topimg); \ blockbitmapblockcommitdata.base = testQemuBitmapGetFakeChainEntry(bitmapSourceChain, baseimg); \ blockbitmapblockcommitdata.nodedatafile = ndf; \ diff --git a/tests/qemublocktestdata/bitmapblockcommit/empty b/tests/qemublocktestdata/bitmapblockcommit/empty index bfc58f994e..9260011852 100644 --- a/tests/qemublocktestdata/bitmapblockcommit/empty +++ b/tests/qemublocktestdata/bitmapblockcommit/empty @@ -1,2 +1 @@ -pre job bitmap disable: merge bitmpas: -- 2.26.2

In the 'basic case we have few bitmaps in only the top layer. Simulate commit into the backing of the top layer and also 2 levels deep. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 4 + .../bitmapblockcommit/basic-1-2 | 145 ++++++++++++++++++ .../bitmapblockcommit/basic-1-3 | 145 ++++++++++++++++++ .../bitmapblockcommit/basic-2-3 | 1 + 4 files changed, 295 insertions(+) create mode 100644 tests/qemublocktestdata/bitmapblockcommit/basic-1-2 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/basic-1-3 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/basic-2-3 diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 5624c96d5f..d1148ec02e 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1365,6 +1365,10 @@ mymain(void) TEST_BITMAP_BLOCKCOMMIT("empty", 1, 2, "empty"); + TEST_BITMAP_BLOCKCOMMIT("basic-1-2", 1, 2, "basic"); + TEST_BITMAP_BLOCKCOMMIT("basic-1-3", 1, 3, "basic"); + TEST_BITMAP_BLOCKCOMMIT("basic-2-3", 2, 3, "basic"); + cleanup: qemuTestDriverFree(&driver); VIR_FREE(capslatest_x86_64); diff --git a/tests/qemublocktestdata/bitmapblockcommit/basic-1-2 b/tests/qemublocktestdata/bitmapblockcommit/basic-1-2 new file mode 100644 index 0000000000..eeca383dec --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/basic-1-2 @@ -0,0 +1,145 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-2-format", + "name": "current", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-2-format", + "target": "current", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-2-format", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-2-format", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "d" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-2-format", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-2-format", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "c" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-2-format", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-2-format", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "b" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-2-format", + "name": "a", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-2-format", + "target": "a", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "a" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-2-format", + "name": "libvirt-tmp-activewrite" + } + } +] diff --git a/tests/qemublocktestdata/bitmapblockcommit/basic-1-3 b/tests/qemublocktestdata/bitmapblockcommit/basic-1-3 new file mode 100644 index 0000000000..3db21cb465 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/basic-1-3 @@ -0,0 +1,145 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-3-format", + "name": "current", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-3-format", + "target": "current", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + }, + { + "node": "libvirt-3-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-3-format", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-3-format", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "d" + }, + { + "node": "libvirt-3-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-3-format", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-3-format", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "c" + }, + { + "node": "libvirt-3-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-3-format", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-3-format", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "b" + }, + { + "node": "libvirt-3-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-3-format", + "name": "a", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-3-format", + "target": "a", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "a" + }, + { + "node": "libvirt-3-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-3-format", + "name": "libvirt-tmp-activewrite" + } + } +] diff --git a/tests/qemublocktestdata/bitmapblockcommit/basic-2-3 b/tests/qemublocktestdata/bitmapblockcommit/basic-2-3 new file mode 100644 index 0000000000..9260011852 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/basic-2-3 @@ -0,0 +1 @@ +merge bitmpas: -- 2.26.2

Simulate commit between all the combinations of layers in the 'snapshots' case to see whether the code merges the correct bitmaps with the correct depth of temporary bitmaps. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 14 ++ .../bitmapblockcommit/snapshots-1-2 | 37 +++++ .../bitmapblockcommit/snapshots-1-3 | 70 +++++++++ .../bitmapblockcommit/snapshots-1-4 | 141 ++++++++++++++++++ .../bitmapblockcommit/snapshots-1-5 | 141 ++++++++++++++++++ .../bitmapblockcommit/snapshots-2-3 | 26 ++++ .../bitmapblockcommit/snapshots-2-4 | 82 ++++++++++ .../bitmapblockcommit/snapshots-2-5 | 82 ++++++++++ .../bitmapblockcommit/snapshots-3-4 | 49 ++++++ .../bitmapblockcommit/snapshots-3-5 | 49 ++++++ .../bitmapblockcommit/snapshots-4-5 | 1 + 11 files changed, 692 insertions(+) create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5 create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5 diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index d1148ec02e..8706f1a5ec 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1369,6 +1369,20 @@ mymain(void) TEST_BITMAP_BLOCKCOMMIT("basic-1-3", 1, 3, "basic"); TEST_BITMAP_BLOCKCOMMIT("basic-2-3", 2, 3, "basic"); + TEST_BITMAP_BLOCKCOMMIT("snapshots-1-2", 1, 2, "snapshots"); + TEST_BITMAP_BLOCKCOMMIT("snapshots-1-3", 1, 3, "snapshots"); + TEST_BITMAP_BLOCKCOMMIT("snapshots-1-4", 1, 4, "snapshots"); + TEST_BITMAP_BLOCKCOMMIT("snapshots-1-5", 1, 5, "snapshots"); + + TEST_BITMAP_BLOCKCOMMIT("snapshots-2-3", 2, 3, "snapshots"); + TEST_BITMAP_BLOCKCOMMIT("snapshots-2-4", 2, 4, "snapshots"); + TEST_BITMAP_BLOCKCOMMIT("snapshots-2-5", 2, 5, "snapshots"); + + TEST_BITMAP_BLOCKCOMMIT("snapshots-3-4", 3, 4, "snapshots"); + TEST_BITMAP_BLOCKCOMMIT("snapshots-3-5", 3, 5, "snapshots"); + + TEST_BITMAP_BLOCKCOMMIT("snapshots-4-5", 4, 5, "snapshots"); + cleanup: qemuTestDriverFree(&driver); VIR_FREE(capslatest_x86_64); diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2 new file mode 100644 index 0000000000..70aa9608c7 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2 @@ -0,0 +1,37 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-2-format", + "name": "current", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-2-format", + "target": "current", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-2-format", + "name": "libvirt-tmp-activewrite" + } + } +] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3 new file mode 100644 index 0000000000..a223ef998e --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3 @@ -0,0 +1,70 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-3-format", + "name": "current", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-3-format", + "target": "current", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + }, + { + "node": "libvirt-3-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-3-format", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-3-format", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "d" + }, + { + "node": "libvirt-3-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-3-format", + "name": "libvirt-tmp-activewrite" + } + } +] +allocation bitmap: +libvirt-1-format diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4 new file mode 100644 index 0000000000..497dd093d1 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4 @@ -0,0 +1,141 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-4-format", + "name": "current", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-4-format", + "target": "current", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + }, + { + "node": "libvirt-4-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-4-format", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-4-format", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "d" + }, + { + "node": "libvirt-4-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-4-format", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-4-format", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "b" + }, + { + "node": "libvirt-4-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-4-format", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-4-format", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "c" + }, + { + "node": "libvirt-4-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-4-format", + "name": "libvirt-tmp-activewrite" + } + } +] +allocation bitmap: +libvirt-2-format +libvirt-1-format diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5 new file mode 100644 index 0000000000..301a814856 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5 @@ -0,0 +1,141 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-5-format", + "name": "current", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-5-format", + "target": "current", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + }, + { + "node": "libvirt-5-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-5-format", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-5-format", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "d" + }, + { + "node": "libvirt-5-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-5-format", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-5-format", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "b" + }, + { + "node": "libvirt-5-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-5-format", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-5-format", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "c" + }, + { + "node": "libvirt-5-format", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "libvirt-5-format", + "name": "libvirt-tmp-activewrite" + } + } +] +allocation bitmap: +libvirt-2-format +libvirt-1-format diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3 new file mode 100644 index 0000000000..e20c5aa2e9 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3 @@ -0,0 +1,26 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-3-format", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-3-format", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-2-format", + "name": "d" + } + ] + } + } +] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4 new file mode 100644 index 0000000000..73a86d2e5d --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4 @@ -0,0 +1,82 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-4-format", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-4-format", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-2-format", + "name": "d" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-4-format", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-4-format", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "b" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-4-format", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-4-format", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "c" + } + ] + } + } +] +allocation bitmap: +libvirt-2-format diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5 new file mode 100644 index 0000000000..9b68cca2c8 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5 @@ -0,0 +1,82 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-5-format", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-5-format", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-2-format", + "name": "d" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-5-format", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-5-format", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "b" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-5-format", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-5-format", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "c" + } + ] + } + } +] +allocation bitmap: +libvirt-2-format diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4 new file mode 100644 index 0000000000..237b659429 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4 @@ -0,0 +1,49 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-4-format", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-4-format", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-3-format", + "name": "b" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-4-format", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-4-format", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-3-format", + "name": "c" + } + ] + } + } +] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5 new file mode 100644 index 0000000000..827b26e36f --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5 @@ -0,0 +1,49 @@ +merge bitmpas: +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-5-format", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-5-format", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-3-format", + "name": "b" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "libvirt-5-format", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "libvirt-5-format", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-3-format", + "name": "c" + } + ] + } + } +] diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5 new file mode 100644 index 0000000000..9260011852 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5 @@ -0,0 +1 @@ +merge bitmpas: -- 2.26.2

New semantics of the bitmap handling don't need this. Remove the field and all uses of it including the status XML. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_blockjob.c | 44 ------------------- src/qemu/qemu_blockjob.h | 3 -- src/qemu/qemu_domain.c | 22 ---------- src/qemu/qemu_driver.c | 3 +- .../blockjob-blockdev-in.xml | 4 -- 5 files changed, 1 insertion(+), 75 deletions(-) diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index ef22bc60ab..801d88a9fb 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -85,11 +85,6 @@ qemuBlockJobDataDisposeJobdata(qemuBlockJobDataPtr job) virObjectUnref(job->data.backup.store); g_free(job->data.backup.bitmap); } - - if (job->type == QEMU_BLOCKJOB_TYPE_COMMIT || - job->type == QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT) { - virStringListFree(job->data.commit.disabledBitmapsBase); - } } @@ -291,7 +286,6 @@ qemuBlockJobDiskNewCommit(virDomainObjPtr vm, virStorageSourcePtr topparent, virStorageSourcePtr top, virStorageSourcePtr base, - char ***disabledBitmapsBase, bool delete_imgs, unsigned int jobflags) { @@ -317,7 +311,6 @@ qemuBlockJobDiskNewCommit(virDomainObjPtr vm, job->data.commit.top = top; job->data.commit.base = base; job->data.commit.deleteCommittedImages = delete_imgs; - job->data.commit.disabledBitmapsBase = g_steal_pointer(disabledBitmapsBase); job->jobflags = jobflags; if (qemuBlockJobRegister(job, vm, disk, true) < 0) @@ -1405,40 +1398,6 @@ qemuBlockJobProcessEventFailedActiveCommit(virQEMUDriverPtr driver, } -static void -qemuBlockJobProcessEventFailedCommitCommon(virDomainObjPtr vm, - qemuBlockJobDataPtr job, - qemuDomainAsyncJob asyncJob) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - g_autoptr(virJSONValue) actions = virJSONValueNewArray(); - char **disabledBitmaps = job->data.commit.disabledBitmapsBase; - - if (!disabledBitmaps || !*disabledBitmaps) - return; - - for (; *disabledBitmaps; disabledBitmaps++) { - qemuMonitorTransactionBitmapEnable(actions, - job->data.commit.base->nodeformat, - *disabledBitmaps); - } - - if (qemuBlockReopenReadWrite(vm, job->data.commit.base, asyncJob) < 0) - return; - - if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0) - return; - - qemuMonitorTransaction(priv->mon, &actions); - - if (qemuDomainObjExitMonitor(priv->driver, vm) < 0) - return; - - if (qemuBlockReopenReadOnly(vm, job->data.commit.base, asyncJob) < 0) - return; -} - - static void qemuBlockJobProcessEventConcludedCreate(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -1578,8 +1537,6 @@ qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job, case QEMU_BLOCKJOB_TYPE_COMMIT: if (success) qemuBlockJobProcessEventCompletedCommit(driver, vm, job, asyncJob); - else - qemuBlockJobProcessEventFailedCommitCommon(vm, job, asyncJob); break; case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT: @@ -1587,7 +1544,6 @@ qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job, qemuBlockJobProcessEventCompletedActiveCommit(driver, vm, job, asyncJob); } else { qemuBlockJobProcessEventFailedActiveCommit(driver, vm, job); - qemuBlockJobProcessEventFailedCommitCommon(vm, job, asyncJob); } break; diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h index 0b9da7dd5b..89747b30c0 100644 --- a/src/qemu/qemu_blockjob.h +++ b/src/qemu/qemu_blockjob.h @@ -89,8 +89,6 @@ struct _qemuBlockJobCommitData { virStorageSourcePtr top; virStorageSourcePtr base; bool deleteCommittedImages; - char **disabledBitmapsBase; /* a NULL-terminated list of bitmap names which - were disabled in @base for the commit job */ }; @@ -196,7 +194,6 @@ qemuBlockJobDiskNewCommit(virDomainObjPtr vm, virStorageSourcePtr topparent, virStorageSourcePtr top, virStorageSourcePtr base, - char ***disabledBitmapsBase, bool delete_imgs, unsigned int jobflags); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index bceeaf0342..e8ab42db70 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2634,7 +2634,6 @@ qemuDomainPrivateBlockJobFormatCommit(qemuBlockJobDataPtr job, virBufferPtr buf) { g_auto(virBuffer) disabledBitmapsBuf = VIR_BUFFER_INIT_CHILD(buf); - char **bitmaps = job->data.commit.disabledBitmapsBase; if (job->data.commit.base) virBufferAsprintf(buf, "<base node='%s'/>\n", job->data.commit.base->nodeformat); @@ -2648,9 +2647,6 @@ qemuDomainPrivateBlockJobFormatCommit(qemuBlockJobDataPtr job, if (job->data.commit.deleteCommittedImages) virBufferAddLit(buf, "<deleteCommittedImages/>\n"); - while (bitmaps && *bitmaps) - virBufferEscapeString(&disabledBitmapsBuf, "<bitmap name='%s'/>\n", *(bitmaps++)); - virXMLFormatElement(buf, "disabledBaseBitmaps", NULL, &disabledBitmapsBuf); } @@ -3277,9 +3273,6 @@ static int qemuDomainObjPrivateXMLParseBlockjobDataCommit(qemuBlockJobDataPtr job, xmlXPathContextPtr ctxt) { - g_autofree xmlNodePtr *nodes = NULL; - ssize_t nnodes; - if (job->type == QEMU_BLOCKJOB_TYPE_COMMIT) { qemuDomainObjPrivateXMLParseBlockjobNodename(job, "string(./topparent/@node)", @@ -3306,21 +3299,6 @@ qemuDomainObjPrivateXMLParseBlockjobDataCommit(qemuBlockJobDataPtr job, !job->data.commit.base) return -1; - if ((nnodes = virXPathNodeSet("./disabledBaseBitmaps/bitmap", ctxt, &nodes)) > 0) { - size_t i; - - job->data.commit.disabledBitmapsBase = g_new0(char *, nnodes + 1); - - for (i = 0; i < nnodes; i++) { - char *tmp; - - if (!(tmp = virXMLPropString(nodes[i], "name"))) - return -1; - - job->data.commit.disabledBitmapsBase[i] = g_steal_pointer(&tmp); - } - } - return 0; } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 98a60ec2e2..516be76b8f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -18441,7 +18441,6 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *nodebase = NULL; bool persistjob = false; bool blockdev = false; - VIR_AUTOSTRINGLIST bitmapDisableList = NULL; virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW | VIR_DOMAIN_BLOCK_COMMIT_ACTIVE | @@ -18606,7 +18605,7 @@ qemuDomainBlockCommit(virDomainPtr dom, } if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource, - baseSource, &bitmapDisableList, + baseSource, flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE, flags))) goto endjob; diff --git a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml index cc17a17ff4..ca6d110179 100644 --- a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml +++ b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml @@ -243,10 +243,6 @@ <base node='libvirt-19-format'/> <top node='libvirt-17-format'/> <deleteCommittedImages/> - <disabledBaseBitmaps> - <bitmap name='test'/> - <bitmap name='test1'/> - </disabledBaseBitmaps> </blockjob> <blockjob name='create-libvirt-1337-storage' type='create' state='running'> <create mode='storage'/> -- 2.26.2

Reuse qemuBlockGetBitmapMergeActions which allows to remove the ad-hoc implementatio of bitmap merging for block copy. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 116 +++------------------------------------ src/qemu/qemu_block.h | 3 +- src/qemu/qemu_blockjob.c | 45 +++++++++++++++ src/qemu/qemu_driver.c | 13 +++-- tests/qemublocktest.c | 12 +++- 5 files changed, 71 insertions(+), 118 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index fd3fe4c354..d46a631671 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3035,38 +3035,6 @@ qemuBlockBitmapChainIsValid(virStorageSourcePtr src, } -struct qemuBlockBitmapsHandleBlockcopyConcatData { - virHashTablePtr bitmaps_merge; - virJSONValuePtr actions; - const char *mirrornodeformat; - bool has_bitmaps; -}; - - -static int -qemuBlockBitmapsHandleBlockcopyConcatActions(void *payload, - const void *name, - void *opaque) -{ - struct qemuBlockBitmapsHandleBlockcopyConcatData *data = opaque; - virJSONValuePtr createactions = payload; - const char *bitmapname = name; - g_autoptr(virJSONValue) mergebitmaps = virHashSteal(data->bitmaps_merge, bitmapname); - - data->has_bitmaps = true; - - virJSONValueArrayConcat(data->actions, createactions); - - if (qemuMonitorTransactionBitmapMerge(data->actions, - data->mirrornodeformat, - bitmapname, - &mergebitmaps) < 0) - return -1; - - return 0; -} - - /** * qemuBlockBitmapsHandleBlockcopy: * @src: disk source @@ -3087,88 +3055,18 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src, virStorageSourcePtr mirror, virHashTablePtr blockNamedNodeData, bool shallow, - virJSONValuePtr *actions) + virJSONValuePtr *actions, + GSList **allocationbitmapnodes) { - g_autoptr(virHashTable) bitmaps = virHashNew(virJSONValueHashFree); - g_autoptr(virHashTable) bitmaps_merge = virHashNew(virJSONValueHashFree); - g_autoptr(virHashTable) bitmaps_skip = virHashNew(NULL); - g_autoptr(virJSONValue) tmpactions = virJSONValueNewArray(); - qemuBlockNamedNodeDataPtr entry; - virStorageSourcePtr n; - size_t i; - struct qemuBlockBitmapsHandleBlockcopyConcatData data = { .bitmaps_merge = bitmaps_merge, - .actions = tmpactions, - .mirrornodeformat = mirror->nodeformat, - .has_bitmaps = false, }; - - for (n = src; n; n = n->backingStore) { - if (!(entry = virHashLookup(blockNamedNodeData, n->nodeformat))) - continue; - - for (i = 0; i < entry->nbitmaps; i++) { - qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i]; - virJSONValuePtr bitmap_merge; - - if (virHashHasEntry(bitmaps_skip, bitmap->name)) - continue; - - if (!(bitmap_merge = virHashLookup(bitmaps_merge, bitmap->name))) { - g_autoptr(virJSONValue) tmp = NULL; - bool disabled = !bitmap->recording; - - /* disable any non top-layer bitmaps */ - if (n != src) - disabled = true; - - if (!bitmap->persistent || - !(qemuBlockBitmapChainIsValid(n, bitmap->name, - blockNamedNodeData))) { - ignore_value(virHashAddEntry(bitmaps_skip, bitmap->name, NULL)); - continue; - } - - /* prepare the data for adding the bitmap to the mirror */ - tmp = virJSONValueNewArray(); - - if (qemuMonitorTransactionBitmapAdd(tmp, - mirror->nodeformat, - bitmap->name, - true, - disabled, - bitmap->granularity) < 0) - return -1; - - if (virHashAddEntry(bitmaps, bitmap->name, tmp) < 0) - return -1; - - tmp = NULL; - - /* prepare array for merging all the bitmaps from the original chain */ - tmp = virJSONValueNewArray(); + virStorageSourcePtr base = NULL; - if (virHashAddEntry(bitmaps_merge, bitmap->name, tmp) < 0) - return -1; + if (shallow) + base = src->backingStore; - bitmap_merge = g_steal_pointer(&tmp); - } - - if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(bitmap_merge, - n->nodeformat, - bitmap->name) < 0) - return -1; - } - - if (shallow) - break; - } - - if (virHashForEach(bitmaps, qemuBlockBitmapsHandleBlockcopyConcatActions, - &data) < 0) + if (qemuBlockGetBitmapMergeActions(src, base, mirror, NULL, NULL, mirror, actions, + allocationbitmapnodes, blockNamedNodeData) < 0) return -1; - if (data.has_bitmaps) - *actions = g_steal_pointer(&tmpactions); - return 0; } diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 5d98f7ce6b..36091e44fa 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -242,7 +242,8 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src, virStorageSourcePtr mirror, virHashTablePtr blockNamedNodeData, bool shallow, - virJSONValuePtr *actions); + virJSONValuePtr *actions, + GSList **allocationbitmapnodes); int qemuBlockBitmapsHandleCommitFinish(virStorageSourcePtr topsrc, diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 801d88a9fb..126a808e20 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -1323,6 +1323,49 @@ qemuBlockJobProcessEventCompletedActiveCommit(virQEMUDriverPtr driver, } +static int +qemuBlockJobProcessEventCompletedCopyBitmaps(virDomainObjPtr vm, + qemuBlockJobDataPtr job, + qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + g_autoptr(virHashTable) blockNamedNodeData = NULL; + g_autoptr(virJSONValue) actions = NULL; + g_autoptr(GSList) allocationbitmapnodes = NULL; + bool shallow = job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW; + + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) + return 0; + + if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob))) + return -1; + + if (qemuBlockBitmapsHandleBlockcopy(job->disk->src, + job->disk->mirror, + blockNamedNodeData, + shallow, + &actions, + &allocationbitmapnodes) < 0) + return 0; + + if (!actions) + return 0; + + if (qemuBlockBitmapTemporaryAdd(vm, blockNamedNodeData, + &allocationbitmapnodes, asyncJob) < 0) + return -1; + + if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0) + return -1; + + qemuMonitorTransaction(priv->mon, &actions); + + if (qemuDomainObjExitMonitor(priv->driver, vm) < 0) + return -1; + + return 0; +} + static void qemuBlockJobProcessEventConcludedCopyPivot(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -1337,6 +1380,8 @@ qemuBlockJobProcessEventConcludedCopyPivot(virQEMUDriverPtr driver, !job->disk->mirror) return; + qemuBlockJobProcessEventCompletedCopyBitmaps(vm, job, asyncJob); + /* for shallow copy without reusing external image the user can either not * specify the backing chain in which case libvirt will open and use the * chain the user provided or not specify a chain in which case we'll diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 516be76b8f..8a677f925d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17274,14 +17274,15 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver, if (blockdev && !job->jobflagsmissing) { bool shallow = job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW; bool reuse = job->jobflags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT; - g_autoptr(virHashTable) blockNamedNodeData = NULL; - if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE))) - return -1; + actions = virJSONValueNewArray(); - if (qemuBlockBitmapsHandleBlockcopy(disk->src, disk->mirror, - blockNamedNodeData, - shallow, &actions) < 0) + if (qemuMonitorTransactionBitmapAdd(actions, + disk->mirror->nodeformat, + "libvirt-tmp-activewrite", + false, + false, + 0) < 0) return -1; /* Open and install the backing chain of 'mirror' late if we can use diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 8706f1a5ec..91796e96d8 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -885,6 +885,8 @@ testQemuBlockBitmapBlockcopy(const void *opaque) g_autoptr(virJSONValue) nodedatajson = NULL; g_autoptr(virHashTable) nodedata = NULL; g_autoptr(virStorageSource) fakemirror = virStorageSourceNew(); + g_autoptr(GSList) allocationbitmapnodes = NULL; + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; if (!fakemirror) return -1; @@ -904,13 +906,19 @@ testQemuBlockBitmapBlockcopy(const void *opaque) } if (qemuBlockBitmapsHandleBlockcopy(data->chain, fakemirror, nodedata, - data->shallow, &actions) < 0) + data->shallow, &actions, + &allocationbitmapnodes) < 0) return -1; + if (actions && - !(actual = virJSONValueToString(actions, true))) + virJSONValueToBuffer(actions, &buf, true) < 0) return -1; + testQemuBitmapListPrint("allocation bitmap:", allocationbitmapnodes, &buf); + + actual = virBufferContentAndReset(&buf); + return virTestCompareToFile(actual, expectpath); } -- 2.26.2

Test both 'basic' and 'snapshots' cases on shallow and deep copy modes. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 5 + .../bitmapblockcopy/basic-deep-out.json | 144 ++++++++++++++ .../bitmapblockcopy/basic-shallow-out.json | 144 ++++++++++++++ .../bitmapblockcopy/snapshots-deep-out.json | 185 ++++++++++++++++++ .../snapshots-shallow-out.json | 36 ++++ 5 files changed, 514 insertions(+) create mode 100644 tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json create mode 100644 tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json create mode 100644 tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json create mode 100644 tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 91796e96d8..8c3d1cfc47 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1357,6 +1357,11 @@ mymain(void) TEST_BITMAP_BLOCKCOPY("empty-shallow", true, "empty"); TEST_BITMAP_BLOCKCOPY("empty-deep", false, "empty"); + TEST_BITMAP_BLOCKCOPY("basic-shallow", true, "basic"); + TEST_BITMAP_BLOCKCOPY("basic-deep", false, "basic"); + + TEST_BITMAP_BLOCKCOPY("snapshots-shallow", true, "snapshots"); + TEST_BITMAP_BLOCKCOPY("snapshots-deep", false, "snapshots"); #define TEST_BITMAP_BLOCKCOMMIT(testname, topimg, baseimg, ndf) \ do {\ diff --git a/tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json b/tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json new file mode 100644 index 0000000000..95ee835d30 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json @@ -0,0 +1,144 @@ +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "current", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "current", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "d" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "c" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "b" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "a", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "a", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "a" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + } +] diff --git a/tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json b/tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json new file mode 100644 index 0000000000..95ee835d30 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json @@ -0,0 +1,144 @@ +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "current", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "current", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "d" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "c" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "b" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "a", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "a", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "a" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + } +] diff --git a/tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json b/tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json new file mode 100644 index 0000000000..cde0d0cbf5 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json @@ -0,0 +1,185 @@ +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "current", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "current", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "d", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "d", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "d" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "b", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "b", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "b" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "c", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "c", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "c" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "a", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "a", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-2-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-3-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-4-format", + "name": "libvirt-tmp-allocation" + }, + { + "node": "libvirt-5-format", + "name": "a" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + } +] +allocation bitmap: +libvirt-4-format +libvirt-3-format +libvirt-2-format +libvirt-1-format diff --git a/tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json b/tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json new file mode 100644 index 0000000000..5e812eeef2 --- /dev/null +++ b/tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json @@ -0,0 +1,36 @@ +[ + { + "type": "block-dirty-bitmap-add", + "data": { + "node": "mirror-format-node", + "name": "current", + "persistent": true, + "disabled": false, + "granularity": 65536 + } + }, + { + "type": "block-dirty-bitmap-merge", + "data": { + "node": "mirror-format-node", + "target": "current", + "bitmaps": [ + { + "node": "libvirt-1-format", + "name": "current" + }, + { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + ] + } + }, + { + "type": "block-dirty-bitmap-remove", + "data": { + "node": "mirror-format-node", + "name": "libvirt-tmp-activewrite" + } + } +] -- 2.26.2

On Tue, Jun 09, 2020 at 17:00:07 +0200, Peter Krempa wrote:
Use 'block-dirty-bitmap-populate' and change how we create bitmaps corresponding to checkpoints to simplify the code and also properly integrate with backing chain images created outside of libvirt.
This patchset changes how we approach checkpoints by keeping one bitmap per checkpoint and disk and not propagating the bitmaps into overlays on snapshots. This massively simplifies the code handling all the operations during blockjobs and backups.
While the change isn't compatible with checkpoints created previously, we didn't yet enable the support for checkpoints/backups.
Note that 'block-dirty-bitmap-populate' is _not_ in finished state in qemu yet, so I'm posting this as RFC and as reference for qemu developers of the usefulnes of it.
The changes can be fetched by:
git fetch https://gitlab.com/pipo.sk/libvirt.git checkpoint-bitmap-populate
Note that the above branch also contains a commit enabling incremental backup for simpler testing.
I've pushed the appropriate qemu patches for convenience here:
git fetch https://gitlab.com/pipo.sk/qemu.git block-dirty-bitmap-populate
I'll be posting a new version which doesn't require the 'block-dirty-bitmap-populate' blockjob at the beginning but still simplifies the internals and I'll then base the rest of this series on top of that once the qemu design is ready.
participants (2)
-
Eric Blake
-
Peter Krempa