qemuSnapshotCreate: Don't insert snapshot into list with VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA

Our approach to snapshots without metadata was to insert them to the
snapshot list and then later remove them from the list when the flag is
present.

This quirky logic was broken in a recent refactor of the snapshot code
causing that the snapshot stayed inserted in the snapshot list.

Recent refactor of the snapshot code didn't faithfully relocate this
logic to the new function.

Rather than attempting to restore the quirky logic of adding and then
removing the object, don't add the snapshot into the list at all when
the user doesn't want metadata.

We achieve this by creating a temporary 'virDomainMomentObj' wrapper
which is not inserted into the list and using that instead of calling
virDomainSnapshotAssignDef.

Fixes: 9bad0fb809
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2039131
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Peter Krempa 2022-01-11 10:28:45 +01:00
parent 6ba3334222
commit 164aba8c4a

View File

@ -1756,7 +1756,7 @@ qemuSnapshotCreate(virDomainObj *vm,
virQEMUDriverConfig *cfg, virQEMUDriverConfig *cfg,
unsigned int flags) unsigned int flags)
{ {
g_autoptr(virDomainMomentObj) tmpsnap = NULL;
virDomainMomentObj *snap = NULL; virDomainMomentObj *snap = NULL;
virDomainMomentObj *current = NULL; virDomainMomentObj *current = NULL;
virDomainSnapshotPtr ret = NULL; virDomainSnapshotPtr ret = NULL;
@ -1767,16 +1767,20 @@ qemuSnapshotCreate(virDomainObj *vm,
if (qemuSnapshotPrepare(vm, def, &flags) < 0) if (qemuSnapshotPrepare(vm, def, &flags) < 0)
return NULL; return NULL;
if (!(snap = virDomainSnapshotAssignDef(vm->snapshots, def))) if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA) {
return NULL; snap = tmpsnap = virDomainMomentObjNew();
snap->def = &def->parent;
} else {
if (!(snap = virDomainSnapshotAssignDef(vm->snapshots, def)))
return NULL;
if ((current = virDomainSnapshotGetCurrent(vm->snapshots))) {
snap->def->parent_name = g_strdup(current->def->name);
}
}
virObjectRef(def); virObjectRef(def);
current = virDomainSnapshotGetCurrent(vm->snapshots);
if (current) {
snap->def->parent_name = g_strdup(current->def->name);
}
/* actually do the snapshot */ /* actually do the snapshot */
if (virDomainObjIsActive(vm)) { if (virDomainObjIsActive(vm)) {
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY || if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY ||
@ -1804,7 +1808,7 @@ qemuSnapshotCreate(virDomainObj *vm,
} }
} }
if (!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) { if (!tmpsnap) {
qemuSnapshotSetCurrent(vm, snap); qemuSnapshotSetCurrent(vm, snap);
if (qemuSnapshotCreateWriteMetadata(vm, snap, driver, cfg) < 0) if (qemuSnapshotCreateWriteMetadata(vm, snap, driver, cfg) < 0)
@ -1818,7 +1822,8 @@ qemuSnapshotCreate(virDomainObj *vm,
return ret; return ret;
error: error:
virDomainSnapshotObjListRemove(vm->snapshots, snap); if (!tmpsnap)
virDomainSnapshotObjListRemove(vm->snapshots, snap);
return NULL; return NULL;
} }