258 lines
10 KiB
Diff
258 lines
10 KiB
Diff
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
|
|
--- a/src/qemu/qemu_checkpoint.c
|
|
+++ b/src/qemu/qemu_checkpoint.c
|
|
@@ -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
|
|
--- a/src/qemu/qemu_checkpoint.h
|
|
+++ b/src/qemu/qemu_checkpoint.h
|
|
@@ -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
|
|
--- a/tests/qemublocktest.c
|
|
+++ b/tests/qemublocktest.c
|
|
@@ -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
|
|
--- a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json
|
|
+++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json
|
|
@@ -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
|
|
--- a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json
|
|
+++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json
|
|
@@ -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
|
|
--- a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json
|
|
+++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json
|
|
@@ -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
|
|
--- a/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json
|
|
+++ b/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json
|
|
@@ -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
|
|
--- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json
|
|
+++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json
|
|
@@ -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
|
|
--- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json
|
|
+++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json
|
|
@@ -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
|
|
--- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json
|
|
+++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json
|
|
@@ -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
|
|
--- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json
|
|
+++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json
|
|
@@ -21,3 +21,7 @@
|
|
}
|
|
}
|
|
]
|
|
+reopen nodes:
|
|
+libvirt-5-format
|
|
+libvirt-4-format
|
|
+libvirt-3-format
|
|
--
|
|
2.25.0
|
|
|