mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
qemu: checkpoint: Fix rollback and access to unlocked 'vm' when deleting checkpoints
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@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
2eb7c68332
commit
cec4e32998
@ -130,11 +130,14 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
if (!metadata_only) {
|
if (!metadata_only) {
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
bool success = true;
|
|
||||||
bool search_parents;
|
bool search_parents;
|
||||||
virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk);
|
virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk);
|
||||||
|
int rc;
|
||||||
|
g_autoptr(virJSONValue) actions = NULL;
|
||||||
|
|
||||||
|
if (!(actions = virJSONValueNewArray()))
|
||||||
|
return -1;
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
|
||||||
parent = virDomainCheckpointFindByName(vm->checkpoints,
|
parent = virDomainCheckpointFindByName(vm->checkpoints,
|
||||||
chk->def->parent_name);
|
chk->def->parent_name);
|
||||||
for (i = 0; i < chkdef->ndisks; i++) {
|
for (i = 0; i < chkdef->ndisks; i++) {
|
||||||
@ -164,31 +167,29 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
|
|||||||
continue;
|
continue;
|
||||||
search_parents = false;
|
search_parents = false;
|
||||||
|
|
||||||
arr = virJSONValueNewArray();
|
if (!(arr = virJSONValueNewArray()))
|
||||||
if (!arr ||
|
return -1;
|
||||||
virJSONValueArrayAppendString(arr, disk->bitmap) < 0) {
|
|
||||||
success = false;
|
if (virJSONValueArrayAppendString(arr, disk->bitmap) < 0)
|
||||||
break;
|
return -1;
|
||||||
}
|
|
||||||
if (chk == virDomainCheckpointGetCurrent(vm->checkpoints) &&
|
if (chk == virDomainCheckpointGetCurrent(vm->checkpoints)) {
|
||||||
qemuMonitorEnableBitmap(priv->mon, node,
|
if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
|
||||||
disk2->bitmap) < 0) {
|
return -1;
|
||||||
success = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (qemuMonitorMergeBitmaps(priv->mon, node,
|
|
||||||
disk2->bitmap, &arr) < 0) {
|
|
||||||
success = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (qemuMonitorDeleteBitmap(priv->mon, node, disk->bitmap) < 0) {
|
|
||||||
success = false;
|
if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
|
||||||
break;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user