]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemuSnapshotRevertActive: Remove transient domain on failure
authorPeter Krempa <pkrempa@redhat.com>
Thu, 15 May 2025 06:21:49 +0000 (08:21 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 16 May 2025 12:48:20 +0000 (14:48 +0200)
Code paths which deal with stopping of the qemu process need extra
handling for transient definitions as they need to be removed from the
domain list when we'd be leaving them inactive.

In case of snapshot code it's on failure to revert a snapshot as we stop
the qemu process but the failure to revert may mean that the new process
will not be started.

I've observed this when I was fixing the recent bug in snapshot
reversion which left the domain in unusable state after failure to
revert:

 $ virsh list foo
 error: Requested operation is not valid: domain is not running

 $ virsh undefine foo
 error: Requested operation is not valid: cannot undefine transient domain

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_snapshot.c

index f9b18f94b678300e82515fc2172b6070ada3c7a0..6926d1a0e4593fb61b76b510b782e94d03401715 100644 (file)
@@ -2628,13 +2628,12 @@ qemuSnapshotRevertActive(virDomainObj *vm,
 
     if (virDomainSnapshotIsExternal(snap)) {
         if (!(tmpsnapdef = virDomainSnapshotDefNew()))
-            return -1;
+            goto error;
 
         if (qemuSnapshotRevertExternalPrepare(vm, tmpsnapdef, snap,
                                               *config, *inactiveConfig,
-                                              &memdata) < 0) {
-            return -1;
-        }
+                                              &memdata) < 0)
+            goto error;
     } else {
         loadSnap = snap;
     }
@@ -2656,7 +2655,7 @@ qemuSnapshotRevertActive(virDomainObj *vm,
                             VIR_ASYNC_JOB_SNAPSHOT,
                             VIR_QEMU_PROCESS_STOP_MIGRATED);
         }
-        return -1;
+        goto error;
     }
 
     detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;
@@ -2667,7 +2666,7 @@ qemuSnapshotRevertActive(virDomainObj *vm,
 
     if (virDomainSnapshotIsExternal(snap)) {
         if (qemuSnapshotRevertExternalActive(vm, tmpsnapdef) < 0)
-            return -1;
+            goto error;
 
         qemuSnapshotRevertExternalFinish(vm, tmpsnapdef, snap);
     }
@@ -2689,16 +2688,22 @@ qemuSnapshotRevertActive(virDomainObj *vm,
         if (!virDomainObjIsActive(vm)) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("guest unexpectedly quit"));
-            return -1;
+            goto error;
         }
         rc = qemuProcessStartCPUs(driver, vm,
                                   VIR_DOMAIN_RUNNING_FROM_SNAPSHOT,
                                   VIR_ASYNC_JOB_SNAPSHOT);
         if (rc < 0)
-            return -1;
+            goto error;
     }
 
     return qemuSnapshotRevertWriteMetadata(vm, snap, driver, cfg, defined);
+
+ error:
+    if (!virDomainObjIsActive(vm))
+        qemuDomainRemoveInactive(driver, vm, 0, false);
+
+    return -1;
 }