[RFC PATCH 05/41] qemu: backup: Fix backup of disk skipped in an intermediate checkpoint

Peter Krempa pkrempa at redhat.com
Tue Jun 9 15:00:12 UTC 2020


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 at 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




More information about the libvir-list mailing list