[libvirt] [PATCH 1/2] nodedev: sysfs: Set PCI_PHYSICAL_FUNCTION flag more carefully
Laine Stump
laine at laine.org
Mon May 23 19:21:15 UTC 2016
On 05/23/2016 07:53 AM, Andrea Bolognani wrote:
> The flag was set if virPCIGetPhysicalFunction() did not return
> an error; unfortunately, the 'physfn' sysfs file not being
> present is not considered an error, which means that the flag
> was set pretty much unconditionally.
This behavior is the result of commit c8b1a83605:
https://www.redhat.com/archives/libvir-list/2016-May/msg01348.html
Prior to this, virPCIGetPhysicalFunction had returned the return value
from virPCIGetDeviceAddressFromSysfsLink(), which would be -1 if the
physfn file didn't exist. That patch discards the return value and
hardcodes a "return 0".
I think that virPCIGetPhysicalFunction should be restored to its
original glory (No, I didn't write it). Either that, or the other caller
to virPCIGetPhysicalFunction (virPCIGetVirtualFunctionInfo) should also
be fixed so that it doesn't crash due to the changed semantics of
virPCIGetPhysicalFunction.
(A more correct fix may be to change the semantics of
virPCIGetPhysicalFunction() to return -1 only in the case of a bonafide
error (OOM, failure to parse the contents of an existing physfn file),
but that would also require modifying
virPCIGetDeviceAddressFromSysfsLink() to return 0/-1 rather than a
virPCIDeviceAddresPtr so that we can tell the difference between "no
physfn" and "there was a physfn but I encountered some other error". In
other words - 1) revert commit c1faf309 (part of the same "coverity
fixes" series as x8b1a83605), then 2) adjust the function to set *bdf =
0 and return 0 when the physfn file doesn't exist.)
>
> This, in turn, caused libvirtd to crash in
> virNodeDeviceDefFormat(), where the presence of the flag
> is considered a reliable indicator of the fact that
> pci_dev.physical_function has been filled in.
>
> Change the code to check pci_dev.physical_function before
> setting the flag.
> ---
> src/node_device/node_device_linux_sysfs.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 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;
> +
> + 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;
> }
>
More information about the libvir-list
mailing list