mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
qemu: snapshot: Write metadata of previously-'current' snapshot on update
Whether a snapshot definition is considered 'current' or active is stored in the metadata XML libvirt writes when we create metadata. This means that if we are changing the 'current' snapshot we must re-write the metadata of the previously 'current' snapshot to update the field to prevent having multiple active snapshots. Unfortunately the snapshot creation code didn't do this properly, which resulted in the following error: error : qemuDomainSnapshotLoad:430 : internal error: Too many snapshots claiming to be current for domain snapshot-test being printed if libvirtd was terminated and restarted. Introduce qemuSnapshotSetCurrent which writes out the old snapshot's metadata when updating the current snapshot. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
926563dc3a
commit
5d8acaa8bc
@ -47,6 +47,36 @@
|
||||
VIR_LOG_INIT("qemu.qemu_snapshot");
|
||||
|
||||
|
||||
/**
|
||||
* qemuSnapshotSetCurrent: Set currently active snapshot
|
||||
*
|
||||
* @vm: domain object
|
||||
* @newcurrent: snapshot object to set as current/active
|
||||
*
|
||||
* Sets @newcurrent as the 'current' snapshot of @vm. This helper ensures that
|
||||
* the snapshot which was 'current' previously is updated.
|
||||
*/
|
||||
static void
|
||||
qemuSnapshotSetCurrent(virDomainObjPtr vm,
|
||||
virDomainMomentObjPtr newcurrent)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
virQEMUDriverPtr driver = priv->driver;
|
||||
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
|
||||
virDomainMomentObjPtr oldcurrent = virDomainSnapshotGetCurrent(vm->snapshots);
|
||||
|
||||
virDomainSnapshotSetCurrent(vm->snapshots, newcurrent);
|
||||
|
||||
/* we need to write out metadata for the old snapshot to update the
|
||||
* 'active' property */
|
||||
if (oldcurrent &&
|
||||
oldcurrent != newcurrent) {
|
||||
if (qemuDomainSnapshotWriteMetadata(vm, oldcurrent, driver->xmlopt, cfg->snapshotDir) < 0)
|
||||
VIR_WARN("failed to update old current snapshot");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Looks up snapshot object from VM and name */
|
||||
virDomainMomentObjPtr
|
||||
qemuSnapObjFromName(virDomainObjPtr vm,
|
||||
@ -1781,7 +1811,8 @@ qemuSnapshotCreateXML(virDomainPtr domain,
|
||||
endjob:
|
||||
if (snapshot && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
|
||||
if (update_current)
|
||||
virDomainSnapshotSetCurrent(vm->snapshots, snap);
|
||||
qemuSnapshotSetCurrent(vm, snap);
|
||||
|
||||
if (qemuDomainSnapshotWriteMetadata(vm, snap,
|
||||
driver->xmlopt,
|
||||
cfg->snapshotDir) < 0) {
|
||||
@ -2243,7 +2274,7 @@ qemuSnapshotRevert(virDomainObjPtr vm,
|
||||
|
||||
cleanup:
|
||||
if (ret == 0) {
|
||||
virDomainSnapshotSetCurrent(vm->snapshots, snap);
|
||||
qemuSnapshotSetCurrent(vm, snap);
|
||||
if (qemuDomainSnapshotWriteMetadata(vm, snap,
|
||||
driver->xmlopt,
|
||||
cfg->snapshotDir) < 0) {
|
||||
@ -2360,7 +2391,8 @@ qemuSnapshotDelete(virDomainObjPtr vm,
|
||||
if (rem.err < 0)
|
||||
goto endjob;
|
||||
if (rem.found) {
|
||||
virDomainSnapshotSetCurrent(vm->snapshots, snap);
|
||||
qemuSnapshotSetCurrent(vm, snap);
|
||||
|
||||
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
|
||||
if (qemuDomainSnapshotWriteMetadata(vm, snap,
|
||||
driver->xmlopt,
|
||||
|
Loading…
Reference in New Issue
Block a user