[libvirt] [PATCH] test: Implement virConnectListAllInterfaces

Cole Robinson crobinso at redhat.com
Tue Jul 10 21:09:21 UTC 2018


This adds some generic virinterfaceobj code, roughly matching what
is used by other stateful drivers like network, storage, etc.

Signed-off-by: Cole Robinson <crobinso at redhat.com>
---
 src/conf/virinterfaceobj.c | 105 +++++++++++++++++++++++++++++++++++++
 src/conf/virinterfaceobj.h |   7 +++
 src/libvirt_private.syms   |   1 +
 src/test/test_driver.c     |  15 ++++++
 4 files changed, 128 insertions(+)

diff --git a/src/conf/virinterfaceobj.c b/src/conf/virinterfaceobj.c
index a1d7346eb2..87ce188117 100644
--- a/src/conf/virinterfaceobj.c
+++ b/src/conf/virinterfaceobj.c
@@ -241,6 +241,111 @@ virInterfaceObjListFindByName(virInterfaceObjListPtr interfaces,
     return obj;
 }
 
+#define MATCH(FLAG) (flags & (FLAG))
+static bool
+virInterfaceMatch(virInterfaceObjPtr obj,
+                  unsigned int flags)
+{
+    /* filter by active state */
+    if (MATCH(VIR_CONNECT_LIST_INTERFACES_FILTERS_ACTIVE) &&
+        !((MATCH(VIR_CONNECT_LIST_INTERFACES_ACTIVE) &&
+           virInterfaceObjIsActive(obj)) ||
+          (MATCH(VIR_CONNECT_LIST_INTERFACES_INACTIVE) &&
+           !virInterfaceObjIsActive(obj))))
+        return false;
+
+    return true;
+}
+#undef MATCH
+
+
+struct virInterfaceObjListData {
+    virConnectPtr conn;
+    virInterfacePtr *ifaces;
+    virInterfaceObjListFilter filter;
+    unsigned int flags;
+    int nifaces;
+    bool error;
+};
+
+static int
+virInterfaceObjListPopulate(void *payload,
+                            const void *name ATTRIBUTE_UNUSED,
+                            void *opaque)
+{
+    struct virInterfaceObjListData *data = opaque;
+    virInterfaceObjPtr obj = payload;
+    virInterfacePtr iface = NULL;
+
+    if (data->error)
+        return 0;
+
+    virObjectLock(obj);
+
+    if (data->filter &&
+        !data->filter(data->conn, obj->def))
+        goto cleanup;
+
+    if (!virInterfaceMatch(obj, data->flags))
+        goto cleanup;
+
+    if (!data->ifaces) {
+        data->nifaces++;
+        goto cleanup;
+    }
+
+    if (!(iface = virGetInterface(data->conn, obj->def->name, obj->def->mac))) {
+        data->error = true;
+        goto cleanup;
+    }
+
+    data->ifaces[data->nifaces++] = iface;
+
+ cleanup:
+    virObjectUnlock(obj);
+    return 0;
+}
+
+
+int
+virInterfaceObjListExport(virConnectPtr conn,
+                          virInterfaceObjListPtr ifaceobjs,
+                          virInterfacePtr **ifaces,
+                          virInterfaceObjListFilter filter,
+                          unsigned int flags)
+{
+    int ret = -1;
+    struct virInterfaceObjListData data = {
+        .conn = conn, .ifaces = NULL, .filter = filter, .flags = flags,
+        .nifaces = 0, .error = false };
+
+    virObjectRWLockRead(ifaceobjs);
+    if (ifaces && VIR_ALLOC_N(data.ifaces,
+                              virHashSize(ifaceobjs->objsName) + 1) < 0)
+        goto cleanup;
+
+    virHashForEach(ifaceobjs->objsName, virInterfaceObjListPopulate, &data);
+
+    if (data.error)
+        goto cleanup;
+
+    if (data.ifaces) {
+        /* trim the array to the final size */
+        ignore_value(VIR_REALLOC_N(data.ifaces, data.nifaces + 1));
+        *ifaces = data.ifaces;
+        data.ifaces = NULL;
+    }
+
+    ret = data.nifaces;
+ cleanup:
+    virObjectRWUnlock(ifaceobjs);
+    while (data.ifaces && data.nifaces)
+        virObjectUnref(data.ifaces[--data.nifaces]);
+
+    VIR_FREE(data.ifaces);
+    return ret;
+}
+
 
 void
 virInterfaceObjListDispose(void *obj)
diff --git a/src/conf/virinterfaceobj.h b/src/conf/virinterfaceobj.h
index 799d38038f..33d2dda05d 100644
--- a/src/conf/virinterfaceobj.h
+++ b/src/conf/virinterfaceobj.h
@@ -82,4 +82,11 @@ virInterfaceObjListGetNames(virInterfaceObjListPtr interfaces,
                             char **const names,
                             int maxnames);
 
+int
+virInterfaceObjListExport(virConnectPtr conn,
+                          virInterfaceObjListPtr ifaceobjs,
+                          virInterfacePtr **ifaces,
+                          virInterfaceObjListFilter filter,
+                          unsigned int flags);
+
 #endif /* __VIRINTERFACEOBJ_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e688981c3e..ec5ed0cc81 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -961,6 +961,7 @@ virInterfaceObjGetDef;
 virInterfaceObjIsActive;
 virInterfaceObjListAssignDef;
 virInterfaceObjListClone;
+virInterfaceObjListExport;
 virInterfaceObjListFindByMACString;
 virInterfaceObjListFindByName;
 virInterfaceObjListGetNames;
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 5494d51017..951d9c4151 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -3828,6 +3828,20 @@ testConnectListDefinedInterfaces(virConnectPtr conn,
 }
 
 
+static int
+testConnectListAllInterfaces(virConnectPtr conn,
+                             virInterfacePtr **ifaces,
+                             unsigned int flags)
+{
+    testDriverPtr privconn = conn->privateData;
+
+    virCheckFlags(VIR_CONNECT_LIST_INTERFACES_FILTERS_ACTIVE, -1);
+
+    return virInterfaceObjListExport(conn, privconn->ifaces, ifaces,
+                                     NULL, flags);
+}
+
+
 static virInterfacePtr
 testInterfaceLookupByName(virConnectPtr conn,
                           const char *name)
@@ -6944,6 +6958,7 @@ static virInterfaceDriver testInterfaceDriver = {
     .connectListInterfaces = testConnectListInterfaces, /* 0.7.0 */
     .connectNumOfDefinedInterfaces = testConnectNumOfDefinedInterfaces, /* 0.7.0 */
     .connectListDefinedInterfaces = testConnectListDefinedInterfaces, /* 0.7.0 */
+    .connectListAllInterfaces = testConnectListAllInterfaces, /* 4.6.0 */
     .interfaceLookupByName = testInterfaceLookupByName, /* 0.7.0 */
     .interfaceLookupByMACString = testInterfaceLookupByMACString, /* 0.7.0 */
     .interfaceGetXMLDesc = testInterfaceGetXMLDesc, /* 0.7.0 */
-- 
2.17.1




More information about the libvir-list mailing list