]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: pci: Introduce virPCIGetMdevTypes helper
authorErik Skultety <eskultet@redhat.com>
Fri, 19 Jan 2018 19:33:43 +0000 (20:33 +0100)
committerErik Skultety <eskultet@redhat.com>
Mon, 29 Jan 2018 14:34:30 +0000 (15:34 +0100)
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 <eskultet@redhat.com>
src/libvirt_private.syms
src/util/virpci.c
src/util/virpci.h

index c52c3ec385c1586873fb57880998ce838a6e3010..24d94ca8106b1f38f2666d2d16205f742dce1905 100644 (file)
@@ -2457,6 +2457,7 @@ virPCIDeviceWaitForCleanup;
 virPCIEDeviceInfoFree;
 virPCIGetDeviceAddressFromSysfsLink;
 virPCIGetHeaderType;
+virPCIGetMdevTypes;
 virPCIGetNetName;
 virPCIGetPhysicalFunction;
 virPCIGetVirtualFunctionIndex;
index fe57bef32774e3fea970556ab089e246c7a09063..b6a5739cadc74647b3c0b0d92458799b6c65f7f0 100644 (file)
@@ -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");
 
index f1fbe39e6f17edf70c0f2a0dd2aa674866de424c..794b7e59db518c9369c2f78323858c64726a7ba5 100644 (file)
@@ -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__ */