<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 19, 2016 at 3:01 AM, Shivaprasad G Bhat <span dir="ltr"><<a href="mailto:shivaprasadbhat@gmail.com" target="_blank">shivaprasadbhat@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This patch just introduces the parser function used by<br>
the later patches. The parser disallows hostdevices to be<br>
used with other virtio devices simultaneously.<br>
<br>
Signed-off-by: Shivaprasad G Bhat <<a href="mailto:sbhat@linux.vnet.ibm.com">sbhat@linux.vnet.ibm.com</a>><br>
---<br>
src/conf/domain_conf.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++<br>
src/conf/domain_conf.h | 22 ++++<br>
src/libvirt_private.syms | 3 +<br>
3 files changed, 261 insertions(+)<br>
<br>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c<br>
index ed0c471..e946147 100644<br>
--- a/src/conf/domain_conf.c<br>
+++ b/src/conf/domain_conf.c<br>
@@ -860,6 +860,36 @@ virDomainXMLOptionClassDispose(void *obj)<br>
(xmlopt->config.privFree)(xmlopt->config.priv);<br>
}<br>
<br>
+/* virDomainDeviceDefListAddCopy - add a *copy* of the device to this list */<br>
+int<br>
+virDomainDeviceDefListAddCopy(virDomainDeviceDefListPtr list,<br>
+ virDomainDeviceDefPtr dev,<br>
+ const virDomainDef *def,<br>
+ virCapsPtr caps,<br>
+ virDomainXMLOptionPtr xmlopt)<br>
+{<br>
+ virDomainDeviceDefPtr copy = virDomainDeviceDefCopy(dev, def, caps, xmlopt);<br>
+<br>
+ if (!copy)<br>
+ return -1;<br>
+ if (VIR_APPEND_ELEMENT(list->devs, list->count, copy) < 0) {<br>
+ virDomainDeviceDefFree(copy);<br>
+ return -1;<br>
+ }<br>
+ return 0;<br>
+}<br>
+<br>
+void virDomainDeviceDefListDispose(virDomainDeviceDefListPtr list)<br>
+{<br>
+ size_t i;<br>
+<br>
+ if (!list)<br>
+ return;<br>
+ for (i = 0; i < list->count; i++)<br>
+ virDomainDeviceDefFree(list->devs[i]);<br>
+ VIR_FREE(list);<br>
+}<br>
+<br>
/**<br>
* virDomainKeyWrapCipherDefParseXML:<br>
*<br>
@@ -24365,3 +24395,209 @@ virDomainObjGetShortName(virDomainObjPtr vm)<br>
<br>
return ret;<br>
}<br>
+<br>
+static int<br>
+virDomainPCIMultifunctionDeviceDefParseXML(xmlXPathContextPtr ctxt,<br>
+ const virDomainDef *def,<br>
+ virDomainDeviceDefListPtr devlist,<br>
+ virCapsPtr caps,<br>
+ virDomainXMLOptionPtr xmlopt,<br>
+ unsigned int flags)<br>
+{<br>
+ size_t i, j;<br>
+ int n;<br>
+ virDomainDeviceDef device;<br>
+ xmlNodePtr *nodes = NULL;<br>
+ char *netprefix = NULL;<br>
+ int nhostdevs = 0;<br>
+<br>
+ device.type = VIR_DOMAIN_DEVICE_DISK;<br>
+<br>
+ if ((n = virXPathNodeSet("./disk", ctxt, &nodes)) < 0)<br>
+ goto error;<br>
+<br>
+ for (i = 0; i < n; i++) {<br>
+ virDomainDiskDefPtr disk = virDomainDiskDefParseXML(xmlopt,<br>
+ nodes[i],<br>
+ ctxt,<br>
+ NULL,<br>
+ def->seclabels,<br>
+ def->nseclabels,<br>
+ flags);<br>
+ if (!disk)<br>
+ goto error;<br>
+<br>
+ device.data.disk = disk;<br>
+ if (virDomainDeviceDefListAddCopy(devlist, &device, def, caps, xmlopt) < 0)<br>
+ goto error;<br>
+ VIR_FREE(disk);<br>
+ }<br>
+ VIR_FREE(nodes);<br>
+<br>
+ device.type = VIR_DOMAIN_DEVICE_CONTROLLER;<br>
+ /* analysis of the controller devices */<br>
+ if ((n = virXPathNodeSet("./controller", ctxt, &nodes)) < 0)<br>
+ goto error;<br>
+<br>
+ for (i = 0; i < n; i++) {<br>
+ virDomainControllerDefPtr controller = virDomainControllerDefParseXML(nodes[i],<br>
+ ctxt,<br>
+ flags);<br>
+ if (!controller)<br>
+ goto error;<br>
+<br>
+ device.data.controller = controller;<br>
+ if (virDomainDeviceDefListAddCopy(devlist, &device, def, caps, xmlopt) < 0)<br>
+ goto error;<br>
+ VIR_FREE(controller);<br>
+ }<br>
+ VIR_FREE(nodes);<br>
+<br>
+ device.type = VIR_DOMAIN_DEVICE_NET;<br>
+ if ((n = virXPathNodeSet("./interface", ctxt, &nodes)) < 0)<br>
+ goto error;<br>
+<br>
+ netprefix = caps->host.netprefix;<br>
+ for (i = 0; i < n; i++) {<br>
+ virDomainNetDefPtr net = virDomainNetDefParseXML(xmlopt,<br>
+ nodes[i],<br>
+ ctxt,<br>
+ NULL,<br>
+ netprefix,<br>
+ flags);<br>
+ if (!net)<br>
+ goto error;<br>
+<br>
+ <a href="http://device.data.net" rel="noreferrer" target="_blank">device.data.net</a> = net;<br>
+ if (virDomainDeviceDefListAddCopy(devlist, &device, def, caps, xmlopt) < 0)<br>
+ goto error;<br>
+ VIR_FREE(net);<br>
+ }<br>
+ VIR_FREE(nodes);<br>
+<br>
+ /* analysis of the host devices */<br>
+ device.type = VIR_DOMAIN_DEVICE_HOSTDEV;<br>
+ if ((nhostdevs = virXPathNodeSet("./hostdev", ctxt, &nodes)) < 0)<br>
+ goto error;<br>
+ if (nhostdevs && devlist->count)<br>
+ goto misconfig;<br>
+ for (i = 0; i < nhostdevs; i++) {<br>
+ virDomainHostdevDefPtr hostdev;<br>
+<br>
+ hostdev = virDomainHostdevDefParseXML(xmlopt, nodes[i], ctxt,<br>
+ NULL, flags);<br>
+ if (!hostdev)<br>
+ goto error;<br>
+<br>
+ if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB ||<br>
+ hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {<br>
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",<br>
+ _("Can't add host USB device: "<br>
+ "USB is disabled in this host"));<br>
+ virDomainHostdevDefFree(hostdev);<br>
+ goto error;<br>
+ }<br>
+ device.data.hostdev = hostdev;<br>
+ for (j = 0; j < devlist->count; j++) {<br>
+ if (virDomainHostdevMatch(hostdev, devlist->devs[j]->data.hostdev)) {<br>
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",<br>
+ _("Duplicate host devices in list"));<br>
+ goto error;<br>
+ }<br>
+ }<br>
+ if (virDomainDeviceDefListAddCopy(devlist, &device, def, caps, xmlopt) < 0)<br>
+ goto error;<br>
+ VIR_FREE(hostdev);<br>
+ }<br>
+ VIR_FREE(nodes);<br>
+<br>
+ /* Parse the RNG devices */<br>
+ device.type = VIR_DOMAIN_DEVICE_RNG;<br>
+ if ((n = virXPathNodeSet("./rng", ctxt, &nodes)) < 0)<br>
+ goto error;<br>
+ for (i = 0; i < n; i++) {<br>
+ virDomainRNGDefPtr rng = virDomainRNGDefParseXML(nodes[i],<br>
+ ctxt,<br>
+ flags);<br>
+ if (!rng)<br>
+ goto error;<br>
+<br>
+ device.data.rng = rng;<br>
+ if (virDomainDeviceDefListAddCopy(devlist, &device, def, caps, xmlopt) < 0)<br>
+ goto error;<br>
+ VIR_FREE(rng);<br>
+ }<br>
+ VIR_FREE(nodes);<br>
+<br>
+ device.type = VIR_DOMAIN_DEVICE_CHR;<br>
+ if ((n = virXPathNodeSet("./serial", ctxt, &nodes)) < 0)<br>
+ goto error;<br>
+<br>
+ for (i = 0; i < n; i++) {<br>
+ virDomainChrDefPtr chr = virDomainChrDefParseXML(ctxt,<br>
+ nodes[i],<br>
+ def->seclabels,<br>
+ def->nseclabels,<br>
+ flags);<br>
+ if (!chr)<br>
+ goto error;<br>
+<br>
+ if (chr->target.port == -1) {<br>
+ int maxport = -1;<br>
+ for (j = 0; j < i; j++) {<br>
+ if (def->serials[j]->target.port > maxport)<br>
+ maxport = def->serials[j]->target.port;<br>
+ }<br>
+ chr->target.port = maxport + 1;<br>
+ }<br>
+ device.data.chr = chr;<br>
+ if (virDomainDeviceDefListAddCopy(devlist, &device, def, caps, xmlopt) < 0)<br>
+ goto error;<br>
+ VIR_FREE(chr);<br>
+ }<br>
+ VIR_FREE(nodes);<br>
+<br></blockquote><div><br></div><div>I realised the Character devices arent on PCI slot to get a PCI address and cant be hotplugged.</div><div>Will drop the character devices. </div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ if (nhostdevs && nhostdevs != devlist->count)<br>
+ goto misconfig;<br>
+<br>
+ return 0;<br>
+ misconfig:<br>
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",<br>
+ _("Shouldn't mix host devices with other devices"));<br>
+ error:<br>
+ return -1;<br>
+}<br>
+<br>
+<br>
+int<br>
+virDomainPCIMultifunctionDeviceDefParseNode(const char *xml,<br>
+ const virDomainDef *def,<br>
+ virDomainDeviceDefListPtr devlist,<br>
+ virCapsPtr caps,<br>
+ virDomainXMLOptionPtr xmlopt,<br>
+ unsigned int flags)<br>
+{<br>
+ xmlXPathContextPtr ctxt = NULL;<br>
+ int ret = -1;<br>
+<br>
+ xmlDocPtr xmlptr;<br>
+<br>
+ if (!(xmlptr = virXMLParse(NULL, xml, _("(device_definition)")))) {<br>
+ /* We report error anyway later */<br>
+ return -1;<br>
+ }<br>
+<br>
+ ctxt = xmlXPathNewContext(xmlptr);<br>
+ if (ctxt == NULL) {<br>
+ virReportOOMError();<br>
+ goto cleanup;<br>
+ }<br>
+<br>
+ ctxt->node = xmlDocGetRootElement(xmlptr);<br>
+ ret = virDomainPCIMultifunctionDeviceDefParseXML(ctxt, def, devlist,<br>
+ caps, xmlopt, flags);<br>
+<br>
+ cleanup:<br>
+ xmlXPathFreeContext(ctxt);<br>
+ return ret;<br>
+}<br>
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h<br>
index b9e696d..9ddfbd1 100644<br>
--- a/src/conf/domain_conf.h<br>
+++ b/src/conf/domain_conf.h<br>
@@ -2462,6 +2462,20 @@ typedef enum {<br>
typedef struct _virDomainXMLOption virDomainXMLOption;<br>
typedef virDomainXMLOption *virDomainXMLOptionPtr;<br>
<br>
+struct virDomainDeviceDefList {<br>
+ virDomainDeviceDefPtr *devs;<br>
+ size_t count;<br>
+};<br>
+typedef struct virDomainDeviceDefList *virDomainDeviceDefListPtr;<br>
+<br>
+int<br>
+virDomainDeviceDefListAddCopy(virDomainDeviceDefListPtr list, virDomainDeviceDefPtr dev,<br>
+ const virDomainDef *def,<br>
+ virCapsPtr caps,<br>
+ virDomainXMLOptionPtr xmlopt);<br>
+void virDomainDeviceDefListDispose(virDomainDeviceDefListPtr list);<br>
+<br>
+<br>
/* Called once after everything else has been parsed, for adjusting<br>
* overall domain defaults. */<br>
typedef int (*virDomainDefPostParseCallback)(virDomainDefPtr def,<br>
@@ -3176,6 +3190,14 @@ int virDomainDefGetVcpuPinInfoHelper(virDomainDefPtr def,<br>
<br>
bool virDomainDefHasMemballoon(const virDomainDef *def) ATTRIBUTE_NONNULL(1);<br>
<br>
+int<br>
+virDomainPCIMultifunctionDeviceDefParseNode(const char *xml,<br>
+ const virDomainDef *def,<br>
+ virDomainDeviceDefListPtr devlist,<br>
+ virCapsPtr caps,<br>
+ virDomainXMLOptionPtr xmlopt,<br>
+ unsigned int flags);<br>
+<br>
char *virDomainObjGetShortName(virDomainObjPtr vm);<br>
<br>
#endif /* __DOMAIN_CONF_H */<br>
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms<br>
index e4953b7..d6a60b5 100644<br>
--- a/src/libvirt_private.syms<br>
+++ b/src/libvirt_private.syms<br>
@@ -109,6 +109,7 @@ virDomainPCIAddressSetGrow;<br>
virDomainPCIAddressSlotInUse;<br>
virDomainPCIAddressValidate;<br>
virDomainPCIControllerModelToConnectType;<br>
+virDomainPCIMultifunctionDeviceDefParseNode;<br>
virDomainVirtioSerialAddrAssign;<br>
virDomainVirtioSerialAddrAutoAssign;<br>
virDomainVirtioSerialAddrIsComplete;<br>
@@ -249,6 +250,8 @@ virDomainDeviceAddressIsValid;<br>
virDomainDeviceAddressTypeToString;<br>
virDomainDeviceDefCopy;<br>
virDomainDeviceDefFree;<br>
+virDomainDeviceDefListAddCopy;<br>
+virDomainDeviceDefListDispose;<br>
virDomainDeviceDefParse;<br>
virDomainDeviceFindControllerModel;<br>
virDomainDeviceGetInfo;<br>
<br>
--<br>
libvir-list mailing list<br>
<a href="mailto:libvir-list@redhat.com">libvir-list@redhat.com</a><br>
<a href="https://www.redhat.com/mailman/listinfo/libvir-list" rel="noreferrer" target="_blank">https://www.redhat.com/mailman/listinfo/libvir-list</a><br>
</blockquote></div><br></div></div>