]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu_snapshot: error out when deleting internal snapshot on non-active disk
authorPavel Hrdina <phrdina@redhat.com>
Wed, 2 Nov 2022 14:30:46 +0000 (15:30 +0100)
committerPavel Hrdina <phrdina@redhat.com>
Mon, 9 Jan 2023 12:33:01 +0000 (13:33 +0100)
Deleting internal snapshot when the currently active disk image is
different than where the internal snapshot was taken doesn't work
correctly.

This applies to a running VM only as we are using QMP command and
talking to the QEMU process that is using different disk.

This works correctly when the VM is shut of as in this case we spawn
qemu-img process to delete the snapshot.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
src/qemu/qemu_snapshot.c

index c23f629e9fde84382232edbdaad13dde7af2ae46..30137a2b8f2e87392a97c5efb954d404a1c646ad 100644 (file)
@@ -2492,9 +2492,31 @@ qemuSnapshotCountExternalInternal(void *payload,
 
 
 static int
-qemuSnapshotDeleteValidate(virDomainMomentObj *snap,
+qemuSnapshotDeleteValidate(virDomainObj *vm,
+                           virDomainMomentObj *snap,
                            unsigned int flags)
 {
+    if (!virDomainSnapshotIsExternal(snap) &&
+        virDomainObjIsActive(vm)) {
+        ssize_t i;
+        virDomainSnapshotDef *snapdef = virDomainSnapshotObjGetDef(snap);
+
+        for (i = 0; i < snapdef->ndisks; i++) {
+            virDomainSnapshotDiskDef *snapDisk = &(snapdef->disks[i]);
+            virDomainDiskDef *vmdisk = NULL;
+            virDomainDiskDef *disk = NULL;
+
+            vmdisk = qemuDomainDiskByName(vm->def, snapDisk->name);
+            disk = qemuDomainDiskByName(snapdef->parent.dom, snapDisk->name);
+
+            if (!virStorageSourceIsSameLocation(vmdisk->src, disk->src)) {
+                virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                               _("disk image '%s' for internal snapshot '%s' is not the same as disk image currently used by VM"),
+                               snapDisk->name, snap->def->name);
+                return -1;
+            }
+        }
+    }
 
     if (flags & (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
                  VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) {
@@ -2548,7 +2570,7 @@ qemuSnapshotDelete(virDomainObj *vm,
         goto endjob;
 
     if (!metadata_only) {
-        if (qemuSnapshotDeleteValidate(snap, flags) < 0)
+        if (qemuSnapshotDeleteValidate(vm, snap, flags) < 0)
             goto endjob;
     }