From 541f21afa609a3698908fa21a6e78bcd8dbdfcc9 Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Sun, 3 Apr 2016 21:01:06 +0200 Subject: [PATCH] conf: Parse more of our nodedev XML We were lacking tests that are checking for the completeness of our nodedev XMLs and also whether we output properly formatted ones. This patch adds parsing for the capability elements inside the element. Also bunch of tests are added to show everything works properly. Signed-off-by: Martin Kletzander --- src/conf/node_device_conf.c | 98 +++++++++++++++++++++++++++++++++++++ tests/nodedevxml2xmltest.c | 7 +++ 2 files changed, 105 insertions(+) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 96ec6a0037..a06e450428 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1268,6 +1268,91 @@ virPCIEDeviceInfoParseXML(xmlXPathContextPtr ctxt, } +static int +virNodeDevPCICapabilityParseXML(xmlXPathContextPtr ctxt, + xmlNodePtr node, + virNodeDevCapDataPtr data) +{ + char *maxFuncsStr = virXMLPropString(node, "maxCount"); + char *type = virXMLPropString(node, "type"); + xmlNodePtr *addresses = NULL; + xmlNodePtr orignode = ctxt->node; + int ret = -1; + size_t i = 0; + + ctxt->node = node; + + if (!type) { + virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing capability type")); + goto out; + } + + if (STREQ(type, "phys_function")) { + xmlNodePtr address = virXPathNode("./address[1]", ctxt); + + if (VIR_ALLOC(data->pci_dev.physical_function) < 0) + goto out; + + data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION; + + if (!address) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing address in 'phys_function' capability")); + goto out; + } + + if (virPCIDeviceAddressParseXML(address, + data->pci_dev.physical_function) < 0) + goto out; + } else if (STREQ(type, "virt_functions")) { + int naddresses = virXPathNodeSet("./address", ctxt, &addresses); + + if (maxFuncsStr && + virStrToLong_uip(maxFuncsStr, NULL, 10, + &data->pci_dev.max_virtual_functions) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Malformed 'maxCount' parameter")); + goto out; + } + + if (VIR_ALLOC_N(data->pci_dev.virtual_functions, naddresses) < 0) + goto out; + + for (i = 0; i < naddresses; i++) { + virPCIDeviceAddressPtr addr = NULL; + + if (VIR_ALLOC(addr) < 0) + goto out; + + if (virPCIDeviceAddressParseXML(addresses[i], addr) < 0) { + VIR_FREE(addr); + goto out; + } + + if (VIR_APPEND_ELEMENT(data->pci_dev.virtual_functions, + data->pci_dev.num_virtual_functions, + addr) < 0) + goto out; + } + + data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION; + } else { + int hdrType = virPCIHeaderTypeFromString(type); + + if (hdrType > 0 && !data->pci_dev.hdrType) + data->pci_dev.hdrType = hdrType; + } + + ret = 0; + out: + VIR_FREE(addresses); + VIR_FREE(maxFuncsStr); + VIR_FREE(type); + ctxt->node = orignode; + return ret; +} + + static int virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDefPtr def, @@ -1275,9 +1360,12 @@ virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt, virNodeDevCapDataPtr data) { xmlNodePtr orignode, iommuGroupNode, pciExpress; + xmlNodePtr *nodes = NULL; + int n = 0; int ret = -1; virPCIEDeviceInfoPtr pci_express = NULL; char *tmp = NULL; + size_t i = 0; orignode = ctxt->node; ctxt->node = node; @@ -1321,6 +1409,15 @@ virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt, data->pci_dev.vendor_name = virXPathString("string(./vendor[1])", ctxt); data->pci_dev.product_name = virXPathString("string(./product[1])", ctxt); + if ((n = virXPathNodeSet("./capability", ctxt, &nodes)) < 0) + goto out; + + for (i = 0; i < n; i++) { + if (virNodeDevPCICapabilityParseXML(ctxt, nodes[i], data) < 0) + goto out; + } + VIR_FREE(nodes); + if ((iommuGroupNode = virXPathNode("./iommuGroup[1]", ctxt))) { if (virNodeDevCapPCIDevIommuGroupParseXML(ctxt, iommuGroupNode, data) < 0) { @@ -1349,6 +1446,7 @@ virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt, ret = 0; out: + VIR_FREE(nodes); VIR_FREE(tmp); virPCIEDeviceInfoFree(pci_express); ctxt->node = orignode; diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index 96041f50b9..0ed06fdff3 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -91,7 +91,14 @@ mymain(void) DO_TEST("usb_device_1d6b_1_0000_00_1d_0"); DO_TEST("pci_8086_4238_pcie_wireless"); DO_TEST("pci_8086_0c0c_snd_hda_intel"); + DO_TEST("pci_0000_00_02_0_header_type"); + DO_TEST("pci_0000_00_1c_0_header_type"); DO_TEST("scsi_target0_0_0"); + DO_TEST("pci_0000_02_10_7_sriov"); + DO_TEST("pci_0000_02_10_7_sriov_vfs"); + DO_TEST("pci_0000_02_10_7_sriov_zero_vfs_max_count"); + DO_TEST("pci_0000_02_10_7_sriov_pf_vfs_all"); + DO_TEST("pci_0000_02_10_7_sriov_pf_vfs_all_header_type"); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } -- 2.47.2