At persistent modification of inactive domains, we go several steps as
- insert disk to vmdef
- assign controller if necessary
- assign pci address if necessary
- save it to file
If failure happens in above sequence, we need to keep consistency between
vmdef on cache and XML in the file. This patch adds support for
consistent modification of vmdef.
This patch adds virDomainObjCopyPersistentDef(). This will create a
copy of persistent def. The caller can update this and later replace
current one as:
copy = virDomainObjCopyPersistentDef()
.....update....
if (error)
virDomainObjAssignDef(dom, copy);
else
virDomainDefFree(copy).
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu(a)jp.fujitsu.com>
---
src/conf/domain_conf.c | 18 ++++++++++++++++++
src/conf/domain_conf.h | 3 +++
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 13 +++++++++++--
4 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 90a1317..e644af0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9370,3 +9370,21 @@ cleanup:
return ret;
}
+
+virDomainDefPtr
+virDomainObjCopyPersistentDef(virCapsPtr caps, virDomainObjPtr dom)
+{
+ char *xml;
+ virDomainDefPtr cur, ret;
+
+ cur = virDomainObjGetPersistentDef(caps, dom);
+
+ xml = virDomainDefFormat(cur, VIR_DOMAIN_XML_WRITE_FLAGS);
+ if (!xml)
+ return NULL;
+
+ ret = virDomainDefParseString(caps, xml, VIR_DOMAIN_XML_READ_FLAGS);
+
+ VIR_FREE(xml);
+ return ret;
+}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 95bd11e..9b97f26 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1377,6 +1377,9 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
virDomainDiskDefPathIterator iter,
void *opaque);
+virDomainDefPtr
+virDomainObjCopyPersistentDef(virCapsPtr caps, virDomainObjPtr dom);
+
typedef const char* (*virLifecycleToStringFunc)(int type);
typedef int (*virLifecycleFromStringFunc)(const char *type);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 54e4482..f464951 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -278,6 +278,7 @@ virDomainMemballoonModelTypeToString;
virDomainNetDefFree;
virDomainNetTypeToString;
virDomainObjAssignDef;
+virDomainObjCopyPersistentDef;
virDomainObjSetDefTransient;
virDomainObjGetPersistentDef;
virDomainObjIsDuplicate;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 49af487..b568382 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3983,8 +3983,11 @@ static int qemuDomainModifyDevicePersistent(virDomainPtr dom,
_("cannot modify active domain's definition"));
goto endjob;
}
-
- vmdef = virDomainObjGetPersistentDef(driver->caps, vm);
+ /*
+ * Here, create a copy of the current definition and update it.
+ * We'll finally replace the definition at success.
+ */
+ vmdef = virDomainObjCopyPersistentDef(driver->caps, vm);
if (!vmdef)
goto endjob;
@@ -4002,6 +4005,12 @@ static int qemuDomainModifyDevicePersistent(virDomainPtr dom,
if (!ret)
ret = virDomainSaveConfig(driver->configDir, vmdef);
+ /* At success, replace it. this never fails. */
+ if (!ret)
+ virDomainObjAssignDef(vm, vmdef, false);
+ else /* At failure, discard copy. */
+ virDomainDefFree(vmdef);
+
virDomainDeviceDefFree(device);
endjob:
--
1.7.4.1