735c6b
From 7289999ecc435bcc65881c64b49efba9746a9571 Mon Sep 17 00:00:00 2001
735c6b
Message-Id: <7289999ecc435bcc65881c64b49efba9746a9571@dist-git>
735c6b
From: Pavel Hrdina <phrdina@redhat.com>
735c6b
Date: Tue, 21 Feb 2023 16:52:28 +0100
735c6b
Subject: [PATCH] qemu_snapshot: refactor qemuSnapshotDeleteExternalPrepare
735c6b
735c6b
When user creates external snapshot with making only memory snapshot
735c6b
without any disks deleting that snapshot failed without reporting any
735c6b
meaningful error.
735c6b
735c6b
The issue is that the qemuSnapshotDeleteExternalPrepare function
735c6b
returns NULL because the returned list is empty. This will not change
735c6b
so to make it clear if the function fails or not return int instead and
735c6b
have another parameter where we can pass the list.
735c6b
735c6b
With the fixed memory snapshot deletion it will now correctly delete
735c6b
memory only snapshot as well.
735c6b
735c6b
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2170826
735c6b
735c6b
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
735c6b
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
735c6b
(cherry picked from commit e3957c22462bc52c37c94ca4d6fe3d26f8202119)
735c6b
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
735c6b
---
735c6b
 src/qemu/qemu_snapshot.c | 28 +++++++++++++++-------------
735c6b
 1 file changed, 15 insertions(+), 13 deletions(-)
735c6b
735c6b
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
735c6b
index 5cdcbc6290..cfa531edef 100644
735c6b
--- a/src/qemu/qemu_snapshot.c
735c6b
+++ b/src/qemu/qemu_snapshot.c
735c6b
@@ -2301,9 +2301,10 @@ qemuSnapshotFindParentSnapForDisk(virDomainMomentObj *snap,
735c6b
 }
735c6b
 
735c6b
 
735c6b
-static GSList*
735c6b
+static int
735c6b
 qemuSnapshotDeleteExternalPrepare(virDomainObj *vm,
735c6b
-                                  virDomainMomentObj *snap)
735c6b
+                                  virDomainMomentObj *snap,
735c6b
+                                  GSList **externalData)
735c6b
 {
735c6b
     ssize_t i;
735c6b
     virDomainSnapshotDef *snapdef = virDomainSnapshotObjGetDef(snap);
735c6b
@@ -2320,7 +2321,7 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm,
735c6b
             virReportError(VIR_ERR_OPERATION_INVALID,
735c6b
                            _("snapshot disk '%s' was target of not completed snapshot delete"),
735c6b
                            snapDisk->name);
735c6b
-            return NULL;
735c6b
+            return -1;
735c6b
         }
735c6b
 
735c6b
         data = g_new0(qemuSnapshotDeleteExternalData, 1);
735c6b
@@ -2328,18 +2329,18 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm,
735c6b
 
735c6b
         data->domDisk = qemuDomainDiskByName(vm->def, snapDisk->name);
735c6b
         if (!data->domDisk)
735c6b
-            return NULL;
735c6b
+            return -1;
735c6b
 
735c6b
         data->diskSrc = virStorageSourceChainLookupBySource(data->domDisk->src,
735c6b
                                                             data->snapDisk->src,
735c6b
                                                             &data->prevDiskSrc);
735c6b
         if (!data->diskSrc)
735c6b
-            return NULL;
735c6b
+            return -1;
735c6b
 
735c6b
         if (!virStorageSourceIsSameLocation(data->diskSrc, data->snapDisk->src)) {
735c6b
             virReportError(VIR_ERR_OPERATION_FAILED, "%s",
735c6b
                            _("VM disk source and snapshot disk source are not the same"));
735c6b
-            return NULL;
735c6b
+            return -1;
735c6b
         }
735c6b
 
735c6b
         data->parentDomDisk = virDomainDiskByTarget(snapdef->parent.dom,
735c6b
@@ -2348,7 +2349,7 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm,
735c6b
             virReportError(VIR_ERR_OPERATION_FAILED,
735c6b
                            _("failed to find disk '%s' in snapshot VM XML"),
735c6b
                            snapDisk->name);
735c6b
-            return NULL;
735c6b
+            return -1;
735c6b
         }
735c6b
 
735c6b
         if (virDomainObjIsActive(vm)) {
735c6b
@@ -2356,13 +2357,13 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm,
735c6b
             if (!virStorageSourceIsBacking(data->parentDiskSrc)) {
735c6b
                 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
735c6b
                                _("failed to find parent disk source in backing chain"));
735c6b
-                return NULL;
735c6b
+                return -1;
735c6b
             }
735c6b
 
735c6b
             if (!virStorageSourceIsSameLocation(data->parentDiskSrc, data->parentDomDisk->src)) {
735c6b
                 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
735c6b
                                _("snapshot VM disk source and parent disk source are not the same"));
735c6b
-                return NULL;
735c6b
+                return -1;
735c6b
             }
735c6b
         }
735c6b
 
735c6b
@@ -2371,15 +2372,16 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm,
735c6b
         if (data->parentSnap && !virDomainSnapshotIsExternal(data->parentSnap)) {
735c6b
             virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
735c6b
                            _("deleting external snapshot that has internal snapshot as parent not supported"));
735c6b
-            return NULL;
735c6b
+            return -1;
735c6b
         }
735c6b
 
735c6b
         ret = g_slist_prepend(ret, g_steal_pointer(&data));
735c6b
     }
735c6b
 
735c6b
     ret = g_slist_reverse(ret);
735c6b
+    *externalData = g_steal_pointer(&ret;;
735c6b
 
735c6b
-    return g_steal_pointer(&ret;;
735c6b
+    return 0;
735c6b
 }
735c6b
 
735c6b
 
735c6b
@@ -3159,7 +3161,7 @@ qemuSnapshotDelete(virDomainObj *vm,
735c6b
             g_autoslist(qemuSnapshotDeleteExternalData) tmpData = NULL;
735c6b
 
735c6b
             /* this also serves as validation whether the snapshot can be deleted */
735c6b
-            if (!(tmpData = qemuSnapshotDeleteExternalPrepare(vm, snap)))
735c6b
+            if (qemuSnapshotDeleteExternalPrepare(vm, snap, &tmpData) < 0)
735c6b
                 goto endjob;
735c6b
 
735c6b
             if (!virDomainObjIsActive(vm)) {
735c6b
@@ -3174,7 +3176,7 @@ qemuSnapshotDelete(virDomainObj *vm,
735c6b
 
735c6b
                 /* Call the prepare again as some data require that the VM is
735c6b
                  * running to get everything we need. */
735c6b
-                if (!(externalData = qemuSnapshotDeleteExternalPrepare(vm, snap)))
735c6b
+                if (qemuSnapshotDeleteExternalPrepare(vm, snap, &externalData) < 0)
735c6b
                     goto endjob;
735c6b
             } else {
735c6b
                 qemuDomainJobPrivate *jobPriv = vm->job->privateData;
735c6b
-- 
735c6b
2.39.1
735c6b