diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index f570081e3a2d88b142419b6f8992bcc086f6a5fb..6e51f590cd9a291984e16486c1066dc94793c3e9 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, "\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/@index)", 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 7b79d7725725be2686384494bd1e0f29d6e975c5..5dcbdfbbe158a0ec741f4e42916a3e6ea1f09181 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 e1278db9d9af90355de3c8dc1692730584f1cd61..39716f91625f86bf22125a10230ff9b105cd6926 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7157,6 +7157,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);
diff --git a/tests/qemustatusxml2xmldata/modern-in.xml b/tests/qemustatusxml2xmldata/modern-in.xml
index 4fb5f326c2e772a1a0eb8e327983174adc667c37..c9f5c4e76a072e7cbf0f2c7679377923cca2c665 100644
--- a/tests/qemustatusxml2xmldata/modern-in.xml
+++ b/tests/qemustatusxml2xmldata/modern-in.xml
@@ -233,6 +233,7 @@
+
@@ -258,6 +259,7 @@
+
upstream