On Mon, Sep 27, 2021 at 10:30:49PM +0300, Dmitrii Shcherbakov wrote:
> Add helper functions to virpci to provide means of checking for a VPD
> file presence and for VPD resource retrieval using the PCI VPD parser.
> 
> The added test assesses the basic functionality of VPD retrieval while
> the full parser is tested by virpcivpdtest.
> 
> Signed-off-by: Dmitrii Shcherbakov <dmitrii.shcherba...@canonical.com>
> ---
>  src/libvirt_private.syms |  2 ++
>  src/util/virpci.c        | 62 ++++++++++++++++++++++++++++++++++++++
>  src/util/virpci.h        |  3 ++
>  tests/virpcimock.c       | 30 +++++++++++++++++++
>  tests/virpcitest.c       | 64 ++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 161 insertions(+)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index bb9b380599..ebee46ce9b 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -2988,7 +2988,9 @@ virPCIDeviceGetReprobe;
>  virPCIDeviceGetStubDriver;
>  virPCIDeviceGetUnbindFromStub;
>  virPCIDeviceGetUsedBy;
> +virPCIDeviceGetVPDResources;
>  virPCIDeviceHasPCIExpressLink;
> +virPCIDeviceHasVPD;
>  virPCIDeviceIsAssignable;
>  virPCIDeviceIsPCIExpress;
>  virPCIDeviceListAdd;
> diff --git a/src/util/virpci.c b/src/util/virpci.c
> index f307580a53..480d91c17f 100644
> --- a/src/util/virpci.c
> +++ b/src/util/virpci.c
> @@ -37,6 +37,7 @@
>  #include "virkmod.h"
>  #include "virstring.h"
>  #include "viralloc.h"
> +#include "virpcivpd.h"
>  
>  VIR_LOG_INIT("util.pci");
>  
> @@ -2640,6 +2641,53 @@ virPCIGetVirtualFunctionInfo(const char 
> *vf_sysfs_device_path,
>      return 0;
>  }
>  
> +
> +gboolean
> +virPCIDeviceHasVPD(virPCIDevice *dev)
> +{
> +    g_autofree char *vpdPath = NULL;
> +    vpdPath = virPCIFile(dev->name, "vpd");
> +    if (!virFileExists(vpdPath)) {
> +        VIR_INFO("Device VPD file does not exist %s", vpdPath);

IIUC this is normal case for most PCI devices, so DEBUG level is
better.

> +        return false;
> +    } else if (!virFileIsRegular(vpdPath)) {
> +        VIR_WARN("VPD path does not point to a regular file %s", vpdPath);
> +        return false;
> +    }
> +    return true;
> +}
> +
> +/**
> + * virPCIDeviceGetVPDResources:
> + * @dev: a PCI device to get a list of VPD resources for.
> + *
> + * Obtain resources stored in the PCI device's Vital Product Data (VPD).
> + * VPD is optional in both PCI Local Bus and PCIe specifications so there is
> + * no guarantee it will be there for a particular device.
> + *
> + * Returns: a pointer to a list of VPDResource types which needs to be freed 
> by the caller or
> + * NULL if getting it failed for some reason.
> + */
> +GList *
> +virPCIDeviceGetVPDResources(virPCIDevice *dev)
> +{
> +    g_autofree char *vpdPath = NULL;
> +    int fd;
> +
> +    vpdPath = virPCIFile(dev->name, "vpd");
> +    if (!virPCIDeviceHasVPD(dev)) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, _("Device %s does not have a 
> VPD"),
> +                virPCIDeviceGetName(dev));

Nit-pick - align with the '(' above.

> +        return NULL;
> +    }
> +    if ((fd = open(vpdPath, O_RDONLY)) < 0) {
> +        virReportSystemError(-fd,
> +                             _("Failed to open a VPD file '%s'"), vpdPath);
> +        return NULL;
> +    }
> +    return virPCIVPDParse(fd);

Nothing is closing 'fd' here, unless virPCIVPDParse is doing it, which
I would consider an unexpected design.


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

Reply via email to