[...]
+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