From: Shivaprasad G Bhat <sbhat(a)linux.vnet.ibm.com>
Signed-off-by: Shivaprasad G Bhat <sbhat(a)linux.vnet.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413(a)gmail.com>
---
src/qemu/qemu_domain.c | 70 ++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 7 +++++
2 files changed, 77 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 2de7343882..3ed2552227 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -16534,6 +16534,76 @@ qemuProcessEventFree(struct qemuProcessEvent *event)
}
+static bool isPCIMultifunctionDeviceXML(const char *xml)
+{
+ xmlDocPtr xmlptr;
+
+ if (!(xmlptr = virXMLParse(NULL, xml, _("(device_definition)")))) {
+ /* We report error anyway later */
+ return false;
+ }
+
+ return STREQ((const char *)(xmlDocGetRootElement(xmlptr))->name,
"devices");
+}
+
+static
+int qemuDomainValidateMultifunctionDeviceList(virDomainDeviceDefListPtr devlist)
+{
+ size_t i;
+ virDomainHostdevDefPtr hostdev = NULL;
+ virDomainDeviceInfoPtr info;
+
+ for (i = 0; i < devlist->count; i++) {
+ info = virDomainDeviceGetInfo(devlist->devs[i]);
+ if (devlist->devs[i]->type == VIR_DOMAIN_DEVICE_HOSTDEV)
+ hostdev = devlist->devs[i]->data.hostdev;
+
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ return -1;
+
+ if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+ info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+virDomainDeviceDefListPtr
+qemuDomainDeviceParseXMLMany(const char *xml,
+ virDomainDeviceDefListDataPtr data,
+ void *parseOpaque,
+ unsigned int parse_flags)
+{
+ virDomainDeviceDefListPtr devlist = NULL;
+
+ if (isPCIMultifunctionDeviceXML(xml)) {
+ if (!(devlist = virDomainDeviceDefParseXMLMany(xml, data->def,
+ data->xmlopt,
+ parseOpaque,
+ parse_flags)))
+ goto cleanup;
+
+ if (qemuDomainValidateMultifunctionDeviceList(devlist) < 0)
+ goto cleanup;
+ } else {
+ virDomainDeviceDefPtr dev = virDomainDeviceDefParse(xml, data->def,
+ data->xmlopt,
+ parseOpaque,
+ parse_flags);
+ if (!dev || VIR_ALLOC(devlist) < 0)
+ goto cleanup;
+
+ if (VIR_APPEND_ELEMENT(devlist->devs, devlist->count, dev) < 0)
+ goto cleanup;
+ }
+
+ cleanup:
+ return devlist;
+}
+
+
char *
qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivatePtr priv)
{
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index c54af16fa5..8d13cc0e56 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1260,6 +1260,13 @@ qemuDomainNVRAMPathGenerate(virQEMUDriverConfigPtr cfg,
virDomainEventSuspendedDetailType
qemuDomainPausedReasonToSuspendedEvent(virDomainPausedReason reason);
+
+virDomainDeviceDefListPtr
+qemuDomainDeviceParseXMLMany(const char *xml,
+ virDomainDeviceDefListDataPtr data,
+ void *parseOpaque,
+ unsigned int parse_flags);
+
int
qemuDomainValidateActualNetDef(const virDomainNetDef *net,
virQEMUCapsPtr qemuCaps);
--
2.24.1