On 02/12/2018 05:52 AM, Michal Privoznik wrote:
@@ -430,31 +552,64 @@ virNWFilterObjListGetNames(virNWFilterObjListPtr nwfilters,
char **const names,
int maxnames)
{
- int nnames = 0;
+ struct virNWFilterNameData data = {filter, conn, 0, 0, maxnames, names};
Here you don't user .filter = filter while further below you.
The rest looks all good to me.
size_t i;
- virNWFilterDefPtr def;
-
- for (i = 0; i < nwfilters->count && nnames < maxnames; i++) {
- virNWFilterObjPtr obj = nwfilters->objs[i];
- virObjectLock(obj);
- def = obj->def;
- if (!filter || filter(conn, def)) {
- if (VIR_STRDUP(names[nnames], def->name) < 0) {
- virObjectUnlock(obj);
- goto failure;
- }
- nnames++;
- }
- virObjectUnlock(obj);
+
+ virObjectRWLockRead(nwfilters);
+ virHashForEach(nwfilters->objs, virNWFilterObjListCopyNames, &data);
+ virObjectRWUnlock(nwfilters);
+ if (data.oom) {
+ for (i = 0; i < data.numnames; i++)
+ VIR_FREE(data.names[i]);
+ return -1;
+ }
+
+ return data.numnames;
+}
+
+
+struct virNWFilterListData {
+ virConnectPtr conn;
+ virNWFilterPtr *nwfilters;
+ virNWFilterObjListFilter filter;
+ int nnwfilters;
+ bool error;
+};
+
+
+static int
+virNWFilterObjListPopulate(void *payload,
+ const void *name ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ struct virNWFilterListData *data = opaque;
+ virNWFilterObjPtr obj = payload;
+ virNWFilterPtr nwfilter = NULL;
+
+ if (data->error)
+ return 0;
+
+ virObjectLock(obj);
+
+ if (data->filter &&
+ !data->filter(data->conn, obj->def))
+ goto cleanup;
+
+ if (!data->nwfilters) {
+ data->nnwfilters++;
+ goto cleanup;
}
- return nnames;
+ if (!(nwfilter = virGetNWFilter(data->conn, obj->def->name,
obj->def->uuid))) {
+ data->error = true;
+ goto cleanup;
+ }
- failure:
- while (--nnames >= 0)
- VIR_FREE(names[nnames]);
+ data->nwfilters[data->nnwfilters++] = nwfilter;
- return -1;
+ cleanup:
+ virObjectUnlock(obj);
+ return 0;
}
@@ -464,47 +619,33 @@ virNWFilterObjListExport(virConnectPtr conn,
virNWFilterPtr **filters,
virNWFilterObjListFilter filter)
{
- virNWFilterPtr *tmp_filters = NULL;
- int nfilters = 0;
- virNWFilterPtr nwfilter = NULL;
- virNWFilterObjPtr obj = NULL;
- virNWFilterDefPtr def;
- size_t i;
int ret = -1;
+ struct virNWFilterListData data = {.conn = conn, .nwfilters = NULL,
+ .filter = filter, .nnwfilters = 0, .error = false};
- if (!filters) {
- ret = nwfilters->count;
+ virObjectRWLockRead(nwfilters);
+ if (filters && VIR_ALLOC_N(data.nwfilters, virHashSize(nwfilters->objs) +
1) < 0)
goto cleanup;
- }
- if (VIR_ALLOC_N(tmp_filters, nwfilters->count + 1) < 0)
+ virHashForEach(nwfilters->objs, virNWFilterObjListPopulate, &data);
+
+ if (data.error)
goto cleanup;
- for (i = 0; i < nwfilters->count; i++) {
- obj = nwfilters->objs[i];
- virObjectLock(obj);
- def = obj->def;
- if (!filter || filter(conn, def)) {
- if (!(nwfilter = virGetNWFilter(conn, def->name, def->uuid))) {
- virObjectUnlock(obj);
- goto cleanup;
- }
- tmp_filters[nfilters++] = nwfilter;
- }
- virObjectUnlock(obj);
+ if (data.nnwfilters) {
+ /* trim the array to the final size */
+ ignore_value(VIR_REALLOC_N(data.nwfilters, data.nnwfilters + 1));
+ *filters = data.nwfilters;
+ data.nwfilters = NULL;
}
- *filters = tmp_filters;
- tmp_filters = NULL;
- ret = nfilters;
-
+ ret = data.nnwfilters;
cleanup:
- if (tmp_filters) {
- for (i = 0; i < nfilters; i ++)
- virObjectUnref(tmp_filters[i]);
- }
- VIR_FREE(tmp_filters);
+ virObjectRWUnlock(nwfilters);
+ while (data.nwfilters && data.nnwfilters)
+ virObjectUnref(data.nwfilters[--data.nnwfilters]);
+ VIR_FREE(data.nwfilters);
return ret;
}
diff --git a/src/conf/virnwfilterobj.h b/src/conf/virnwfilterobj.h
index 0281bc5f5..caff76e9a 100644
--- a/src/conf/virnwfilterobj.h
+++ b/src/conf/virnwfilterobj.h
@@ -56,9 +56,6 @@ virNWFilterObjWantRemoved(virNWFilterObjPtr obj);
virNWFilterObjListPtr
virNWFilterObjListNew(void);
-void
-virNWFilterObjListFree(virNWFilterObjListPtr nwfilters);
-
void
virNWFilterObjListRemove(virNWFilterObjListPtr nwfilters,
virNWFilterObjPtr obj);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index edda56f80..fe63defb3 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1047,7 +1047,6 @@ virNWFilterObjListExport;
virNWFilterObjListFindByName;
virNWFilterObjListFindByUUID;
virNWFilterObjListFindInstantiateFilter;
-virNWFilterObjListFree;
virNWFilterObjListGetNames;
virNWFilterObjListLoadAllConfigs;
virNWFilterObjListNew;
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index c9bbae422..093844c9e 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -270,7 +270,7 @@ nwfilterStateInitialize(bool privileged,
virNWFilterIPAddrMapShutdown();
err_free_driverstate:
- virNWFilterObjListFree(driver->nwfilters);
+ virObjectUnref(driver->nwfilters);
VIR_FREE(driver);
return -1;
@@ -354,7 +354,7 @@ nwfilterStateCleanup(void)
}
/* free inactive nwfilters */
- virNWFilterObjListFree(driver->nwfilters);
+ virObjectUnref(driver->nwfilters);
virMutexDestroy(&driver->lock);
VIR_FREE(driver);