diff --git a/libvirt-qemu_snapshot-refactor-qemuSnapshotDeleteExternalPrepare.patch b/libvirt-qemu_snapshot-refactor-qemuSnapshotDeleteExternalPrepare.patch new file mode 100644 index 0000000..8a632b8 --- /dev/null +++ b/libvirt-qemu_snapshot-refactor-qemuSnapshotDeleteExternalPrepare.patch @@ -0,0 +1,141 @@ +From 7289999ecc435bcc65881c64b49efba9746a9571 Mon Sep 17 00:00:00 2001 +Message-Id: <7289999ecc435bcc65881c64b49efba9746a9571@dist-git> +From: Pavel Hrdina +Date: Tue, 21 Feb 2023 16:52:28 +0100 +Subject: [PATCH] qemu_snapshot: refactor qemuSnapshotDeleteExternalPrepare + +When user creates external snapshot with making only memory snapshot +without any disks deleting that snapshot failed without reporting any +meaningful error. + +The issue is that the qemuSnapshotDeleteExternalPrepare function +returns NULL because the returned list is empty. This will not change +so to make it clear if the function fails or not return int instead and +have another parameter where we can pass the list. + +With the fixed memory snapshot deletion it will now correctly delete +memory only snapshot as well. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2170826 + +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +(cherry picked from commit e3957c22462bc52c37c94ca4d6fe3d26f8202119) +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_snapshot.c | 28 +++++++++++++++------------- + 1 file changed, 15 insertions(+), 13 deletions(-) + +diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c +index 5cdcbc6290..cfa531edef 100644 +--- a/src/qemu/qemu_snapshot.c ++++ b/src/qemu/qemu_snapshot.c +@@ -2301,9 +2301,10 @@ qemuSnapshotFindParentSnapForDisk(virDomainMomentObj *snap, + } + + +-static GSList* ++static int + qemuSnapshotDeleteExternalPrepare(virDomainObj *vm, +- virDomainMomentObj *snap) ++ virDomainMomentObj *snap, ++ GSList **externalData) + { + ssize_t i; + virDomainSnapshotDef *snapdef = virDomainSnapshotObjGetDef(snap); +@@ -2320,7 +2321,7 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm, + virReportError(VIR_ERR_OPERATION_INVALID, + _("snapshot disk '%s' was target of not completed snapshot delete"), + snapDisk->name); +- return NULL; ++ return -1; + } + + data = g_new0(qemuSnapshotDeleteExternalData, 1); +@@ -2328,18 +2329,18 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm, + + data->domDisk = qemuDomainDiskByName(vm->def, snapDisk->name); + if (!data->domDisk) +- return NULL; ++ return -1; + + data->diskSrc = virStorageSourceChainLookupBySource(data->domDisk->src, + data->snapDisk->src, + &data->prevDiskSrc); + if (!data->diskSrc) +- return NULL; ++ return -1; + + if (!virStorageSourceIsSameLocation(data->diskSrc, data->snapDisk->src)) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("VM disk source and snapshot disk source are not the same")); +- return NULL; ++ return -1; + } + + data->parentDomDisk = virDomainDiskByTarget(snapdef->parent.dom, +@@ -2348,7 +2349,7 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm, + virReportError(VIR_ERR_OPERATION_FAILED, + _("failed to find disk '%s' in snapshot VM XML"), + snapDisk->name); +- return NULL; ++ return -1; + } + + if (virDomainObjIsActive(vm)) { +@@ -2356,13 +2357,13 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm, + if (!virStorageSourceIsBacking(data->parentDiskSrc)) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("failed to find parent disk source in backing chain")); +- return NULL; ++ return -1; + } + + if (!virStorageSourceIsSameLocation(data->parentDiskSrc, data->parentDomDisk->src)) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("snapshot VM disk source and parent disk source are not the same")); +- return NULL; ++ return -1; + } + } + +@@ -2371,15 +2372,16 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm, + if (data->parentSnap && !virDomainSnapshotIsExternal(data->parentSnap)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("deleting external snapshot that has internal snapshot as parent not supported")); +- return NULL; ++ return -1; + } + + ret = g_slist_prepend(ret, g_steal_pointer(&data)); + } + + ret = g_slist_reverse(ret); ++ *externalData = g_steal_pointer(&ret); + +- return g_steal_pointer(&ret); ++ return 0; + } + + +@@ -3159,7 +3161,7 @@ qemuSnapshotDelete(virDomainObj *vm, + g_autoslist(qemuSnapshotDeleteExternalData) tmpData = NULL; + + /* this also serves as validation whether the snapshot can be deleted */ +- if (!(tmpData = qemuSnapshotDeleteExternalPrepare(vm, snap))) ++ if (qemuSnapshotDeleteExternalPrepare(vm, snap, &tmpData) < 0) + goto endjob; + + if (!virDomainObjIsActive(vm)) { +@@ -3174,7 +3176,7 @@ qemuSnapshotDelete(virDomainObj *vm, + + /* Call the prepare again as some data require that the VM is + * running to get everything we need. */ +- if (!(externalData = qemuSnapshotDeleteExternalPrepare(vm, snap))) ++ if (qemuSnapshotDeleteExternalPrepare(vm, snap, &externalData) < 0) + goto endjob; + } else { + qemuDomainJobPrivate *jobPriv = vm->job->privateData; +-- +2.39.1 + diff --git a/libvirt-qemu_snapshot-remove-memory-snapshot-when-deleting-external-snapshot.patch b/libvirt-qemu_snapshot-remove-memory-snapshot-when-deleting-external-snapshot.patch new file mode 100644 index 0000000..b7c8bd6 --- /dev/null +++ b/libvirt-qemu_snapshot-remove-memory-snapshot-when-deleting-external-snapshot.patch @@ -0,0 +1,73 @@ +From 3ef43d47b0a5a49b0896b1725476b4b6ec0629b0 Mon Sep 17 00:00:00 2001 +Message-Id: <3ef43d47b0a5a49b0896b1725476b4b6ec0629b0@dist-git> +From: Pavel Hrdina +Date: Tue, 21 Feb 2023 16:10:56 +0100 +Subject: [PATCH] qemu_snapshot: remove memory snapshot when deleting external + snapshot + +When deleting external snapshot we should remove the memory snapshot +file as well. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +(cherry picked from commit 356e227208ec66fff178b91ed4b1197c7e6cf974) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2170826 + +Signed-off-by: Pavel Hrdina +--- + src/qemu/qemu_snapshot.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c +index b8416808b3..5cdcbc6290 100644 +--- a/src/qemu/qemu_snapshot.c ++++ b/src/qemu/qemu_snapshot.c +@@ -2684,9 +2684,11 @@ qemuSnapshotSetInvalid(virDomainObj *vm, + + static int + qemuSnapshotDiscardExternal(virDomainObj *vm, ++ virDomainMomentObj *snap, + GSList *externalData) + { + GSList *cur = NULL; ++ virDomainSnapshotDef *snapdef = virDomainSnapshotObjGetDef(snap); + + for (cur = externalData; cur; cur = g_slist_next(cur)) { + qemuSnapshotDeleteExternalData *data = cur->data; +@@ -2756,6 +2758,14 @@ qemuSnapshotDiscardExternal(virDomainObj *vm, + goto error; + } + ++ if (snapdef->memory == VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL && ++ snapdef->memorysnapshotfile) { ++ if (unlink(snapdef->memorysnapshotfile) < 0) { ++ VIR_WARN("failed to remove memory snapshot '%s'", ++ snapdef->memorysnapshotfile); ++ } ++ } ++ + return 0; + + error: +@@ -2886,7 +2896,7 @@ qemuSnapshotDiscardImpl(virQEMUDriver *driver, + } + + if (virDomainSnapshotIsExternal(snap)) { +- if (qemuSnapshotDiscardExternal(vm, externalData) < 0) ++ if (qemuSnapshotDiscardExternal(vm, snap, externalData) < 0) + return -1; + } else { + if (qemuDomainSnapshotForEachQcow2(driver, def, snap, "-d", true) < 0) +@@ -2894,7 +2904,7 @@ qemuSnapshotDiscardImpl(virQEMUDriver *driver, + } + } else { + if (virDomainSnapshotIsExternal(snap)) { +- if (qemuSnapshotDiscardExternal(vm, externalData) < 0) ++ if (qemuSnapshotDiscardExternal(vm, snap, externalData) < 0) + return -1; + } else { + /* Similarly as internal snapshot creation we would use a regular job +-- +2.39.1 + diff --git a/libvirt.spec b/libvirt.spec index a0b745c..d80f56a 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -229,7 +229,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 9.0.0 -Release: 6%{?dist}%{?extra_release} +Release: 7%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -267,6 +267,8 @@ Patch26: libvirt-qemu_extdevice-Do-cleanup-host-only-for-VIR_DOMAIN_TPM_TYPE_EMU Patch27: libvirt-qemu-blockjob-Handle-pending-blockjob-state-only-when-we-need-it.patch Patch28: libvirt-rpc-client-Don-t-check-return-value-of-virNetMessageNew.patch Patch29: libvirt-rpc-Don-t-warn-about-max_client_requests-in-single-threaded-daemons.patch +Patch30: libvirt-qemu_snapshot-remove-memory-snapshot-when-deleting-external-snapshot.patch +Patch31: libvirt-qemu_snapshot-refactor-qemuSnapshotDeleteExternalPrepare.patch Requires: libvirt-daemon = %{version}-%{release} @@ -2357,6 +2359,10 @@ exit 0 %endif %changelog +* Wed Feb 22 2023 Jiri Denemark - 9.0.0-7 +- qemu_snapshot: remove memory snapshot when deleting external snapshot (rhbz#2170826) +- qemu_snapshot: refactor qemuSnapshotDeleteExternalPrepare (rhbz#2170826) + * Fri Feb 17 2023 Jiri Denemark - 9.0.0-6 - rpc: client: Don't check return value of virNetMessageNew (rhbz#2145188) - rpc: Don't warn about "max_client_requests" in single-threaded daemons (rhbz#2145188)