]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: checkpoint: Track and relabel images for bitmap merging
authorPeter Krempa <pkrempa@redhat.com>
Thu, 9 Jan 2020 16:34:29 +0000 (17:34 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 4 Feb 2020 12:45:32 +0000 (13:45 +0100)
Allow qemu access to modify backing files in case when we want to delete
a checkpoint.

This patch adds tracking of which images need to be relabelled when
calculating the transaction, the code to relabel them and rollback.

To verify that stuff works we also output the list of images to relabel
into the test case output files in qemublocktest.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_checkpoint.c
src/qemu/qemu_checkpoint.h
tests/qemublocktest.c
tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json
tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json
tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json
tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json
tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json
tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json
tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json
tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json

index 55061bbf7653185e847e9c364cace6eae4b380d7..59b7f63fdc2582354d264620a1cdaf42a2c6d1e7 100644 (file)
@@ -155,7 +155,8 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
                                  const char *delbitmap,
                                  const char *parentbitmap,
                                  virJSONValuePtr actions,
-                                 const char *diskdst)
+                                 const char *diskdst,
+                                 GSList **reopenimages)
 {
     virStorageSourcePtr n = src;
 
@@ -235,6 +236,9 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
                                                srcbitmap->name) < 0)
             return -1;
 
+        if (n != src)
+            *reopenimages = g_slist_prepend(*reopenimages, n);
+
         n = n->backingStore;
     }
 
@@ -250,9 +254,12 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virQEMUDriverPtr driver = priv->driver;
     g_autoptr(virHashTable) blockNamedNodeData = NULL;
-    int rc;
+    int rc = -1;
     g_autoptr(virJSONValue) actions = NULL;
     size_t i;
+    g_autoptr(GSList) reopenimages = NULL;
+    g_autoptr(GSList) relabelimages = NULL;
+    GSList *next;
 
     if (!(actions = virJSONValueNewArray()))
         return -1;
@@ -284,16 +291,34 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
 
         if (qemuCheckpointDiscardDiskBitmaps(domdisk->src, blockNamedNodeData,
                                              chkdisk->bitmap, parentbitmap,
-                                             actions, domdisk->dst) < 0)
+                                             actions, domdisk->dst,
+                                             &reopenimages) < 0)
             return -1;
     }
 
+    /* label any non-top images for read-write access */
+    for (next = reopenimages; next; next = next->next) {
+        virStorageSourcePtr src = next->data;
+
+        if (qemuDomainStorageSourceAccessAllow(driver, vm, src, false, false) < 0)
+            goto relabel;
+
+        relabelimages = g_slist_prepend(relabelimages, src);
+    }
+
     qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorTransaction(priv->mon, &actions);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
         return -1;
 
-    return 0;
+ relabel:
+    for (next = relabelimages; next; next = next->next) {
+        virStorageSourcePtr src = next->data;
+
+        ignore_value(qemuDomainStorageSourceAccessAllow(driver, vm, src, true, false));
+    }
+
+    return rc;
 }
 
 
index 976b1eed0f6d22f58836819a66166eed0344a2d5..cf1e9e46cb25093f5ab935921ef2b3f0c6e2751a 100644 (file)
@@ -78,4 +78,5 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
                                  const char *delbitmap,
                                  const char *parentbitmap,
                                  virJSONValuePtr actions,
-                                 const char *diskdst);
+                                 const char *diskdst,
+                                 GSList **reopenimages);
index 8f290452062ff81c7959506eed397a61e7c95f91..f518b0e025353780ad4a34a2b2aa4fb133fde7a7 100644 (file)
@@ -721,6 +721,9 @@ testQemuCheckpointDeleteMerge(const void *opaque)
     g_autoptr(virJSONValue) actions = NULL;
     g_autoptr(virJSONValue) nodedatajson = NULL;
     g_autoptr(virHashTable) nodedata = NULL;
+    g_autoptr(GSList) reopenimages = NULL;
+    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+    GSList *tmp;
 
     expectpath = g_strdup_printf("%s/%s%s-out.json", abs_srcdir,
                                  checkpointDeletePrefix, data->name);
@@ -742,14 +745,26 @@ testQemuCheckpointDeleteMerge(const void *opaque)
                                          data->deletebitmap,
                                          data->parentbitmap,
                                          actions,
-                                         "testdisk") < 0) {
+                                         "testdisk",
+                                         &reopenimages) < 0) {
         VIR_TEST_VERBOSE("failed to generate checkpoint delete transaction\n");
         return -1;
     }
 
-    if (!(actual = virJSONValueToString(actions, true)))
+    if (virJSONValueToBuffer(actions, &buf, true) < 0)
         return -1;
 
+    if (reopenimages) {
+        virBufferAddLit(&buf, "reopen nodes:\n");
+
+        for (tmp = reopenimages; tmp; tmp = tmp->next) {
+            virStorageSourcePtr src = tmp->data;
+            virBufferAsprintf(&buf, "%s\n", src->nodeformat);
+        }
+    }
+
+    actual = virBufferContentAndReset(&buf);
+
     return virTestCompareToFile(actual, expectpath);
 }
 
index 4da21a9df71230df76d7b6a0e8e6963f7a310d1f..8a0e3f2cff8d9bbc050f026698c2671c26d227ad 100644 (file)
@@ -57,3 +57,6 @@
     }
   }
 ]
+reopen nodes:
+libvirt-3-format
+libvirt-2-format
index 45a84b47c24ca7cde95f72acb0ecdaf8008cfa8e..f750f44da2029eac82d3deb1936b1ab2b0fbb84f 100644 (file)
@@ -21,3 +21,7 @@
     }
   }
 ]
+reopen nodes:
+libvirt-5-format
+libvirt-4-format
+libvirt-3-format