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 <ebl...@redhat.com>
---
 src/qemu/qemu_driver.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1d5b5f8653..36426cd65a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -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;
     }

-- 
2.20.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to