In current implemention, mdev_types caps keep constant all the time. But, it is possible that a device capable of mdev_types sometime(for example:bind to proper driver) and incapable of mdev_types at other times(for example: unbind from its driver). We should keep the info of xml dumped out consistent with real status of the device. Signed-off-by: Wu Zongyong <cordius.wu@xxxxxxxxxx> --- src/node_device/node_device_linux_sysfs.c | 22 ++++++++++++++++++ src/node_device/node_device_udev.c | 37 ++++++++++++++++++++++++++----- src/node_device/node_device_udev.h | 3 +++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c index 6f438e5..388ffb4 100644 --- a/src/node_device/node_device_linux_sysfs.c +++ b/src/node_device/node_device_linux_sysfs.c @@ -29,6 +29,7 @@ #include "dirname.h" #include "node_device_driver.h" #include "node_device_hal.h" +#include "node_device_udev.h" #include "node_device_linux_sysfs.h" #include "virerror.h" #include "viralloc.h" @@ -175,6 +176,25 @@ nodeDeviceSysfsGetPCIIOMMUGroupCaps(virNodeDevCapPCIDevPtr pci_dev) return ret; } +static int +nodeDeviceSysfsGetPCIMdevTypesCaps(const char *sysfsPath, + virNodeDevCapPCIDevPtr pci_dev) +{ + size_t i; + + /* this could be a refresh, so clear out the old data */ + for (i = 0; i < pci_dev->nmdev_types; i++) + virNodeDevCapMdevTypeFree(pci_dev->mdev_types[i]); + VIR_FREE(pci_dev->mdev_types); + pci_dev->nmdev_types = 0; + pci_dev->flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_MDEV; + + if (udevPCISysfsGetMdevTypesCap(sysfsPath, pci_dev) < 0) + return -1; + + return 0; +} + /* nodeDeviceSysfsGetPCIRelatedCaps() get info that is stored in sysfs * about devices related to this device, i.e. things that can change @@ -190,6 +210,8 @@ nodeDeviceSysfsGetPCIRelatedDevCaps(const char *sysfsPath, return -1; if (nodeDeviceSysfsGetPCIIOMMUGroupCaps(pci_dev) < 0) return -1; + if (nodeDeviceSysfsGetPCIMdevTypesCaps(sysfsPath, pci_dev) < 0) + return -1; return 0; } diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index e0fca61..7b0014e 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -506,6 +506,37 @@ udevPCIGetMdevTypesCap(struct udev_device *device, } +int +udevPCISysfsGetMdevTypesCap(const char *sysfsPath, + virNodeDevCapPCIDevPtr pci_dev) +{ + int ret = -1; + struct udev *udev = NULL; + struct udev_device *device = NULL; + udevEventDataPtr priv = driver->privateData; + + virObjectLock(priv); + udev = udev_monitor_get_udev(priv->udev_monitor); + device = udev_device_new_from_syspath(udev, sysfsPath); + virObjectUnlock(priv); + + if (!device) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to create udev device from path %s"), + sysfsPath); + goto cleanup; + } + + if (udevPCIGetMdevTypesCap(device, pci_dev) < 0) + goto cleanup; + + ret = 0; + cleanup: + udev_device_unref(device); + return ret; +} + + static int udevProcessPCI(struct udev_device *device, virNodeDeviceDefPtr def) @@ -597,12 +628,6 @@ udevProcessPCI(struct udev_device *device, } } - /* check whether the device is mediated devices framework capable, if so, - * process it - */ - if (udevPCIGetMdevTypesCap(device, pci_dev) < 0) - goto cleanup; - ret = 0; cleanup: diff --git a/src/node_device/node_device_udev.h b/src/node_device/node_device_udev.h index 300f57e..bbdc70f 100644 --- a/src/node_device/node_device_udev.h +++ b/src/node_device/node_device_udev.h @@ -29,5 +29,8 @@ # define DMI_DEVPATH "/sys/devices/virtual/dmi/id" # define DMI_DEVPATH_FALLBACK "/sys/class/dmi/id" +int +udevPCISysfsGetMdevTypesCap(const char *sysfsPath, virNodeDevCapPCIDevPtr pci_dev); + #endif /* __VIR_NODE_DEVICE_UDEV_H__ */ -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list