
[...]
+static int +udevPCIGetMdevCaps(struct udev_device *device, + virNodeDevCapPCIDevPtr pcidata) +{ + int ret = -1; + int direrr = -1; + DIR *dir = NULL; + struct dirent *entry; + char *path = NULL; + char *tmppath = NULL; + virNodeDevCapMdevPtr mdev = NULL; + virNodeDevCapMdevPtr *mdevs = NULL; + size_t nmdevs = 0; + size_t i; + + if (virAsprintf(&path, "%s/mdev_supported_types", + udev_device_get_syspath(device)) < 0) + return -1; + + if ((direrr = virDirOpenIfExists(&dir, path)) < 0) + goto cleanup; + + if (direrr == 0) { + ret = 0; + goto cleanup; + } + + if (VIR_ALLOC(mdevs) < 0) + goto cleanup; + + /* since udev doesn't provide means to list other than top-level + * attributes, we need to scan the subdirectories ourselves + */ + while ((direrr = virDirRead(dir, &entry, path)) > 0) { + if (VIR_ALLOC(mdev) < 0) + goto cleanup; + + if (virAsprintf(&tmppath, "%s/%s", path, entry->d_name) < 0) + goto cleanup; + + if (udevGetMdevCaps(device, tmppath, mdev) < 0) + goto cleanup; + + if (VIR_APPEND_ELEMENT(mdevs, nmdevs, mdev) < 0) + goto cleanup; + + VIR_FREE(tmppath); + } + + if (direrr < 0) + goto cleanup; + + VIR_STEAL_PTR(pcidata->mdevs, mdevs); + pcidata->nmdevs = nmdevs; + nmdevs = 0; + ret = 0; + cleanup:
Oops, I forgot something in here. Consider this bit squashed in (otherwise the parent device's output would lack some tiny bits) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index a04009110..349d51f69 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -427,6 +427,7 @@ udevPCIGetMdevCaps(struct udev_device *device, VIR_STEAL_PTR(pcidata->mdevs, mdevs); pcidata->nmdevs = nmdevs; + pcidata->flags |= VIR_NODE_DEV_CAP_FLAG_PCI_MDEV; nmdevs = 0; ret = 0; cleanup: Erik