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