Restore the domain description from the snapshot information.
TODOs:
- Only restart the KVM process when the snapshot is incompatible with
"loadvm". This would have the benefir of being able to switch saved
states very fast and also doesn't disconnect any VNC viewer.
Signed-off-by: Philipp Hahn <hahn(a)univention.de>
---
src/qemu/qemu_driver.c | 39 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 38 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5041d32..5610961 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6282,6 +6282,7 @@ static virDomainSnapshotPtr qemuDomainSnapshotCreateXML(virDomainPtr
domain,
{
struct qemud_driver *driver = domain->conn->privateData;
virDomainObjPtr vm = NULL;
+ virDomainDefPtr newDef = NULL;
virDomainSnapshotObjPtr snap = NULL;
virDomainSnapshotPtr snapshot = NULL;
char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -6311,6 +6312,18 @@ static virDomainSnapshotPtr
qemuDomainSnapshotCreateXML(virDomainPtr domain,
if (!(def = virDomainSnapshotDefParseString(xmlDesc, 1, qemu_driver->caps)))
goto cleanup;
+ /* create copy */
+ if (!def->dom) {
+ char *xml = NULL;
+ if (!(xml = virDomainDefFormat(vm->def, VIR_DOMAIN_XML_INACTIVE |
VIR_DOMAIN_XML_SECURE)))
+ goto cleanup;
+ newDef = virDomainDefParseString(driver->caps, xml, VIR_DOMAIN_XML_INACTIVE);
+ VIR_FREE(xml);
+ if (!newDef)
+ goto cleanup;
+ def->dom = newDef;
+ }
+
if (!(snap = virDomainSnapshotAssignDef(&vm->snapshots, def)))
goto cleanup;
@@ -6561,6 +6574,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr
snapshot,
virDomainEventPtr event = NULL;
qemuDomainObjPrivatePtr priv;
int rc;
+ virDomainDefPtr newDef = NULL;
virCheckFlags(0, -1);
@@ -6586,10 +6600,23 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr
snapshot,
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
goto cleanup;
+ /* create copy */
+ if (snap->def->dom) {
+ char *xml = NULL;
+ /* TODO:Compare old definition to new definition to decide, if KVM must be
restarted or existing KVM can be reused. */
+ if (!(xml = virDomainDefFormat(snap->def->dom, VIR_DOMAIN_XML_INACTIVE |
VIR_DOMAIN_XML_SECURE)))
+ goto cleanup;
+ newDef = virDomainDefParseString(driver->caps, xml, VIR_DOMAIN_XML_INACTIVE);
+ VIR_FREE(xml);
+ if (!newDef)
+ goto cleanup;
+ virDomainObjAssignDef(vm, newDef, false);
+ }
+
if (snap->def->state == VIR_DOMAIN_RUNNING
|| snap->def->state == VIR_DOMAIN_PAUSED) {
- if (virDomainObjIsActive(vm)) {
+ if (virDomainObjIsActive(vm) && !newDef) {
priv = vm->privateData;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
rc = qemuMonitorLoadSnapshot(priv->mon, snap->def->name);
@@ -6598,6 +6625,16 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr
snapshot,
goto endjob;
}
else {
+ if (virDomainObjIsActive(vm)) {
+ //qemudShutdownVMDaemon(driver, vm, 0); // <= 0.12.4
+ qemuProcessStop(driver, vm, 0); // >= 14
+ if (!vm->persistent) {
+ if (qemuDomainObjEndJob(vm) > 0)
+ virDomainRemoveInactive(&driver->domains, vm);
+ vm = NULL;
+ goto cleanup;
+ }
+ }
if (qemuDomainSnapshotSetCurrentActive(vm, driver->snapshotDir) < 0)
goto endjob;
--
1.7.1