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 <capability
type='pci'> element.  Also bunch of tests are added to show everything
works properly.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
Martin Kletzander 2016-04-03 21:01:06 +02:00
parent 9840761fb4
commit 541f21afa6
2 changed files with 105 additions and 0 deletions

View File

@ -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;

View File

@ -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;
}