|
|
a41c76 |
From 628b1f392c5fb2e3a492640a9069edd244a7b150 Mon Sep 17 00:00:00 2001
|
|
|
a41c76 |
Message-Id: <628b1f392c5fb2e3a492640a9069edd244a7b150@dist-git>
|
|
|
a41c76 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
a41c76 |
Date: Tue, 4 Feb 2020 15:07:50 +0100
|
|
|
a41c76 |
Subject: [PATCH] qemu: checkpoint: split out checkpoint deletion bitmaps
|
|
|
a41c76 |
MIME-Version: 1.0
|
|
|
a41c76 |
Content-Type: text/plain; charset=UTF-8
|
|
|
a41c76 |
Content-Transfer-Encoding: 8bit
|
|
|
a41c76 |
|
|
|
a41c76 |
qemuCheckpointDiscard is a massive function that can be separated into
|
|
|
a41c76 |
smaller bits. Extract the part that actually modifies the disk from the
|
|
|
a41c76 |
metadata handling.
|
|
|
a41c76 |
|
|
|
a41c76 |
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
|
|
|
a41c76 |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
a41c76 |
(cherry picked from commit 44e1b85717b9a4e6df24f9cbf846627e4f29b859)
|
|
|
a41c76 |
|
|
|
a41c76 |
https://bugzilla.redhat.com/show_bug.cgi?id=1207659
|
|
|
a41c76 |
Message-Id: <b6cdc7883d1f3b16e8a496dac6e9ec046ec2c4ea.1580824112.git.pkrempa@redhat.com>
|
|
|
a41c76 |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
a41c76 |
---
|
|
|
a41c76 |
src/qemu/qemu_checkpoint.c | 137 ++++++++++++++++++++-----------------
|
|
|
a41c76 |
1 file changed, 76 insertions(+), 61 deletions(-)
|
|
|
a41c76 |
|
|
|
a41c76 |
diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
|
|
|
a41c76 |
index d13d4c2a37..9ff3129570 100644
|
|
|
a41c76 |
--- a/src/qemu/qemu_checkpoint.c
|
|
|
a41c76 |
+++ b/src/qemu/qemu_checkpoint.c
|
|
|
a41c76 |
@@ -104,6 +104,81 @@ qemuCheckpointWriteMetadata(virDomainObjPtr vm,
|
|
|
a41c76 |
}
|
|
|
a41c76 |
|
|
|
a41c76 |
|
|
|
a41c76 |
+static int
|
|
|
a41c76 |
+qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
|
|
|
a41c76 |
+ virDomainCheckpointDefPtr chkdef,
|
|
|
a41c76 |
+ bool chkcurrent,
|
|
|
a41c76 |
+ virDomainMomentObjPtr parent)
|
|
|
a41c76 |
+{
|
|
|
a41c76 |
+ qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
a41c76 |
+ virQEMUDriverPtr driver = priv->driver;
|
|
|
a41c76 |
+ virDomainMomentObjPtr moment;
|
|
|
a41c76 |
+ virDomainCheckpointDefPtr parentdef = NULL;
|
|
|
a41c76 |
+ bool search_parents;
|
|
|
a41c76 |
+ int rc;
|
|
|
a41c76 |
+ g_autoptr(virJSONValue) actions = NULL;
|
|
|
a41c76 |
+ size_t i;
|
|
|
a41c76 |
+ size_t j;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ if (!(actions = virJSONValueNewArray()))
|
|
|
a41c76 |
+ return -1;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ for (i = 0; i < chkdef->ndisks; i++) {
|
|
|
a41c76 |
+ virDomainCheckpointDiskDef *disk = &chkdef->disks[i];
|
|
|
a41c76 |
+ const char *node;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
|
|
|
a41c76 |
+ continue;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
|
|
|
a41c76 |
+ /* If any ancestor checkpoint has a bitmap for the same
|
|
|
a41c76 |
+ * disk, then this bitmap must be merged to the
|
|
|
a41c76 |
+ * ancestor. */
|
|
|
a41c76 |
+ search_parents = true;
|
|
|
a41c76 |
+ for (moment = parent;
|
|
|
a41c76 |
+ search_parents && moment;
|
|
|
a41c76 |
+ moment = virDomainCheckpointFindByName(vm->checkpoints,
|
|
|
a41c76 |
+ parentdef->parent.parent_name)) {
|
|
|
a41c76 |
+ parentdef = virDomainCheckpointObjGetDef(moment);
|
|
|
a41c76 |
+ for (j = 0; j < parentdef->ndisks; j++) {
|
|
|
a41c76 |
+ virDomainCheckpointDiskDef *disk2;
|
|
|
a41c76 |
+ g_autoptr(virJSONValue) arr = NULL;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ disk2 = &parentdef->disks[j];
|
|
|
a41c76 |
+ if (STRNEQ(disk->name, disk2->name) ||
|
|
|
a41c76 |
+ disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
|
|
|
a41c76 |
+ continue;
|
|
|
a41c76 |
+ search_parents = false;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ if (!(arr = virJSONValueNewArray()))
|
|
|
a41c76 |
+ return -1;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, disk->bitmap) < 0)
|
|
|
a41c76 |
+ return -1;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ if (chkcurrent) {
|
|
|
a41c76 |
+ if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
|
|
|
a41c76 |
+ return -1;
|
|
|
a41c76 |
+ }
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
|
|
|
a41c76 |
+ return -1;
|
|
|
a41c76 |
+ }
|
|
|
a41c76 |
+ }
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
|
|
|
a41c76 |
+ return -1;
|
|
|
a41c76 |
+ }
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ qemuDomainObjEnterMonitor(driver, vm);
|
|
|
a41c76 |
+ rc = qemuMonitorTransaction(priv->mon, &actions);
|
|
|
a41c76 |
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
|
|
|
a41c76 |
+ return -1;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ return 0;
|
|
|
a41c76 |
+}
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+
|
|
|
a41c76 |
static int
|
|
|
a41c76 |
qemuCheckpointDiscard(virQEMUDriverPtr driver,
|
|
|
a41c76 |
virDomainObjPtr vm,
|
|
|
a41c76 |
@@ -112,9 +187,6 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
|
|
|
a41c76 |
bool metadata_only)
|
|
|
a41c76 |
{
|
|
|
a41c76 |
virDomainMomentObjPtr parent = NULL;
|
|
|
a41c76 |
- virDomainMomentObjPtr moment;
|
|
|
a41c76 |
- virDomainCheckpointDefPtr parentdef = NULL;
|
|
|
a41c76 |
- size_t i, j;
|
|
|
a41c76 |
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
|
|
|
a41c76 |
g_autofree char *chkFile = NULL;
|
|
|
a41c76 |
bool chkcurrent = chk == virDomainCheckpointGetCurrent(vm->checkpoints);
|
|
|
a41c76 |
@@ -129,67 +201,10 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
|
|
|
a41c76 |
chk->def->name);
|
|
|
a41c76 |
|
|
|
a41c76 |
if (!metadata_only) {
|
|
|
a41c76 |
- qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
a41c76 |
- bool search_parents;
|
|
|
a41c76 |
virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk);
|
|
|
a41c76 |
- int rc;
|
|
|
a41c76 |
- g_autoptr(virJSONValue) actions = NULL;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- if (!(actions = virJSONValueNewArray()))
|
|
|
a41c76 |
- return -1;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
parent = virDomainCheckpointFindByName(vm->checkpoints,
|
|
|
a41c76 |
chk->def->parent_name);
|
|
|
a41c76 |
- for (i = 0; i < chkdef->ndisks; i++) {
|
|
|
a41c76 |
- virDomainCheckpointDiskDef *disk = &chkdef->disks[i];
|
|
|
a41c76 |
- const char *node;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
|
|
|
a41c76 |
- continue;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
|
|
|
a41c76 |
- /* If any ancestor checkpoint has a bitmap for the same
|
|
|
a41c76 |
- * disk, then this bitmap must be merged to the
|
|
|
a41c76 |
- * ancestor. */
|
|
|
a41c76 |
- search_parents = true;
|
|
|
a41c76 |
- for (moment = parent;
|
|
|
a41c76 |
- search_parents && moment;
|
|
|
a41c76 |
- moment = virDomainCheckpointFindByName(vm->checkpoints,
|
|
|
a41c76 |
- parentdef->parent.parent_name)) {
|
|
|
a41c76 |
- parentdef = virDomainCheckpointObjGetDef(moment);
|
|
|
a41c76 |
- for (j = 0; j < parentdef->ndisks; j++) {
|
|
|
a41c76 |
- virDomainCheckpointDiskDef *disk2;
|
|
|
a41c76 |
- g_autoptr(virJSONValue) arr = NULL;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- disk2 = &parentdef->disks[j];
|
|
|
a41c76 |
- if (STRNEQ(disk->name, disk2->name) ||
|
|
|
a41c76 |
- disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
|
|
|
a41c76 |
- continue;
|
|
|
a41c76 |
- search_parents = false;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- if (!(arr = virJSONValueNewArray()))
|
|
|
a41c76 |
- return -1;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, disk->bitmap) < 0)
|
|
|
a41c76 |
- return -1;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- if (chkcurrent) {
|
|
|
a41c76 |
- if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
|
|
|
a41c76 |
- return -1;
|
|
|
a41c76 |
- }
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
|
|
|
a41c76 |
- return -1;
|
|
|
a41c76 |
- }
|
|
|
a41c76 |
- }
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
|
|
|
a41c76 |
- return -1;
|
|
|
a41c76 |
- }
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- qemuDomainObjEnterMonitor(driver, vm);
|
|
|
a41c76 |
- rc = qemuMonitorTransaction(priv->mon, &actions);
|
|
|
a41c76 |
- if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
|
|
|
a41c76 |
+ if (qemuCheckpointDiscardBitmaps(vm, chkdef, chkcurrent, parent) < 0)
|
|
|
a41c76 |
return -1;
|
|
|
a41c76 |
}
|
|
|
a41c76 |
|
|
|
a41c76 |
--
|
|
|
a41c76 |
2.25.0
|
|
|
a41c76 |
|