On 03/05/2012 08:12 PM, Roopa Prabhu wrote:
From: Roopa Prabhu <roprabhu(a)cisco.com>
pciDeviceGetVirtualFunctionInfo returns pf netdevice name and virtual
function index for a given vf. This is just a wrapper around existing functions
to return vf's pf and vf_index with one api call
pciConfigAddressToSysfsfile returns the sysfile pci device link
from a 'struct pci_config_address'
Signed-off-by: Roopa Prabhu <roprabhu(a)cisco.com>
---
src/util/pci.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/util/pci.h | 7 +++++++
2 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/src/util/pci.c b/src/util/pci.c
index c660e8d..c8a5287 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -2081,6 +2081,20 @@ pciSysfsFile(char *pciDeviceName, char **pci_sysfs_device_link)
return 0;
}
+int
+pciConfigAddressToSysfsFile(struct pci_config_address *dev,
+ char **pci_sysfs_device_link)
+{
+ if (virAsprintf(pci_sysfs_device_link,
+ PCI_SYSFS "devices/%04x:%02x:%02x.%x", dev->domain,
+ dev->bus, dev->slot, dev->function) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ return 0;
+}
+
/*
* Returns the network device name of a pci device
*/
@@ -2123,6 +2137,38 @@ out:
return ret;
}
+
+int
+pciDeviceGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
+ char **pfname, int *vf_index)
+{
+ struct pci_config_address *pf_config_address = NULL;
+ char *pf_sysfs_device_path = NULL;
+ int ret = -1;
+
+ if (pciGetPhysicalFunction(vf_sysfs_device_path, &pf_config_address) < 0)
+ return ret;
+
+ if (pciConfigAddressToSysfsFile(pf_config_address,
+ &pf_sysfs_device_path) < 0) {
+
+ VIR_FREE(pf_config_address);
+ return ret;
+ }
+
+ if (pciGetVirtualFunctionIndex(pf_sysfs_device_path, vf_sysfs_device_path,
+ vf_index) < 0)
+ goto cleanup;
+
+ ret = pciDeviceNetName(pf_sysfs_device_path, pfname);
+
+cleanup:
+ VIR_FREE(pf_config_address);
+ VIR_FREE(pf_sysfs_device_path);
+
+ return ret;
+}
+
#else
int
pciGetPhysicalFunction(const char *vf_sysfs_path ATTRIBUTE_UNUSED,
@@ -2170,4 +2216,13 @@ pciDeviceNetName(char *device_link_sysfs_path ATTRIBUTE_UNUSED,
"supported on non-linux platforms"));
return -1;
}
+
+int
+pciDeviceGetVirtualFunctionInfo(const char *vf_sysfs_device_path ATTRIBUTE_UNUSED,
+ char **pfname, int *vf_index ATTRIBUTE_UNUSED)
+{
+ pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciDeviceGetVirtualFunctionInfo
"
+ "is not supported on non-linux platforms"));
+ return -1;
+}
#endif /* __linux__ */
diff --git a/src/util/pci.h b/src/util/pci.h
index 25b5b66..b71bb12 100644
--- a/src/util/pci.h
+++ b/src/util/pci.h
@@ -111,6 +111,9 @@ int pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
const char *vf_sysfs_device_link,
int *vf_index);
+int pciConfigAddressToSysfsFile(struct pci_config_address *dev,
+ char **pci_sysfs_device_link);
+
int pciDeviceNetName(char *device_link_sysfs_path, char **netname);
int pciSysfsFile(char *pciDeviceName, char **pci_sysfs_device_link)
@@ -122,4 +125,8 @@ int pciGetDeviceAddrString(unsigned domain,
unsigned function,
char **pciConfigAddr)
ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK;
+
+int pciDeviceGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
+ char **pfname, int *vf_index);
+
#endif /* __VIR_PCI_H__ */
After already ACKing this, I realized that the new functions weren't
added to libvirt_private.syms. I'm squashing the following in before I push:
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 2639b48..5d37618 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -864,6 +864,7 @@ virNWFilterVarValueGetSimple;
# pci.h
+pciConfigAddressToSysfsFile;
pciDettachDevice;
pciDeviceFileIterate;
pciDeviceGetManaged;
@@ -872,6 +873,7 @@ pciDeviceGetRemoveSlot;
pciDeviceGetReprobe;
pciDeviceGetUnbindFromStub;
pciDeviceGetUsedBy;
+pciDeviceGetVirtualFunctionInfo;
pciDeviceIsAssignable;
pciDeviceIsVirtualFunction;
pciDeviceListAdd;