Delete/merge bitmaps when deleting checkpoints using a 'transaction' so
that we don't have to deal with halfway-failed scenarios and also fix
access to 'vm' while in the monitor lock.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_checkpoint.c | 47 +++++++++++++++++++-------------------
1 file changed, 24 insertions(+), 23 deletions(-)
diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
index 4b4ad8bb83..a225f04831 100644
--- a/src/qemu/qemu_checkpoint.c
+++ b/src/qemu/qemu_checkpoint.c
@@ -133,11 +133,14 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
if (!metadata_only) {
qemuDomainObjPrivatePtr priv = vm->privateData;
- bool success = true;
bool search_parents;
virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk);
+ int rc;
+ g_autoptr(virJSONValue) actions = NULL;
+
+ if (!(actions = virJSONValueNewArray()))
+ return -1;
- qemuDomainObjEnterMonitor(driver, vm);
parent = virDomainCheckpointFindByName(vm->checkpoints,
chk->def->parent_name);
for (i = 0; i < chkdef->ndisks; i++) {
@@ -167,31 +170,29 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
continue;
search_parents = false;
- arr = virJSONValueNewArray();
- if (!arr ||
- virJSONValueArrayAppendString(arr, disk->bitmap) < 0) {
- success = false;
- break;
- }
- if (chk == virDomainCheckpointGetCurrent(vm->checkpoints)
&&
- qemuMonitorEnableBitmap(priv->mon, node,
- disk2->bitmap) < 0) {
- success = false;
- break;
- }
- if (qemuMonitorMergeBitmaps(priv->mon, node,
- disk2->bitmap, &arr) < 0) {
- success = false;
- break;
+ if (!(arr = virJSONValueNewArray()))
+ return -1;
+
+ if (virJSONValueArrayAppendString(arr, disk->bitmap) < 0)
+ return -1;
+
+ if (chk == virDomainCheckpointGetCurrent(vm->checkpoints)) {
+ if (qemuMonitorTransactionBitmapEnable(actions, node,
disk2->bitmap) < 0)
+ return -1;
}
+
+ if (qemuMonitorTransactionBitmapMerge(actions, node,
disk2->bitmap, &arr) < 0)
+ return -1;
}
}
- if (qemuMonitorDeleteBitmap(priv->mon, node, disk->bitmap) < 0) {
- success = false;
- break;
- }
+
+ if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) <
0)
+ return -1;
}
- if (qemuDomainObjExitMonitor(driver, vm) < 0 || !success)
+
+ qemuDomainObjEnterMonitor(driver, vm);
+ rc = qemuMonitorTransaction(priv->mon, &actions);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
return -1;
}
--
2.21.0