From 6eb1f2b9d06b1b68b7feee440b99de498a56c313 Mon Sep 17 00:00:00 2001 From: Erik Skultety Date: Fri, 19 Jan 2018 20:33:43 +0100 Subject: [PATCH] util: pci: Introduce virPCIGetMdevTypes helper This is a replacement for the existing udevPCIGetMdevTypesCap which is static to the udev backend. This simple helper constructs the sysfs path from the device's base path for each mdev type and queries the corresponding attributes of that type. Signed-off-by: Erik Skultety --- src/libvirt_private.syms | 1 + src/util/virpci.c | 58 ++++++++++++++++++++++++++++++++++++++++ src/util/virpci.h | 4 +++ 3 files changed, 63 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c52c3ec385..24d94ca810 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2457,6 +2457,7 @@ virPCIDeviceWaitForCleanup; virPCIEDeviceInfoFree; virPCIGetDeviceAddressFromSysfsLink; virPCIGetHeaderType; +virPCIGetMdevTypes; virPCIGetNetName; virPCIGetPhysicalFunction; virPCIGetVirtualFunctionIndex; diff --git a/src/util/virpci.c b/src/util/virpci.c index fe57bef327..b6a5739cad 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -3027,6 +3027,64 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path, return ret; } + +ssize_t +virPCIGetMdevTypes(const char *sysfspath, + virMediatedDeviceTypePtr **types) +{ + ssize_t ret = -1; + int dirret = -1; + DIR *dir = NULL; + struct dirent *entry; + char *types_path = NULL; + char *tmppath = NULL; + virMediatedDeviceTypePtr mdev_type = NULL; + virMediatedDeviceTypePtr *mdev_types = NULL; + size_t ntypes = 0; + size_t i; + + if (virAsprintf(&types_path, "%s/mdev_supported_types", sysfspath) < 0) + return -1; + + if ((dirret = virDirOpenIfExists(&dir, types_path)) < 0) + goto cleanup; + + if (dirret == 0) { + ret = 0; + goto cleanup; + } + + while ((dirret = virDirRead(dir, &entry, types_path)) > 0) { + /* append the type id to the path and read the attributes from there */ + if (virAsprintf(&tmppath, "%s/%s", types_path, entry->d_name) < 0) + goto cleanup; + + if (virMediatedDeviceTypeReadAttrs(tmppath, &mdev_type) < 0) + goto cleanup; + + if (VIR_APPEND_ELEMENT(mdev_types, ntypes, mdev_type) < 0) + goto cleanup; + + VIR_FREE(tmppath); + } + + if (dirret < 0) + goto cleanup; + + VIR_STEAL_PTR(*types, mdev_types); + ret = ntypes; + ntypes = 0; + cleanup: + virMediatedDeviceTypeFree(mdev_type); + for (i = 0; i < ntypes; i++) + virMediatedDeviceTypeFree(mdev_types[i]); + VIR_FREE(mdev_types); + VIR_FREE(types_path); + VIR_FREE(tmppath); + VIR_DIR_CLOSE(dir); + return ret; +} + #else static const char *unsupported = N_("not supported on non-linux platforms"); diff --git a/src/util/virpci.h b/src/util/virpci.h index f1fbe39e6f..794b7e59db 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -25,6 +25,7 @@ # define __VIR_PCI_H__ # include "internal.h" +# include "virmdev.h" # include "virobject.h" # include "virutil.h" @@ -249,4 +250,7 @@ int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType); void virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev); +ssize_t virPCIGetMdevTypes(const char *sysfspath, + virMediatedDeviceType ***types); + #endif /* __VIR_PCI_H__ */