mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-11-08 14:29:56 +00:00
snapshot: Don't hose list on deletion failure
If qemuDomainSnapshotDiscard() fails for any reason (rare, but possible with an ill-timed ENOMEM or if qemuDomainSnapshotForEachQcow2() has problems talking to the qemu guest monitor), then an attempt to retry the snapshot deletion API will crash because we didn't undo the effects of virDomainSnapshotDropParent() temporarily rearranging the internal list structures, and the second attempt to drop parents will dereference NULL. Fix it by instead noting that there are only two callers to qemuDomainSnapshotDiscard(), and only one of the two callers wants the parent to be updated; thus we can move the call to virDomainSnapshotDropParent() into a code path that only gets executed on success. Signed-off-by: Eric Blake <eblake@redhat.com> ACKed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
2569ba1338
commit
68b2596f83
@ -8249,7 +8249,7 @@ int
|
|||||||
qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
|
qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainSnapshotObjPtr snap,
|
virDomainSnapshotObjPtr snap,
|
||||||
bool update_current,
|
bool update_parent,
|
||||||
bool metadata_only)
|
bool metadata_only)
|
||||||
{
|
{
|
||||||
char *snapFile = NULL;
|
char *snapFile = NULL;
|
||||||
@ -8278,7 +8278,7 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (snap == vm->current_snapshot) {
|
if (snap == vm->current_snapshot) {
|
||||||
if (update_current && snap->def->parent) {
|
if (update_parent && snap->def->parent) {
|
||||||
parentsnap = virDomainSnapshotFindByName(vm->snapshots,
|
parentsnap = virDomainSnapshotFindByName(vm->snapshots,
|
||||||
snap->def->parent);
|
snap->def->parent);
|
||||||
if (!parentsnap) {
|
if (!parentsnap) {
|
||||||
@ -8301,6 +8301,8 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
if (unlink(snapFile) < 0)
|
if (unlink(snapFile) < 0)
|
||||||
VIR_WARN("Failed to unlink %s", snapFile);
|
VIR_WARN("Failed to unlink %s", snapFile);
|
||||||
|
if (update_parent)
|
||||||
|
virDomainSnapshotDropParent(snap);
|
||||||
virDomainSnapshotObjListRemove(vm->snapshots, snap);
|
virDomainSnapshotObjListRemove(vm->snapshots, snap);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -16526,7 +16526,6 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
|
|||||||
snap->first_child = NULL;
|
snap->first_child = NULL;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else {
|
} else {
|
||||||
virDomainSnapshotDropParent(snap);
|
|
||||||
ret = qemuDomainSnapshotDiscard(driver, vm, snap, true, metadata_only);
|
ret = qemuDomainSnapshotDiscard(driver, vm, snap, true, metadata_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user