On 26.09.2014 12:43, Martin Kletzander wrote:
This patch adds parsing/formatting code as well as documentation for
shared memory devices. This will currently be only accessible in QEMU
using it's ivshmem device, but is designed as generic as possible to
allow future expansion for other hypervisors.
In the devices section in the domain XML users may specify:
- For shmem device using a server:
<shmem name='shmem0'>
<server path='/tmp/socket-ivshmem0'/>
<size unit='M'>32</size>
<msi vectors='32' ioeventfd='on'/>
</shmem>
- For ivshmem device not using an ivshmem server:
<shmem name='shmem1'>
<size unit='M'>32</size>
</shmem>
Most of the configuration is made optional so it also allows
specifications like:
<shmem name='shmem1/>
<shmem name='shmem2'>
<server/>
</shmem>
Signed-off-by: Maxime Leroy <maxime.leroy(a)6wind.com>
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
docs/formatdomain.html.in | 52 ++++++
docs/schemas/domaincommon.rng | 39 +++++
src/conf/domain_conf.c | 184 ++++++++++++++++++++-
src/conf/domain_conf.h | 24 +++
src/qemu/qemu_hotplug.c | 1 +
.../qemuxml2argv-shmem-msi-only.xml | 24 +++
tests/qemuxml2argvdata/qemuxml2argv-shmem.xml | 51 ++++++
tests/qemuxml2argvtest.c | 2 +
tests/qemuxml2xmltest.c | 1 +
9 files changed, 377 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-shmem-msi-only.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-shmem.xml
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b114737..51bdd31 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9702,6 +9730,84 @@ virDomainNVRAMDefParseXML(xmlNodePtr node,
return NULL;
}
+static virDomainShmemDefPtr
+virDomainShmemDefParseXML(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ unsigned int flags)
+{
+ char *tmp = NULL;
+ virDomainShmemDefPtr def = NULL;
+ virDomainShmemDefPtr ret = NULL;
+ xmlNodePtr msi = NULL;
+ xmlNodePtr save = ctxt->node;
+ xmlNodePtr server = NULL;
+
+
+ if (VIR_ALLOC(def) < 0)
+ return NULL;
+
+ ctxt->node = node;
+
+ if (!(def->name = virXMLPropString(node, "name"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("shmem element must contain 'name'
attribute"));
+ goto cleanup;
+ }
+
+ if (virDomainParseScaledValue("./size[1]", ctxt, &def->size,
+ 1, ULLONG_MAX, false) < 0)
+ goto cleanup;
+
+ if ((server = virXPathNode("./server", ctxt))) {
s,./server,./server[1] to make sure we parse only the first <server/> in
case user supplies two or more in the XML.
+ def->server.enabled = true;
+
+ if ((tmp = virXMLPropString(server, "path")))
+ def->server.path = virFileSanitizePath(tmp);
+ VIR_FREE(tmp);
+ }
+
+ if ((msi = virXPathNode("./msi", ctxt))) {
Same here.
+ def->msi.enabled = true;
+
+ if ((tmp = virXMLPropString(msi, "vectors")) &&
+ virStrToLong_uip(tmp, NULL, 0, &def->msi.vectors) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid number of vectors for shmem:
'%s'"),
+ tmp);
+ goto cleanup;
+ }
+ VIR_FREE(tmp);
+
+ if ((tmp = virXMLPropString(msi, "ioeventfd")) &&
+ (def->msi.ioeventfd = virTristateSwitchTypeFromString(tmp)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid msi ioeventfd setting for shmem:
'%s'"),
+ tmp);
+ goto cleanup;
+ }
+ VIR_FREE(tmp);
+ }
+
+ /* msi option is only relevant with a server */
+ if (def->msi.enabled && !def->server.enabled) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("msi option is only supported with a server"));
+ goto cleanup;
+ }
+
+ if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0)
+ goto cleanup;
+
+
+ ret = def;
+ def = NULL;
+ cleanup:
+ ctxt->node = save;
+ VIR_FREE(tmp);
+ virDomainShmemDefFree(def);
+ return ret;
+}
+
Michal