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(a)openvz.org>
---
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