qemu: backup: Split up code traversing checkpoint list looking for bitmaps

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>
Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Peter Krempa 2020-04-28 15:03:11 +02:00
parent f57a8cd3df
commit 562511afa6

View File

@ -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 virJSONValuePtr
qemuBackupDiskPrepareOneBitmapsChain(virDomainMomentDefPtr *incremental, qemuBackupDiskPrepareOneBitmapsChain(virDomainMomentDefPtr *incremental,
virStorageSourcePtr backingChain, virStorageSourcePtr backingChain,
virHashTablePtr blockNamedNodeData, virHashTablePtr blockNamedNodeData,
const char *diskdst) const char *diskdst)
{ {
qemuBlockNamedNodeDataBitmapPtr bitmap;
g_autoptr(virJSONValue) ret = NULL; g_autoptr(virJSONValue) ret = NULL;
size_t incridx = 0; size_t incridx = 0;
virStorageSourcePtr n = backingChain;
ret = virJSONValueNewArray(); ret = virJSONValueNewArray();
if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, for (incridx = 0; incremental[incridx]; incridx++) {
backingChain, g_autoptr(virJSONValue) tmp = virJSONValueNewArray();
incremental[0]->name))) { virStorageSourcePtr tmpsrc = NULL;
virReportError(VIR_ERR_INVALID_ARG,
_("failed to find bitmap '%s' in image '%s%u'"),
incremental[0]->name, diskdst, backingChain->id);
return NULL;
}
while (bitmap) { if (qemuBackupGetBitmapMergeRange(n, incremental[incridx]->name,
if (bitmap->inconsistent) { &tmp, &tmpsrc, diskdst,
virReportError(VIR_ERR_INVALID_ARG, blockNamedNodeData) < 0)
_("bitmap '%s' for image '%s%u' is inconsistent"),
bitmap->name, diskdst, backingChain->id);
return NULL;
}
if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(ret,
backingChain->nodeformat,
bitmap->name) < 0)
return NULL; return NULL;
if (backingChain->backingStore && if (virJSONValueArrayConcat(ret, tmp) < 0)
(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; return NULL;
} else {
break; n = tmpsrc;
}
} }
return g_steal_pointer(&ret); return g_steal_pointer(&ret);