From: Shivaprasad G Bhat <sbhat@xxxxxxxxxxxxxxxxxx> Signed-off-by: Shivaprasad G Bhat <sbhat@xxxxxxxxxxxxxxxxxx> Signed-off-by: Daniel Henrique Barboza <danielhb413@xxxxxxxxx> --- 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