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