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);
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list