[PATCH 10/11] qemu: use snapshot-load for modern QEMU to revert to snapshot

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Note that if snapshot was done using old QEMU API then it is loaded
using old QEMU API as well as we don't know on which disk vmstate is.

Signed-off-by: Nikolay Shirokovskiy <nikolay.shirokovskiy@xxxxxxxxxx>
---
 src/qemu/qemu_process.c  |  8 +++++-
 src/qemu/qemu_snapshot.c | 54 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 6ed7eaaa83..eac6b00ff4 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -98,6 +98,7 @@
 #include "virutil.h"
 #include "storage_source.h"
 #include "backup_conf.h"
+#include "virdomainsnapshotobjlist.h"
 
 #include "logging/log_manager.h"
 #include "logging/log_protocol.h"
@@ -7389,6 +7390,7 @@ qemuProcessLaunch(virConnectPtr conn,
     size_t nnicindexes = 0;
     g_autofree int *nicindexes = NULL;
     unsigned long long maxMemLock = 0;
+    bool backcompatSnapshot;
 
     VIR_DEBUG("conn=%p driver=%p vm=%p name=%s if=%d asyncJob=%d "
               "incoming.launchURI=%s incoming.deferredURI=%s "
@@ -7444,11 +7446,15 @@ qemuProcessLaunch(virConnectPtr conn,
     if (qemuExtDevicesStart(driver, vm, incoming != NULL) < 0)
         goto cleanup;
 
+    if (snapshot)
+        backcompatSnapshot = !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SNAPSHOT_SAVE) ||
+                             !virDomainSnapshotObjGetDef(snapshot)->memorydisk;
+
     VIR_DEBUG("Building emulator command line");
     if (!(cmd = qemuBuildCommandLine(driver,
                                      vm,
                                      incoming ? incoming->launchURI : NULL,
-                                     snapshot, vmop,
+                                     snapshot && backcompatSnapshot ? snapshot : NULL, vmop,
                                      false,
                                      qemuCheckFips(vm),
                                      &nnicindexes, &nicindexes, 0)))
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 9f81befe85..605288f6c5 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -2395,6 +2395,54 @@ qemuSnapshotRevertWriteMetadata(virDomainObj *vm,
 }
 
 
+static int
+qemuSnapshotLoadState(virQEMUDriver *driver,
+                      virDomainObj *vm,
+                      virDomainMomentObj *snap)
+{
+    qemuDomainObjPrivate *priv = vm->privateData;
+    virDomainSnapshotDef *snapdef = virDomainSnapshotObjGetDef(snap);
+    g_autoptr(GPtrArray) devices = g_ptr_array_new();
+    const char *memoryNode;
+    int ret = -1;
+    int rc;
+
+    if (!(devices = qemuSnapshotGetDisksNodes(snapdef, vm->def, &memoryNode)))
+        goto cleanup;
+
+    if (qemuDomainObjEnterMonitorAsync(driver, vm,
+                                       VIR_ASYNC_JOB_START) < 0)
+        goto cleanup;
+    rc = qemuMonitorSnapshotLoad(priv->mon,
+                                 "snapshot-load",
+                                 snap->def->name,
+                                 memoryNode,
+                                 (const char **)devices->pdata,
+                                 devices->len);
+    qemuDomainObjExitMonitor(vm);
+    if (rc < 0)
+        goto cleanup;
+
+    if (qemuSnapshotWaitJob(driver, vm, VIR_ASYNC_JOB_START,
+                            "snapshot-load") < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    if (ret < 0 && virDomainObjIsActive(vm)) {
+        virErrorPtr err;
+
+        virErrorPreserveLast(&err);
+        qemuProcessStop(driver, vm,
+                        VIR_DOMAIN_SHUTOFF_FAILED,
+                        VIR_ASYNC_JOB_START, 0);
+        virErrorRestore(&err);
+    }
+    return ret;
+}
+
+
 static int
 qemuSnapshotRevertActive(virDomainObj *vm,
                          virDomainSnapshotPtr snapshot,
@@ -2407,6 +2455,7 @@ qemuSnapshotRevertActive(virDomainObj *vm,
                          unsigned int start_flags,
                          unsigned int flags)
 {
+    qemuDomainObjPrivate *priv = vm->privateData;
     virObjectEvent *event = NULL;
     virObjectEvent *event2 = NULL;
     int detail;
@@ -2458,6 +2507,11 @@ qemuSnapshotRevertActive(virDomainObj *vm,
     if (rc < 0)
         return -1;
 
+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SNAPSHOT_SAVE) &&
+        snapdef->memorydisk &&
+        qemuSnapshotLoadState(driver, vm, snap) < 0)
+        return -1;
+
     /* Touch up domain state.  */
     if (!(flags & VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING) &&
         (snapdef->state == VIR_DOMAIN_SNAPSHOT_PAUSED ||
-- 
2.35.1




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux