<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <font size="+1">Tried to reproduce the error using my x86 laptop but
      got hit by<br>
      <a class="moz-txt-link-freetext" href="https://bugzilla.redhat.com/show_bug.cgi?id=1689216">https://bugzilla.redhat.com/show_bug.cgi?id=1689216</a> when trying<br>
      to create the snapshot using upstream code:<br>
      <br>
      $ sudo ./run tools/virsh snapshot-create-as ub1810-cpu-hotplug
      snap<br>
      error: operation failed: Failed to take snapshot: Error: Nested
      VMX virtualization does not support live migration yet<br>
      <br>
      <br>
      Since this issue is arch independent I tried it out with a Power
      server.<br>
      Here's the behavior with current upstream:<br>
      <br>
      <br>
      - relevant piece of VM XML:<br>
      <br>
      <domain type='kvm'><br>
        <name>dhb</name><br>
        <uuid>d3fe0169-2be6-431c-85a5-cc178601bb69</uuid><br>
        <memory unit='KiB'>67108864</memory><br>
        <currentMemory unit='KiB'>67108864</currentMemory><br>
        <vcpu placement='static' current='4'>16</vcpu><br>
      <br>
      $ sudo ./run tools/virsh setvcpus dhb 8 --live<br>
      <br>
      $ <br>
      $ sudo ./run tools/virsh snapshot-create-as dhb snap1<br>
      Domain snapshot snap1 created<br>
      $ <br>
      $ sudo ./run tools/virsh snapshot-revert dhb snap1<br>
      <br>
      $ <br>
      $ sudo ./run tools/virsh dumpxml --inactive dhb<br>
      <domain type='kvm'><br>
        <name>dhb</name><br>
        <uuid>d3fe0169-2be6-431c-85a5-cc178601bb69</uuid><br>
        <memory unit='KiB'>67108864</memory><br>
        <currentMemory unit='KiB'>67108864</currentMemory><br>
        <vcpu placement='static' current='8'>16</vcpu><br>
        <vcpus><br>
      <br>
      The inactive XML got overwritten by the vcpu hotplug, which is not
      intended.<br>
      <br>
      <br>
      After the patch, the problem isn't reproduced: the inactive VM XML
      was<br>
      preserved after the snapshot-revert.<br>
      <br>
      <br>
      Maxiwell, you (or the commiter) can add the following in the
      commit-msg:<br>
      <br>
      Fixes: <a class="moz-txt-link-freetext" href="https://bugzilla.redhat.com/show_bug.cgi?id=1689216">https://bugzilla.redhat.com/show_bug.cgi?id=1689216</a><br>
      <br>
      <br>
      Since the bug you're fixing here also fixes this RH bugzilla.<br>
      <br>
      <br>
      Reviewed-by: Daniel Henrique Barboza <a class="moz-txt-link-rfc2396E" href="mailto:danielhb413@gmail.com"><danielhb413@gmail.com></a></font><br>
    <font size="+1"><font size="+1">Tested-by: Daniel Henrique Barboza
        <a class="moz-txt-link-rfc2396E" href="mailto:danielhb413@gmail.com"><danielhb413@gmail.com></a></font><br>
    </font><br>
    <br>
    <br>
    <br>
    <div class="moz-cite-prefix">On 4/30/19 2:54 PM, Maxiwell S. Garcia
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:20190430175401.19485-1-maxiwell@linux.ibm.com">
      <pre class="moz-quote-pre" wrap="">Snapshot create operation saves the live XML and uses it to replace the
domain definition in case of revert. But the VM config XML is not saved
and the revert operation does not address this issue. This commit
prevents the config XML from being overridden by snapshot definition.

An active domain stores both current and new definitions. The current
definition (vm->def) stores the live XML and the new definition
(vm->newDef) stores the config XML. In an inactive domain, only the
config XML is persistent, and it's saved in vm->def.

The revert operation uses the virDomainObjAssignDef() to set the
snapshot definition in vm->newDef, if domain is active, or in vm->def
otherwise. But before that, it saves the old value to return to
caller. This return is used here to restore the config XML after
all snapshot startup process finish.

Signed-off-by: Maxiwell S. Garcia <a class="moz-txt-link-rfc2396E" href="mailto:maxiwell@linux.ibm.com"><maxiwell@linux.ibm.com></a>
---
 src/qemu/qemu_driver.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b2ac737d1f..a73122454a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16251,6 +16251,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
     qemuDomainObjPrivatePtr priv;
     int rc;
     virDomainDefPtr config = NULL;
+    virDomainDefPtr inactiveConfig = NULL;
     virQEMUDriverConfigPtr cfg = NULL;
     virCapsPtr caps = NULL;
     bool was_stopped = false;
@@ -16465,7 +16466,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
                 goto endjob;
             }
             if (config) {
-                virDomainObjAssignDef(vm, config, false, NULL);
+                virDomainObjAssignDef(vm, config, false, &inactiveConfig);
                 virCPUDefFree(priv->origCPU);
                 VIR_STEAL_PTR(priv->origCPU, origCPU);
             }
@@ -16474,7 +16475,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
         load:
             was_stopped = true;
             if (config)
-                virDomainObjAssignDef(vm, config, false, NULL);
+                virDomainObjAssignDef(vm, config, false, &inactiveConfig);
 
             /* No cookie means libvirt which saved the domain was too old to
              * mess up the CPU definitions.
@@ -16533,6 +16534,9 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
                                                  detail);
             }
         }
+        if (inactiveConfig)
+            VIR_STEAL_PTR(vm->newDef, inactiveConfig);
+
         break;
 
     case VIR_DOMAIN_SNAPSHOT_SHUTDOWN:
@@ -16560,8 +16564,11 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
             qemuProcessEndJob(driver, vm);
             goto cleanup;
         }
-        if (config)
-            virDomainObjAssignDef(vm, config, false, NULL);
+        if (config) {
+            virDomainObjAssignDef(vm, config, false, &inactiveConfig);
+            if (inactiveConfig)
+                VIR_STEAL_PTR(vm->newDef, inactiveConfig);
+        }
 
         if (flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
                      VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
</pre>
    </blockquote>
    <br>
  </body>
</html>