On Tue, Mar 10, 2015 at 17:45:07 +0100, Michal Privoznik wrote:
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/conf/network_conf.c | 382 ++++++++++++++++++++++++++++++------------------
1 file changed, 237 insertions(+), 145 deletions(-)
...
int virNetworkBridgeInUse(virNetworkObjListPtr nets,
const char *bridge,
const char *skipname)
{
- size_t i;
- unsigned int ret = 0;
+ virNetworkObjPtr obj;
+ struct virNetworkBridgeInUseHelperData data = {bridge, skipname};
- for (i = 0; i < nets->count; i++) {
- virNetworkObjLock(nets->objs[i]);
- if (nets->objs[i]->def->bridge &&
- STREQ(nets->objs[i]->def->bridge, bridge) &&
- !(skipname && STREQ(nets->objs[i]->def->name, skipname)))
- ret = 1;
- virNetworkObjUnlock(nets->objs[i]);
- }
+ obj = virHashSearch(nets->objs, virNetworkBridgeInUseHelper, &data);
- return ret;
+ return obj != NULL;
}
char *virNetworkAllocateBridge(virNetworkObjListPtr nets,
@@ -4271,6 +4299,52 @@ virNetworkMatch(virNetworkObjPtr netobj,
}
#undef MATCH
+struct virNetworkObjListData {
+ virConnectPtr conn;
+ virNetworkPtr *nets;
+ virNetworkObjListFilter filter;
+ unsigned int flags;
+ int nnets;
+ bool error;
+};
+
+static void
+virNetworkObjListPopulate(void *payload,
+ const void *name ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ struct virNetworkObjListData *data = opaque;
+ virNetworkObjPtr obj = payload;
+ virNetworkPtr net = NULL;
Similarly to the domain objects this will become problematic once you
drop the driver lock. I'm planing to fix the domain version soon, so
I'll need to update this one too as we don't have any prior art.
+
+ if (data->error)
+ return;
+
+ virNetworkObjLock(obj);
+
+ if (data->filter &&
+ !data->filter(data->conn, obj->def))
+ goto cleanup;
+
+ if (!virNetworkMatch(obj, data->flags))
+ goto cleanup;
+
+ if (!data->nets) {
+ data->nnets++;
+ goto cleanup;
+ }
+
+ if (!(net = virGetNetwork(data->conn, obj->def->name,
obj->def->uuid))) {
+ data->error = true;
+ goto cleanup;
+ }
+
+ data->nets[data->nnets++] = net;
+
+ cleanup:
+ virNetworkObjUnlock(obj);
+}
+
...
+static int
+virNetworkObjListPruneHelper(const void *payload,
+ const void *name ATTRIBUTE_UNUSED,
+ const void *opaque)
+{
+ const struct virNetworkObjListPruneHelperData *data = opaque;
+ virNetworkObjPtr obj = (virNetworkObjPtr) payload;
+ int want = 0;
+
+ virNetworkObjLock(obj);
+ want = virNetworkMatch(obj, data->flags);
+ virNetworkObjUnlock(obj);
+ return want;
}
/**
@@ -4428,21 +4534,7 @@ void
virNetworkObjListPrune(virNetworkObjListPtr nets,
unsigned int flags)
{
- size_t i = 0;
+ struct virNetworkObjListPruneHelperData data = {flags};
- while (i < nets->count) {
- virNetworkObjPtr obj = nets->objs[i];
-
- virNetworkObjLock(obj);
-
- if (virNetworkMatch(obj, flags)) {
- virNetworkObjUnlock(obj);
- virNetworkObjFree(obj);
-
- VIR_DELETE_ELEMENT(nets->objs, i, nets->count);
- } else {
- virNetworkObjUnlock(obj);
- i++;
- }
- }
+ virHashRemoveSet(nets->objs, virNetworkObjListPruneHelper, &data);
}
Now that I've persusaded you to add a function like this you converted
the code to the hash table that supports deletion. Oh well :)
ACK
Peter