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