]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Added Function virNetDevGetVirtualFunctions
authorShradha Shah <sshah@solarflare.com>
Wed, 14 Dec 2011 10:50:14 +0000 (10:50 +0000)
committerEric Blake <eblake@redhat.com>
Wed, 11 Jan 2012 20:01:16 +0000 (13:01 -0700)
This functions enables us to get the Virtual Functions attached to
a Physical function given the name of a SR-IOV physical functio.

In order to accomplish the task, added a getter function pciGetDeviceAddrString
to get the BDF of the Virtual Function in a char array.

src/util/pci.c
src/util/pci.h
src/util/virnetdev.c
src/util/virnetdev.h

index 5e09c2fb91d5a693d6e28974dcd5abca6310073b..17cde81bf921dc834e528570766bf491bebe449b 100644 (file)
@@ -1293,6 +1293,30 @@ pciReadDeviceID(pciDevice *dev, const char *id_name)
     return id_str;
 }
 
+int
+pciGetDeviceAddrString(unsigned domain,
+                       unsigned bus,
+                       unsigned slot,
+                       unsigned function,
+                       char **pciConfigAddr)
+{
+    pciDevice *dev = NULL;
+    int ret = -1;
+
+    dev = pciGetDevice(domain, bus, slot, function);
+    if (dev != NULL) {
+        if ((*pciConfigAddr = strdup(dev->name)) == NULL) {
+            virReportOOMError();
+            goto cleanup;
+        }
+        ret = 0;
+    }
+
+cleanup:
+    pciFreeDevice(dev);
+    return ret;
+}
+
 pciDevice *
 pciGetDevice(unsigned domain,
              unsigned bus,
index fe62a257e217af44a8ed5b880a19db038eb35aa5..5493e0aed0f90729170f63e2186713ff42c6ee97 100644 (file)
@@ -112,4 +112,10 @@ int pciDeviceNetName(char *device_link_sysfs_path, char **netname);
 int pciSysfsFile(char *pciDeviceName, char **pci_sysfs_device_link)
     ATTRIBUTE_RETURN_CHECK;
 
+int pciGetDeviceAddrString(unsigned domain,
+                           unsigned bus,
+                           unsigned slot,
+                           unsigned function,
+                           char **pciConfigAddr)
+    ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK;
 #endif /* __VIR_PCI_H__ */
index 115f46ae341b81e8c92927522332d26d8e12acde..06c825d3b9f5b2db547ea5b461e10dbc6c434541 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2011 Red Hat, Inc.
+ * Copyright (C) 2007-2012 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -969,6 +969,77 @@ virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname,
     return 0;
 }
 
+/**
+ * virNetDevGetVirtualFunctions:
+ *
+ * @pfname : name of the physical function interface name
+ * @vfname: array that will hold the interface names of the virtual_functions
+ * @n_vfname: pointer to the number of virtual functions
+ *
+ * Returns 0 on success and -1 on failure
+ */
+
+int
+virNetDevGetVirtualFunctions(const char *pfname,
+                             char ***vfname,
+                             unsigned int *n_vfname)
+{
+    int ret = -1, i;
+    char *pf_sysfs_device_link = NULL;
+    char *pci_sysfs_device_link = NULL;
+    struct pci_config_address **virt_fns;
+    char *pciConfigAddr;
+
+    if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0)
+        return ret;
+
+    if (pciGetVirtualFunctions(pf_sysfs_device_link, &virt_fns,
+                               n_vfname) < 0)
+        goto cleanup;
+
+    if (VIR_ALLOC_N(*vfname, *n_vfname) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    for (i = 0; i < *n_vfname; i++)
+    {
+        if (pciGetDeviceAddrString(virt_fns[i]->domain,
+                                   virt_fns[i]->bus,
+                                   virt_fns[i]->slot,
+                                   virt_fns[i]->function,
+                                   &pciConfigAddr) < 0) {
+            virReportSystemError(ENOSYS, "%s",
+                                 _("Failed to get PCI Config Address String"));
+            goto cleanup;
+        }
+        if (pciSysfsFile(pciConfigAddr, &pci_sysfs_device_link) < 0) {
+            virReportSystemError(ENOSYS, "%s",
+                                 _("Failed to get PCI SYSFS file"));
+            goto cleanup;
+        }
+
+        if (pciDeviceNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0) {
+            virReportSystemError(ENOSYS, "%s",
+                                 _("Failed to get interface name of the VF"));
+            goto cleanup;
+        }
+    }
+
+    ret = 0;
+
+cleanup:
+    if (ret < 0)
+        VIR_FREE(*vfname);
+    for (i = 0; i < *n_vfname; i++)
+        VIR_FREE(virt_fns[i]);
+    VIR_FREE(virt_fns);
+    VIR_FREE(pf_sysfs_device_link);
+    VIR_FREE(pci_sysfs_device_link);
+    VIR_FREE(pciConfigAddr);
+    return ret;
+}
+
 /**
  * virNetDevIsVirtualFunction:
  * @ifname : name of the interface
@@ -1056,6 +1127,17 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
     return ret;
 }
 #else /* !__linux__ */
+
+int
+virNetDevGetVirtualFunctions(const char *pfname ATTRIBUTE_UNUSED,
+                             char ***vfname ATTRIBUTE_UNUSED,
+                             unsigned int *n_vfname ATTRIBUTE_UNUSED)
+{
+    virReportSystemError(ENOSYS, "%s",
+                         _("Unable to get virtual functions on this platfornm"));
+    return -1;
+}
+
 int
 virNetDevIsVirtualFunction(const char *ifname ATTRIBUTE_UNUSED)
 {
index 13ba1dab7a288f3d5858da445a77ee75b1095c3f..7845e251ca83980139d1c584dc96a446dfbd7e2f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2011 Red Hat, Inc.
+ * Copyright (C) 2007-2012 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -99,4 +99,10 @@ int virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname,
 int virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
 
+int virNetDevGetVirtualFunctions(const char *pfname,
+                                 char ***vfname,
+                                 unsigned int *n_vfname)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+    ATTRIBUTE_RETURN_CHECK;
+
 #endif /* __VIR_NETDEV_H__ */