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)) +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 +virNodeDevCapTypeFromString; virNodeDevCapTypeToString; virNodeDevCapsDefFree; virNodeDeviceAssignDef; @@ -865,6 +866,7 @@ virNodeDeviceFindBySysfsPath; virNodeDeviceGetParentHost; virNodeDeviceGetWWNs; virNodeDeviceHasCap; +virNodeDeviceList; virNodeDeviceObjListFree; virNodeDeviceObjLock; virNodeDeviceObjRemove; -- 1.7.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list