[PATCH v3 11/21] Introduce qemuDomainDeviceParseXMLMany

Daniel Henrique Barboza danielhb413 at gmail.com
Wed May 20 21:11:33 UTC 2020


From: Shivaprasad G Bhat <sbhat at linux.vnet.ibm.com>

Signed-off-by: Shivaprasad G Bhat <sbhat at linux.vnet.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413 at gmail.com>
---
 src/qemu/qemu_domain.c | 74 ++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h |  7 ++++
 2 files changed, 81 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index d5e3d1a3cc..0471a37803 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -13391,6 +13391,80 @@ 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;
+
+    for (i = 0; i < devlist->count; i++) {
+        virDomainDeviceInfoPtr info = virDomainDeviceGetInfo(devlist->devs[i]);
+
+       if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+           info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+           return -1;
+       }
+
+       if (devlist->devs[i]->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
+           virDomainHostdevDefPtr hostdev = devlist->devs[i]->data.hostdev;
+
+           if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_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)))
+            return NULL;
+
+        if (qemuDomainValidateMultifunctionDeviceList(devlist) < 0)
+            goto cleanup;
+    } else {
+        virDomainDeviceDefPtr dev = virDomainDeviceDefParse(xml, data->def,
+                                                            data->xmlopt,
+                                                            parseOpaque,
+                                                            parse_flags);
+        if (!dev || VIR_ALLOC(devlist) < 0)
+            return NULL;
+
+        if (VIR_APPEND_ELEMENT(devlist->devs, devlist->count, dev) < 0)
+            goto cleanup;
+    }
+
+    return devlist;
+
+ cleanup:
+    virDomainDeviceDefListFree(devlist);
+    return NULL;
+}
+
+
 char *
 qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivatePtr priv)
 {
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index b601d52126..31c843de96 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1291,6 +1291,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.26.2




More information about the libvir-list mailing list