]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemuBlockBitmapChainIsValid: Adjust to new semantics of bitmaps
authorPeter Krempa <pkrempa@redhat.com>
Tue, 21 Apr 2020 08:25:09 +0000 (10:25 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 22 Jun 2020 14:04:30 +0000 (16:04 +0200)
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>
src/qemu/qemu_block.c

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