From d0dc4217142fda8ce8850a30b7d89a344bb55d5e Mon Sep 17 00:00:00 2001 Message-Id: From: Peter Krempa Date: Tue, 23 Jun 2020 12:23:35 +0200 Subject: [PATCH] qemu: backup: Split up code traversing checkpoint list looking for bitmaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Eric Blake (cherry picked from commit 562511afa6cef5948e6339596ba5954cb5ed0565) https://bugzilla.redhat.com/show_bug.cgi?id=1804593 Message-Id: Reviewed-by: Ján Tomko --- 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 5d18720f53..400b711f79 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -173,72 +173,83 @@ qemuBackupDiskDataCleanup(virDomainObjPtr vm, } +static int +qemuBackupGetBitmapMergeRange(virStorageSourcePtr from, + const char *bitmapname, + virJSONValuePtr *actions, + virStorageSourcePtr *to, + const char *diskdst, + virHashTablePtr blockNamedNodeData) +{ + g_autoptr(virJSONValue) act = 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(act, + 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(&act); + *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.27.0