[libvirt] [PATCH v3 03/13] Introduce PCI Multifunction device parser

Shivaprasad G Bhat shivaprasadbhat at gmail.com
Mon May 23 20:59:06 UTC 2016


This patch just introduces the parser function used by
the later patches. The parser disallows hostdevices to be
used with other virtio devices simultaneously.

Signed-off-by: Shivaprasad G Bhat <sbhat at linux.vnet.ibm.com>
---
 src/conf/domain_conf.c   |  123 ++++++++++++++++++++++++++++++++++++++--------
 src/conf/domain_conf.h   |   19 +++++++
 src/libvirt_private.syms |    3 +
 3 files changed, 124 insertions(+), 21 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ed0c471..873a309 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -860,6 +860,36 @@ virDomainXMLOptionClassDispose(void *obj)
         (xmlopt->config.privFree)(xmlopt->config.priv);
 }
 
+/* virDomainDeviceDefListAddCopy - add a *copy* of the device to this list */
+int
+virDomainDeviceDefListAddCopy(virDomainDeviceDefListPtr list,
+                              virDomainDeviceDefPtr dev,
+                              const virDomainDef *def,
+                              virCapsPtr caps,
+                              virDomainXMLOptionPtr xmlopt)
+{
+    virDomainDeviceDefPtr copy = virDomainDeviceDefCopy(dev, def, caps, xmlopt);
+
+    if (!copy)
+        return -1;
+    if (VIR_APPEND_ELEMENT(list->devs, list->count, copy) < 0) {
+        virDomainDeviceDefFree(copy);
+        return -1;
+    }
+    return 0;
+}
+
+void virDomainDeviceDefListFree(virDomainDeviceDefListPtr list)
+{
+    size_t i;
+
+    if (!list)
+        return;
+    for (i = 0; i < list->count; i++)
+        virDomainDeviceDefFree(list->devs[i]);
+    VIR_FREE(list);
+}
+
 /**
  * virDomainKeyWrapCipherDefParseXML:
  *
@@ -12880,25 +12910,16 @@ virDomainMemoryDefParseXML(xmlNodePtr memdevNode,
     return NULL;
 }
 
-
-virDomainDeviceDefPtr
-virDomainDeviceDefParse(const char *xmlStr,
-                        const virDomainDef *def,
-                        virCapsPtr caps,
-                        virDomainXMLOptionPtr xmlopt,
-                        unsigned int flags)
+static
+virDomainDeviceDefPtr virDomainDeviceDefParseXML(xmlNodePtr node,
+                                                 const virDomainDef *def,
+                                                 virCapsPtr caps,
+                                                 virDomainXMLOptionPtr xmlopt,
+                                                 xmlXPathContextPtr ctxt,
+                                                 unsigned int flags)
 {
-    xmlDocPtr xml;
-    xmlNodePtr node;
-    xmlXPathContextPtr ctxt = NULL;
     virDomainDeviceDefPtr dev = NULL;
     char *netprefix;
-
-    if (!(xml = virXMLParseStringCtxt(xmlStr, _("(device_definition)"), &ctxt)))
-        goto error;
-
-    node = ctxt->node;
-
     if (VIR_ALLOC(dev) < 0)
         goto error;
 
@@ -13031,14 +13052,33 @@ virDomainDeviceDefParse(const char *xmlStr,
     if (virDomainDeviceDefPostParse(dev, def, caps, flags, xmlopt) < 0)
         goto error;
 
- cleanup:
+    return dev;
+ error:
+    return NULL;
+}
+
+virDomainDeviceDefPtr
+virDomainDeviceDefParse(const char *xmlStr,
+                        const virDomainDef *def,
+                        virCapsPtr caps,
+                        virDomainXMLOptionPtr xmlopt,
+                        unsigned int flags)
+{
+    xmlDocPtr xml;
+    xmlNodePtr node;
+    xmlXPathContextPtr ctxt = NULL;
+    virDomainDeviceDefPtr dev = NULL;
+
+    if (!(xml = virXMLParseStringCtxt(xmlStr, _("(device_definition)"), &ctxt)))
+        return NULL;
+
+    node = ctxt->node;
+
+    dev = virDomainDeviceDefParseXML(node, def, caps, xmlopt, ctxt, flags);
+
     xmlFreeDoc(xml);
     xmlXPathFreeContext(ctxt);
     return dev;
-
- error:
-    VIR_FREE(dev);
-    goto cleanup;
 }
 
 
@@ -24365,3 +24405,44 @@ virDomainObjGetShortName(virDomainObjPtr vm)
 
     return ret;
 }
+
+
+virDomainDeviceDefListPtr
+virDomainDeviceDefParseXMLMany(const char *xml,
+                               const virDomainDef *def,
+                               virCapsPtr caps,
+                               virDomainXMLOptionPtr xmlopt,
+                               unsigned int flags)
+{
+    xmlXPathContextPtr ctxt = NULL;
+    xmlDocPtr xmlPtr;
+    xmlNodePtr node, root;
+    virDomainDeviceDefPtr dev = NULL;
+    virDomainDeviceDefListPtr devlist;
+
+    if (!(xmlPtr = virXMLParseStringCtxt(xml, _("(device_definition)"), &ctxt)))
+        return NULL;
+
+    if (VIR_ALLOC(devlist) < 0)
+         goto exit;
+
+    root = xmlDocGetRootElement(xmlPtr);
+    node = root->children;
+    while (node) {
+        if (node->type == XML_ELEMENT_NODE) {
+            dev = virDomainDeviceDefParseXML(node, def, caps, xmlopt, ctxt, flags);
+            if (VIR_APPEND_ELEMENT(devlist->devs, devlist->count, dev) < 0) {
+                virDomainDeviceDefFree(dev);
+                virDomainDeviceDefListFree(devlist);
+                goto exit;
+            }
+            dev = NULL;
+        }
+        node = node->next;
+    }
+
+ exit:
+    xmlFreeDoc(xmlPtr);
+    xmlXPathFreeContext(ctxt);
+    return devlist;
+}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index b9e696d..ed188f1 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2462,6 +2462,20 @@ typedef enum {
 typedef struct _virDomainXMLOption virDomainXMLOption;
 typedef virDomainXMLOption *virDomainXMLOptionPtr;
 
+struct virDomainDeviceDefList {
+    virDomainDeviceDefPtr *devs;
+    size_t count;
+};
+typedef struct virDomainDeviceDefList *virDomainDeviceDefListPtr;
+
+int
+virDomainDeviceDefListAddCopy(virDomainDeviceDefListPtr list, virDomainDeviceDefPtr dev,
+                              const virDomainDef *def,
+                              virCapsPtr caps,
+                              virDomainXMLOptionPtr xmlopt);
+void virDomainDeviceDefListFree(virDomainDeviceDefListPtr list);
+
+
 /* Called once after everything else has been parsed, for adjusting
  * overall domain defaults.  */
 typedef int (*virDomainDefPostParseCallback)(virDomainDefPtr def,
@@ -2717,6 +2731,11 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(const char *xmlStr,
                                               virCapsPtr caps,
                                               virDomainXMLOptionPtr xmlopt,
                                               unsigned int flags);
+virDomainDeviceDefListPtr virDomainDeviceDefParseXMLMany(const char *xmlStr,
+                                                         const virDomainDef *def,
+                                                         virCapsPtr caps,
+                                                         virDomainXMLOptionPtr xmlopt,
+                                                         unsigned int flags);
 virStorageSourcePtr virDomainDiskDefSourceParse(const char *xmlStr,
                                                 const virDomainDef *def,
                                                 virDomainXMLOptionPtr xmlopt,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e4953b7..0e8a887 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -249,7 +249,10 @@ virDomainDeviceAddressIsValid;
 virDomainDeviceAddressTypeToString;
 virDomainDeviceDefCopy;
 virDomainDeviceDefFree;
+virDomainDeviceDefListAddCopy;
+virDomainDeviceDefListFree;
 virDomainDeviceDefParse;
+virDomainDeviceDefParseXMLMany;
 virDomainDeviceFindControllerModel;
 virDomainDeviceGetInfo;
 virDomainDeviceInfoCopy;




More information about the libvir-list mailing list