Signed-off-by: Shivaprasad G Bhat <sbhat@xxxxxxxxxxxxxxxxxx> --- src/qemu/qemu_domain.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.h | 5 ++++ 2 files changed, 72 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 12ed68a89b..c0a0af525f 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11842,3 +11842,70 @@ qemuProcessEventFree(struct qemuProcessEvent *event) } VIR_FREE(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, + unsigned int parse_flags) +{ + virDomainDeviceDefListPtr devlist = NULL; + + if (isPCIMultifunctionDeviceXML(xml)) { + if (!(devlist = virDomainDeviceDefParseXMLMany(xml, data->def, + data->caps, data->xmlopt, + parse_flags))) + goto cleanup; + + if (qemuDomainValidateMultifunctionDeviceList(devlist) < 0) + goto cleanup; + } else { + virDomainDeviceDefPtr dev = virDomainDeviceDefParse(xml, data->def, + data->caps, data->xmlopt, + 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; +} diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index fbfc994652..339d0ba82c 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -1011,4 +1011,9 @@ qemuDomainPrepareDiskSource(virDomainDiskDefPtr disk, qemuDomainObjPrivatePtr priv, virQEMUDriverConfigPtr cfg); +virDomainDeviceDefListPtr +qemuDomainDeviceParseXMLMany(const char *xml, + virDomainDeviceDefListDataPtr data, + unsigned int parse_flags); + #endif /* __QEMU_DOMAIN_H__ */ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list