]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Fix snapshot redefine vs. domain state bug
authorEric Blake <eblake@redhat.com>
Wed, 27 Feb 2019 19:38:18 +0000 (13:38 -0600)
committerEric Blake <eblake@redhat.com>
Fri, 1 Mar 2019 14:23:31 +0000 (08:23 -0600)
The existing qemu snapshot code has a slight bug: if the domain
is currently pmsuspended, you can't use the _REDEFINE flag even
though the current domain state should have no bearing on being
able to recreate metadata state; and conversely, you can use the
_REDEFINE flag to create snapshot metadata claiming to be
pmsuspended as a bypass to the normal restrictions that you can't
create an original qemu snapshot in that state (the restriction
against pmsuspend is specific to qemu, rather than part of the
driver-agnostic snapshot_conf code).

Fix this by checking the snapshot state (when redefining) instead
of the domain state (which is a subset of snapshot states).

Fixes the second problem mentioned in https://bugzilla.redhat.com/1680304

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
src/qemu/qemu_driver.c

index 1d5b5f865313183ba9c4a1609901de64c9281457..36426cd65a408ae7c8b3a9436cbe488426c4ac45 100644 (file)
@@ -15693,6 +15693,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
     virQEMUDriverConfigPtr cfg = NULL;
     virCapsPtr caps = NULL;
     qemuDomainObjPrivatePtr priv;
+    virDomainState state;
 
     virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
                   VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT |
@@ -15776,7 +15777,11 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
     }
 
     /* allow snapshots only in certain states */
-    switch ((virDomainState) vm->state.state) {
+    state = vm->state.state;
+    if (redefine)
+        state = def->state == VIR_DOMAIN_DISK_SNAPSHOT ? VIR_DOMAIN_SHUTOFF :
+            def->state;
+    switch (state) {
         /* valid states */
     case VIR_DOMAIN_RUNNING:
     case VIR_DOMAIN_PAUSED:
@@ -15796,7 +15801,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
     case VIR_DOMAIN_BLOCKED: /* invalid state, unused in qemu */
     case VIR_DOMAIN_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state %s"),
-                       virDomainStateTypeToString(vm->state.state));
+                       virDomainStateTypeToString(state));
         goto cleanup;
     }