[PATCH 10/11] qemu: use snapshot-load for modern QEMU to revert to snapshot
Nikolay Shirokovskiy
nikolay.shirokovskiy at openvz.org
Thu Mar 31 11:19:20 UTC 2022
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 at 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
More information about the libvir-list
mailing list