Node names for block objects in qemu need to be unique for an instance
of the qemu process. Add a counter to generate objects sequentially and
store it in the status XML so that we can restore it.
The helpers added allow to create new node names and reset the counter
after the VM process terminates.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_domain.c | 38 ++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 6 ++++++
src/qemu/qemu_process.c | 3 +++
3 files changed, 47 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e5f055f203..032ad80baa 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2438,6 +2438,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
qemuDomainObjPrivateXMLFormatPR(buf, priv);
+ if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV))
+ virBufferAsprintf(buf, "<nodename next='%llu'/>\n",
priv->nodenameindex);
+
if (qemuDomainObjPrivateXMLFormatBlockjobs(buf, vm) < 0)
return -1;
@@ -2933,6 +2936,14 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
if (qemuDomainObjPrivateXMLParseBlockjobs(priv, ctxt) < 0)
goto error;
+ qemuDomainStorageIdReset(priv);
+ if (virXPathULongLong("string(./nodename/@next)", ctxt,
+ &priv->nodenameindex) == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("failed to parse node name index"));
+ goto error;
+ }
+
return 0;
error:
@@ -13179,3 +13190,30 @@ qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivatePtr priv)
return ret;
}
+
+
+/**
+ * qemuDomainStorageIdNew:
+ * @priv: qemu VM private data object.
+ *
+ * Generate a new unique id for a storage object. Useful for node name generation.
+ */
+unsigned int
+qemuDomainStorageIdNew(qemuDomainObjPrivatePtr priv)
+{
+ return ++priv->nodenameindex;
+}
+
+
+/**
+ * qemuDomainStorageIdReset:
+ * @priv: qemu VM private data object.
+ *
+ * Resets the data for the node name generator. The node names need to be unique
+ * for a single instance, so can be reset on VM shutdown.
+ */
+void
+qemuDomainStorageIdReset(qemuDomainObjPrivatePtr priv)
+{
+ priv->nodenameindex = 0;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 7b79d77257..5dcbdfbbe1 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -363,6 +363,9 @@ struct _qemuDomainObjPrivate {
/* true if qemu-pr-helper process is running for the domain */
bool prDaemonRunning;
+
+ /* counter for generating node names for qemu disks */
+ unsigned long long nodenameindex;
};
# define QEMU_DOMAIN_PRIVATE(vm) \
@@ -1063,4 +1066,7 @@ qemuDomainDiskCachemodeFlags(int cachemode,
char * qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivatePtr priv);
+unsigned int qemuDomainStorageIdNew(qemuDomainObjPrivatePtr priv);
+void qemuDomainStorageIdReset(qemuDomainObjPrivatePtr priv);
+
#endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ff4d992ff1..0bf8245173 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7154,6 +7154,9 @@ void qemuProcessStop(virQEMUDriverPtr driver,
/* clear all private data entries which are no longer needed */
qemuDomainObjPrivateDataClear(priv);
+ /* reset node name allocator */
+ qemuDomainStorageIdReset(priv);
+
/* The "release" hook cleans up additional resources */
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
--
2.16.2