[libvirt] [PATCH 3/7] list: Add helpers for listing node devices

Peter Krempa pkrempa at redhat.com
Thu Sep 6 20:40:39 UTC 2012


On 09/05/12 07:34, Osier Yang wrote:
> src/conf/node_device_conf.h:
>    * New macro VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_CAP
>    * Declare virNodeDeviceList
>
> src/conf/node_device_conf.c:
>    * New helpers virNodeDeviceCapMatch, virNodeDeviceMatch.
>      virNodeDeviceCapMatch looks up the list of all the caps the device
>      support, to see if the device support the cap type.
>    * Implement virNodeDeviceList
>
> src/libvirt_private.syms:
>    * Export virNodeDeviceList
>    * Export virNodeDevCapTypeFromString
> ---
>   src/conf/node_device_conf.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>   src/conf/node_device_conf.h |   16 +++++++
>   src/libvirt_private.syms    |    2 +
>   3 files changed, 121 insertions(+), 0 deletions(-)
>
> diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
> index 048c70c..60462b8 100644
> --- a/src/conf/node_device_conf.c
> +++ b/src/conf/node_device_conf.c
> @@ -1432,3 +1432,106 @@ void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj)
>   {
>       virMutexUnlock(&obj->lock);
>   }
> +
> +static bool
> +virNodeDeviceCapMatch(virNodeDeviceObjPtr devobj,
> +                      int type)
> +{
> +    virNodeDevCapsDefPtr cap = NULL;
> +
> +    for (cap = devobj->def->caps; cap; cap = cap->next) {
> +        if (type == cap->type)
> +            return true;
> +    }
> +
> +    return false;
> +}
> +
> +#define MATCH(FLAG) (flags & (FLAG))

I probably couldn't resist the temptation to abuse the MATCH macro to 
get rid of half of the lines below. But this is not worth the effort and 
what you have is correct.

> +static bool
> +virNodeDeviceMatch(virNodeDeviceObjPtr devobj,
> +                   unsigned int flags)
> +{
> +    /* filter by cap type */
> +    if (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_CAP)) {
> +        if (!((MATCH(VIR_CONNECT_LIST_NODE_DEVICES_CAP_SYSTEM) &&
> +               virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_SYSTEM))        ||
> +              (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV) &&
> +               virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_PCI_DEV))       ||
> +              (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV) &&
> +               virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_USB_DEV))       ||
> +              (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE) &&
> +               virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_USB_INTERFACE)) ||
> +              (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET) &&
> +               virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_NET))           ||
> +              (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST) &&
> +               virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_SCSI_HOST))     ||
> +              (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_TARGET) &&
> +               virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_SCSI_TARGET))   ||
> +              (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI) &&
> +               virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_SCSI))          ||
> +              (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE) &&
> +               virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_STORAGE))))
> +            return false;
> +    }
> +
> +    return true;
> +}
> +#undef MATCH
> +
> +int
> +virNodeDeviceList(virConnectPtr conn,
> +                  virNodeDeviceObjList devobjs,
> +                  virNodeDevicePtr **devices,
> +                  unsigned int flags)
> +{
> +    virNodeDevicePtr *tmp_devices = NULL;
> +    virNodeDevicePtr device = NULL;
> +    int ndevices = 0;
> +    int ret = -1;
> +    int i;
> +
> +    if (devices) {
> +        if (VIR_ALLOC_N(tmp_devices, devobjs.count + 1) < 0) {
> +            virReportOOMError();
> +            goto cleanup;
> +        }
> +    }
> +
> +    for (i = 0; i < devobjs.count; i++) {
> +        virNodeDeviceObjPtr devobj = devobjs.objs[i];
> +        virNodeDeviceObjLock(devobj);
> +        if (virNodeDeviceMatch(devobj, flags)) {
> +            if (devices) {
> +                if (!(device = virGetNodeDevice(conn,
> +                                                devobj->def->name))) {
> +                    virNodeDeviceObjUnlock(devobj);
> +                    goto cleanup;
> +                }
> +                tmp_devices[ndevices] = device;
> +            }
> +            ndevices++;
> +        }
> +        virNodeDeviceObjUnlock(devobj);
> +    }
> +
> +    if (tmp_devices) {
> +        /* trim the array to the final size */
> +        ignore_value(VIR_REALLOC_N(tmp_devices, ndevices + 1));
> +        *devices = tmp_devices;
> +        tmp_devices = NULL;
> +    }
> +
> +    ret = ndevices;
> +
> +cleanup:
> +    if (tmp_devices) {
> +        for (i = 0; i < ndevices; i++) {
> +            if (tmp_devices[i])
> +                virNodeDeviceFree(tmp_devices[i]);
> +        }
> +    }
> +
> +    VIR_FREE(tmp_devices);
> +    return ret;
> +}
> diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
> index 41c9fcc..b8ee881 100644
> --- a/src/conf/node_device_conf.h
> +++ b/src/conf/node_device_conf.h
> @@ -261,4 +261,20 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps);
>   void virNodeDeviceObjLock(virNodeDeviceObjPtr obj);
>   void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj);
>
> +# define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_CAP \
> +                (VIR_CONNECT_LIST_NODE_DEVICES_CAP_SYSTEM        | \
> +                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV       | \
> +                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV       | \
> +                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE | \
> +                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET           | \
> +                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST     | \
> +                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_TARGET   | \
> +                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI          | \
> +                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE)
> +
> +int virNodeDeviceList(virConnectPtr conn,
> +                      virNodeDeviceObjList devobjs,
> +                      virNodeDevicePtr **devices,
> +                      unsigned int flags);
> +
>   #endif /* __VIR_NODE_DEVICE_CONF_H__ */
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 7464c59..43928f1 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -852,6 +852,7 @@ virPortGroupFindByName;
>
>
>   # node_device_conf.h
> +a;

Is this related directly to this API adition? If not, split it out. (Do 
a separate patch doing this change and then rebase)

>   virNodeDevCapTypeToString;
>   virNodeDevCapsDefFree;
>   virNodeDeviceAssignDef;
> @@ -865,6 +866,7 @@ virNodeDeviceFindBySysfsPath;
>   virNodeDeviceGetParentHost;
>   virNodeDeviceGetWWNs;
>   virNodeDeviceHasCap;
> +virNodeDeviceList;
>   virNodeDeviceObjListFree;
>   virNodeDeviceObjLock;
>   virNodeDeviceObjRemove;
>

ACK if you clarify/remove adding virNodeDevCapTypeFromString to symbols 
in this patch.

Peter




More information about the libvir-list mailing list