
On 05/24/2016 07:11 AM, Andrea Bolognani wrote:
Commit c8b1a83605e4 changed the function, making it impossible for callers to be able to tell whether a non-negative return value means "physical function address found and parsed correctly" or "couldn't find corresponding physical function".
The important difference between the two being that, in the latter case, the returned pointer is NULL and should never, ever be dereferenced.
In order to cope with these changes, the callers have to be updated. Some documentation has also been added to the function, so that callers know how to handle the return value and returned data properly. --- src/node_device/node_device_linux_sysfs.c | 10 ++++++++-- src/util/virpci.c | 18 ++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c index 24a6a2e..b337d2d 100644 --- a/src/node_device/node_device_linux_sysfs.c +++ b/src/node_device/node_device_linux_sysfs.c @@ -154,19 +154,25 @@ nodeDeviceSysfsGetPCISRIOVCaps(const char *sysfsPath, data->pci_dev.flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION; data->pci_dev.flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION;
- if (!virPCIGetPhysicalFunction(sysfsPath, &data->pci_dev.physical_function)) + ret = virPCIGetPhysicalFunction(sysfsPath, + &data->pci_dev.physical_function); + if (ret < 0) + goto out;
I avoid adding "out:" labels, and use "cleanup:" instead, even if there currently isn't any cleanup done there (and if there isn't any cleanup to be done, why goto anyway?)
+ + if (data->pci_dev.physical_function) data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION;
ret = virPCIGetVirtualFunctions(sysfsPath, &data->pci_dev.virtual_functions, &data->pci_dev.num_virtual_functions, &data->pci_dev.max_virtual_functions); if (ret < 0) - return ret; + goto out;
if (data->pci_dev.num_virtual_functions > 0 || data->pci_dev.max_virtual_functions > 0) data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION;
+ out: return ret; }
diff --git a/src/util/virpci.c b/src/util/virpci.c index 3d18bb3..e8dc987 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -2478,8 +2478,19 @@ virPCIGetDeviceAddressFromSysfsLink(const char *device_link) return bdf; }
-/* - * Returns Physical function given a virtual function +/** + * virPCIGetPhysicalFunction: + * @vf_sysfs_path: sysfs path for the virtual function + * @pf: where to store the physical function's address + * + * Given @vf_sysfs_path, this function will store the pointer + * to a newly-allocated virPCIDeviceAddress in @pf. + * + * @pf might be NULL if @vf_sysfs_path does not point to a + * virtual function. If it's not NULL, then it should be + * freed by the caller when no longer needed. + * + * Returns: >=0 on success, <0 on failure
As long as you're here, just to be safe, how about having virPCIGetPhysicalFunction set "*pf = NULL" at the beginning so that it's NULL even if there is an OOM error and the caller hasn't initialized it? (Yeah, I know that will "never ever" happen. But as long as we're being boy scouts, we might as well do it up right :-))
*/ int virPCIGetPhysicalFunction(const char *vf_sysfs_path, @@ -2719,6 +2730,9 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path, if (virPCIGetPhysicalFunction(vf_sysfs_device_path, &pf_config_address) < 0) return ret;
+ if (!pf_config_address) + return ret; + if (virPCIDeviceAddressGetSysfsFile(pf_config_address, &pf_sysfs_device_path) < 0) {
ACK.