| From eee9a7173898212632d42ef74777d6726ce29d5f Mon Sep 17 00:00:00 2001 |
| Message-Id: <eee9a7173898212632d42ef74777d6726ce29d5f@dist-git> |
| From: Peter Krempa <pkrempa@redhat.com> |
| Date: Tue, 4 Feb 2020 15:08:15 +0100 |
| Subject: [PATCH] qemu: checkpoint: Track and relabel images for bitmap merging |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| 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> |
| (cherry picked from commit 8e94e290104ffb5d9db051ab0b0ff36f58dbc943) |
| |
| https://bugzilla.redhat.com/show_bug.cgi?id=1207659 |
| Message-Id: <36c2dc7f5d0d59aac90b2e272983f72476b00661.1580824112.git.pkrempa@redhat.com> |
| Reviewed-by: Ján Tomko <jtomko@redhat.com> |
| |
| src/qemu/qemu_checkpoint.c | 35 ++++++++++++++++--- |
| src/qemu/qemu_checkpoint.h | 3 +- |
| tests/qemublocktest.c | 19 ++++++++-- |
| .../snapshots-intermediate1-out.json | 2 ++ |
| .../snapshots-intermediate2-out.json | 3 ++ |
| .../snapshots-intermediate3-out.json | 2 ++ |
| .../snapshots-noparent-out.json | 4 +++ |
| ...ynthetic-checkpoint-intermediate1-out.json | 2 ++ |
| ...ynthetic-checkpoint-intermediate2-out.json | 2 ++ |
| ...ynthetic-checkpoint-intermediate3-out.json | 2 ++ |
| ...ots-synthetic-checkpoint-noparent-out.json | 4 +++ |
| 11 files changed, 70 insertions(+), 8 deletions(-) |
| |
| diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c |
| index 55061bbf76..59b7f63fdc 100644 |
| |
| |
| @@ -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; |
| } |
| |
| |
| diff --git a/src/qemu/qemu_checkpoint.h b/src/qemu/qemu_checkpoint.h |
| index 976b1eed0f..cf1e9e46cb 100644 |
| |
| |
| @@ -78,4 +78,5 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src, |
| const char *delbitmap, |
| const char *parentbitmap, |
| virJSONValuePtr actions, |
| - const char *diskdst); |
| + const char *diskdst, |
| + GSList **reopenimages); |
| diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c |
| index 2e5927f3c1..ed8b061e2e 100644 |
| |
| |
| @@ -717,6 +717,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); |
| @@ -738,14 +741,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); |
| } |
| |
| diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json |
| index 29fefeea63..c9bda3a17a 100644 |
| |
| |
| @@ -20,3 +20,5 @@ |
| } |
| } |
| ] |
| +reopen nodes: |
| +libvirt-3-format |
| diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json |
| index 4da21a9df7..8a0e3f2cff 100644 |
| |
| |
| @@ -57,3 +57,6 @@ |
| } |
| } |
| ] |
| +reopen nodes: |
| +libvirt-3-format |
| +libvirt-2-format |
| diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json |
| index dc87dd60b8..211bc40baf 100644 |
| |
| |
| @@ -57,3 +57,5 @@ |
| } |
| } |
| ] |
| +reopen nodes: |
| +libvirt-2-format |
| diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json |
| index 45a84b47c2..f750f44da2 100644 |
| |
| |
| @@ -21,3 +21,7 @@ |
| } |
| } |
| ] |
| +reopen nodes: |
| +libvirt-5-format |
| +libvirt-4-format |
| +libvirt-3-format |
| diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json |
| index e979691e6f..d7e6d18637 100644 |
| |
| |
| @@ -27,3 +27,5 @@ |
| } |
| } |
| ] |
| +reopen nodes: |
| +libvirt-3-format |
| diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json |
| index e82098918a..cfbff010c2 100644 |
| |
| |
| @@ -30,3 +30,5 @@ |
| } |
| } |
| ] |
| +reopen nodes: |
| +libvirt-2-format |
| diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json |
| index dc87dd60b8..211bc40baf 100644 |
| |
| |
| @@ -57,3 +57,5 @@ |
| } |
| } |
| ] |
| +reopen nodes: |
| +libvirt-2-format |
| diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json |
| index 45a84b47c2..f750f44da2 100644 |
| |
| |
| @@ -21,3 +21,7 @@ |
| } |
| } |
| ] |
| +reopen nodes: |
| +libvirt-5-format |
| +libvirt-4-format |
| +libvirt-3-format |
| -- |
| 2.25.0 |
| |