qemuBlockBitmapChainIsValid: Adjust to new semantics of bitmaps

Reject duplicates and other problematic bitmaps according to the new
semantics of bitmap use in libvirt.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Peter Krempa 2020-04-21 10:25:09 +02:00
parent ff00fa228d
commit 3857b073cb

View File

@ -2850,41 +2850,49 @@ qemuBlockGetNamedNodeData(virDomainObjPtr vm,
/** /**
* qemuBlockBitmapChainIsValid: * qemuBlockBitmapChainIsValid:
* *
* Validates that the backing chain of @src contains proper consistent bitmap * Validates that the backing chain of @src contains bitmaps which libvirt will
* data for a chain of bitmaps named @bitmapname. * consider as properly corresponding to a checkpoint named @bitmapname.
* *
* A valid chain: * The bitmaps need to:
* 1) bitmaps of same name are in a consecutive subset of images without gap * 1) start from the top image @src
* 2) don't have any inconsistent bitmaps * 2) must be present in consecutive layers
* 3) all must be active, persistent and not inconsistent
*/ */
bool bool
qemuBlockBitmapChainIsValid(virStorageSourcePtr src, qemuBlockBitmapChainIsValid(virStorageSourcePtr src,
const char *bitmapname, const char *bitmapname,
virHashTablePtr blockNamedNodeData) virHashTablePtr blockNamedNodeData)
{ {
qemuBlockNamedNodeDataBitmapPtr bitmap;
virStorageSourcePtr n; virStorageSourcePtr n;
bool chain_started = false; bool found = false;
bool chain_ended = false; bool chain_ended = false;
for (n = src; n; n = n->backingStore) { for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) {
if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, n, bitmapname))) { qemuBlockNamedNodeDataBitmapPtr bitmap;
if (chain_started)
chain_ended = true; if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData,
n, bitmapname))) {
/* rule 1, must start from top */
if (!found)
return false;
chain_ended = true;
continue; continue;
} }
/* rule 2, no-gaps */
if (chain_ended) if (chain_ended)
return false; return false;
chain_started = true; /* rule 3 */
if (bitmap->inconsistent || !bitmap->persistent || !bitmap->recording)
if (bitmap->inconsistent)
return false; return false;
found = true;
} }
return chain_started; return found;
} }