mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
qemu: backup: Merge bitmaps accross the backing chain
To allow backups work across external snapshots we need to improve the algorithm which calculates which bitmaps to merge. The algorithm must look for appropriately named bitmaps in the image and possibly descend into a backing image if the current image does not have the bitmap. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
b7f2cd4652
commit
450888d96b
@ -173,24 +173,70 @@ qemuBackupDiskDataCleanup(virDomainObjPtr vm,
|
||||
virJSONValuePtr
|
||||
qemuBackupDiskPrepareOneBitmapsChain(virDomainMomentDefPtr *incremental,
|
||||
virStorageSourcePtr backingChain,
|
||||
virHashTablePtr blockNamedNodeData G_GNUC_UNUSED,
|
||||
const char *diskdst G_GNUC_UNUSED)
|
||||
virHashTablePtr blockNamedNodeData,
|
||||
const char *diskdst)
|
||||
{
|
||||
qemuBlockNamedNodeDataBitmapPtr bitmap;
|
||||
g_autoptr(virJSONValue) ret = NULL;
|
||||
size_t incridx = 0;
|
||||
|
||||
if (!(ret = virJSONValueNewArray()))
|
||||
return NULL;
|
||||
|
||||
/* TODO: this code works only if the bitmaps are present on a single node.
|
||||
* The algorithm needs to be changed so that it looks into the backing chain
|
||||
* so that we can combine all relevant bitmaps for a given backing chain */
|
||||
while (*incremental) {
|
||||
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;
|
||||
}
|
||||
|
||||
while (bitmap) {
|
||||
if (bitmap->inconsistent) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("bitmap '%s' for image '%s%u' is inconsistent"),
|
||||
bitmap->name, diskdst, backingChain->id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(ret,
|
||||
backingChain->nodeformat,
|
||||
(*incremental)->name) < 0)
|
||||
bitmap->name) < 0)
|
||||
return NULL;
|
||||
|
||||
incremental++;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return g_steal_pointer(&ret);
|
||||
|
Loading…
Reference in New Issue
Block a user