On 8/14/19 11:47 AM, Maxiwell S. Garcia
wrote:
src/conf/moment_conf.c | 1 +
src/conf/moment_conf.h | 11 +++++++++++
src/conf/snapshot_conf.c | 23 +++++++++++++++++++++--
src/qemu/qemu_driver.c | 37 ++++++++++++++++++++++++++++---------
4 files changed, 61 insertions(+), 11 deletions(-)
diff --git a/src/conf/moment_conf.c b/src/conf/moment_conf.c
index fea13f0f97..f54a44b33e 100644
--- a/src/conf/moment_conf.c
+++ b/src/conf/moment_conf.c
@@ -66,6 +66,7 @@ virDomainMomentDefDispose(void *obj)
VIR_FREE(def->description);
VIR_FREE(def->parent_name);
virDomainDefFree(def->dom);
+ virDomainDefFree(def->inactiveDom);
}
/* Provide defaults for creation time and moment name after parsing XML */
diff --git a/src/conf/moment_conf.h b/src/conf/moment_conf.h
index 9fdbef2172..70cc47bd70 100644
--- a/src/conf/moment_conf.h
+++ b/src/conf/moment_conf.h
@@ -36,7 +36,18 @@ struct _virDomainMomentDef {
char *parent_name;
long long creationTime; /* in seconds */
+ /*
+ * Store the active domain definition in case of online
+ * guest and the inactive domain definition in case of
+ * offline guest
+ */
virDomainDefPtr dom;
+
+ /*
+ * Store the inactive domain definition in case of online
+ * guest and leave NULL in case of offline guest
+ */
+ virDomainDefPtr inactiveDom;
};
virClassPtr virClassForDomainMomentDef(void);
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index 7996589ad2..36435043ca 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -235,6 +235,7 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
virDomainSnapshotDefPtr def = NULL;
virDomainSnapshotDefPtr ret = NULL;
xmlNodePtr *nodes = NULL;
+ xmlNodePtr inactiveDomNode = NULL;
size_t i;
int n;
char *creation = NULL, *state = NULL;
@@ -244,6 +245,8 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
char *memoryFile = NULL;
bool offline = !!(flags & VIR_DOMAIN_SNAPSHOT_PARSE_OFFLINE);
virSaveCookieCallbacksPtr saveCookie = virDomainXMLOptionGetSaveCookie(xmlopt);
+ int domainflags = VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE;
if (!(def = virDomainSnapshotDefNew()))
return NULL;
@@ -293,8 +296,6 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
* clients will have to decide between best effort
* initialization or outright failure. */
if ((tmp = virXPathString("string(./domain/@type)", ctxt))) {
- int domainflags = VIR_DOMAIN_DEF_PARSE_INACTIVE |
- VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE;
xmlNodePtr domainNode = virXPathNode("./domain", ctxt);
VIR_FREE(tmp);
@@ -311,6 +312,16 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
} else {
VIR_WARN("parsing older snapshot that lacks domain");
}
+
+ /* /inactiveDomain entry saves the config XML present in a running
+ * VM. In case of absent, leave parent.inactiveDom NULL and use
+ * parent.dom for config and live XML. */
+ if ((inactiveDomNode = virXPathNode("./inactiveDomain", ctxt))) {
+ def->parent.inactiveDom = virDomainDefParseNode(ctxt->node->doc, inactiveDomNode,
+ caps, xmlopt, NULL, domainflags);
+ if (!def->parent.inactiveDom)
+ goto cleanup;
+ }
} else if (virDomainXMLOptionRunMomentPostParse(xmlopt, &def->parent) < 0) {
goto cleanup;
}
@@ -405,6 +416,7 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
VIR_FREE(nodes);
VIR_FREE(memorySnapshot);
VIR_FREE(memoryFile);
+ VIR_FREE(inactiveDomNode);
virObjectUnref(def);
return ret;
@@ -908,6 +920,13 @@ virDomainSnapshotDefFormatInternal(virBufferPtr buf,
virBufferAddLit(buf, "</domain>\n");
}
+ if (def->parent.inactiveDom) {
+ int inactivedomainflags = domainflags | VIR_DOMAIN_DEF_FORMAT_INACTIVE_NODE;
+ if (virDomainDefFormatInternal(def->parent.inactiveDom, caps,
+ inactivedomainflags, buf, xmlopt) < 0)
+ goto error;
+ }
+
if (virSaveCookieFormatBuf(buf, def->cookie,
virDomainXMLOptionGetSaveCookie(xmlopt)) < 0)
goto error;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 48c7b5628b..b3edb40a80 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15911,6 +15911,13 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
goto endjob;
+ if (vm->newDef) {
+ def->parent.inactiveDom = virDomainDefCopy(vm->newDef, caps,
+ driver->xmlopt, priv->qemuCaps, true);
+ if (!def->parent.inactiveDom)
+ goto endjob;
+ }
+
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) {
align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL;
align_match = false;
@@ -16443,6 +16450,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
qemuDomainObjPrivatePtr priv;
int rc;
virDomainDefPtr config = NULL;
+ virDomainDefPtr inactiveConfig = NULL;
virQEMUDriverConfigPtr cfg = NULL;
virCapsPtr caps = NULL;
bool was_stopped = false;
@@ -16544,11 +16552,10 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
* in the failure cases where we know there was no change? */
}
- /* Prepare to copy the snapshot inactive xml as the config of this
- * domain.
- *
- * XXX Should domain snapshots track live xml rather
- * than inactive xml? */
+ /* Prepare to copy the snapshot inactive domain as the config XML
+ * and the snapshot domain as the live XML. In case of inactive domain
+ * NULL, both config and live XML will be copied from snapshot domain.
+ */
if (snap->def->dom) {
config = virDomainDefCopy(snap->def->dom, caps,
driver->xmlopt, priv->qemuCaps, true);
@@ -16556,6 +16563,15 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
goto endjob;
}
+ if (snap->def->inactiveDom) {
+ inactiveConfig = virDomainDefCopy(snap->def->inactiveDom, caps,
+ driver->xmlopt, priv->qemuCaps, true);
+ if (!inactiveConfig)
+ goto endjob;
+ } else {
+ inactiveConfig = config;
+ }
+
cookie = (qemuDomainSaveCookiePtr) snapdef->cookie;
switch ((virDomainSnapshotState) snapdef->state) {
@@ -16658,16 +16674,19 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
goto endjob;
}
if (config) {
- virDomainObjAssignDef(vm, config, false, NULL);
virCPUDefFree(priv->origCPU);
VIR_STEAL_PTR(priv->origCPU, origCPU);
}
+ if (inactiveConfig)
+ virDomainObjAssignDef(vm, inactiveConfig, false, NULL);
} else {
/* Transitions 2, 3 */
load:
was_stopped = true;
+ if (inactiveConfig)
+ virDomainObjAssignDef(vm, inactiveConfig, false, NULL);
if (config)
- virDomainObjAssignDef(vm, config, false, NULL);
+ virDomainObjAssignDef(vm, config, true, NULL);
/* No cookie means libvirt which saved the domain was too old to
* mess up the CPU definitions.
@@ -16753,8 +16772,8 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
qemuProcessEndJob(driver, vm);
goto cleanup;
}
- if (config)
- virDomainObjAssignDef(vm, config, false, NULL);
+ if (inactiveConfig)
+ virDomainObjAssignDef(vm, inactiveConfig, false, NULL);
if (flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {