nwfilter: Introduce virNWFilterObjListFindInstantiateFilter

Create a common API to handle the instantiation path filter lookup.

Signed-off-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
John Ferlan 2017-05-30 17:27:04 -04:00
parent 1cceb220f7
commit 8a75cc4fcc
4 changed files with 71 additions and 81 deletions

View File

@ -190,6 +190,29 @@ virNWFilterObjListFindByName(virNWFilterObjListPtr nwfilters,
} }
virNWFilterObjPtr
virNWFilterObjListFindInstantiateFilter(virNWFilterObjListPtr nwfilters,
const char *filtername)
{
virNWFilterObjPtr obj;
if (!(obj = virNWFilterObjListFindByName(nwfilters, filtername))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("referenced filter '%s' is missing"), filtername);
return NULL;
}
if (virNWFilterObjWantRemoved(obj)) {
virReportError(VIR_ERR_NO_NWFILTER,
_("Filter '%s' is in use."), filtername);
virNWFilterObjUnlock(obj);
return NULL;
}
return obj;
}
static int static int
_virNWFilterObjListDefLoopDetect(virNWFilterObjListPtr nwfilters, _virNWFilterObjListDefLoopDetect(virNWFilterObjListPtr nwfilters,
virNWFilterDefPtr def, virNWFilterDefPtr def,

View File

@ -68,6 +68,10 @@ virNWFilterObjPtr
virNWFilterObjListFindByName(virNWFilterObjListPtr nwfilters, virNWFilterObjListFindByName(virNWFilterObjListPtr nwfilters,
const char *name); const char *name);
virNWFilterObjPtr
virNWFilterObjListFindInstantiateFilter(virNWFilterObjListPtr nwfilters,
const char *filtername);
virNWFilterObjPtr virNWFilterObjPtr
virNWFilterObjListAssignDef(virNWFilterObjListPtr nwfilters, virNWFilterObjListAssignDef(virNWFilterObjListPtr nwfilters,
virNWFilterDefPtr def); virNWFilterDefPtr def);

View File

@ -984,6 +984,7 @@ virNWFilterObjListAssignDef;
virNWFilterObjListExport; virNWFilterObjListExport;
virNWFilterObjListFindByName; virNWFilterObjListFindByName;
virNWFilterObjListFindByUUID; virNWFilterObjListFindByUUID;
virNWFilterObjListFindInstantiateFilter;
virNWFilterObjListFree; virNWFilterObjListFree;
virNWFilterObjListGetNames; virNWFilterObjListGetNames;
virNWFilterObjListLoadAllConfigs; virNWFilterObjListLoadAllConfigs;

View File

@ -61,11 +61,11 @@ static virNWFilterTechDriverPtr filter_tech_drivers[] = {
* to avoid lock ordering deadlocks. eg virNWFilterInstantiateFilterUpdate * to avoid lock ordering deadlocks. eg virNWFilterInstantiateFilterUpdate
* will hold a lock on a virNWFilterObjPtr. This in turn invokes * will hold a lock on a virNWFilterObjPtr. This in turn invokes
* virNWFilterDoInstantiate which invokes virNWFilterDetermineMissingVarsRec * virNWFilterDoInstantiate which invokes virNWFilterDetermineMissingVarsRec
* which invokes virNWFilterObjListFindByName. This iterates over every single * which invokes virNWFilterObjListFindInstantiateFilter. This iterates over
* virNWFilterObjPtr in the list. So if 2 threads try to instantiate a * every single virNWFilterObjPtr in the list. So if 2 threads try to
* filter in parallel, they'll both hold 1 lock at the top level in * instantiate a filter in parallel, they'll both hold 1 lock at the top level
* virNWFilterInstantiateFilterUpdate which will cause the other thread * in virNWFilterInstantiateFilterUpdate which will cause the other thread
* to deadlock in virNWFilterObjListFindByName. * to deadlock in virNWFilterObjListFindInstantiateFilter.
* *
* XXX better long term solution is to make virNWFilterObjList use a * XXX better long term solution is to make virNWFilterObjList use a
* hash table as is done for virDomainObjList. You can then get * hash table as is done for virDomainObjList. You can then get
@ -384,20 +384,9 @@ virNWFilterIncludeDefToRuleInst(virNWFilterDriverStatePtr driver,
int ret = -1; int ret = -1;
VIR_DEBUG("Instantiating filter %s", inc->filterref); VIR_DEBUG("Instantiating filter %s", inc->filterref);
obj = virNWFilterObjListFindByName(driver->nwfilters, if (!(obj = virNWFilterObjListFindInstantiateFilter(driver->nwfilters,
inc->filterref); inc->filterref)))
if (!obj) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("referenced filter '%s' is missing"),
inc->filterref);
goto cleanup; goto cleanup;
}
if (virNWFilterObjWantRemoved(obj)) {
virReportError(VIR_ERR_NO_NWFILTER,
_("Filter '%s' is in use."),
inc->filterref);
goto cleanup;
}
/* create a temporary hashmap for depth-first tree traversal */ /* create a temporary hashmap for depth-first tree traversal */
if (!(tmpvars = virNWFilterCreateVarsFrom(inc->params, if (!(tmpvars = virNWFilterCreateVarsFrom(inc->params,
@ -510,6 +499,7 @@ virNWFilterDetermineMissingVarsRec(virNWFilterDefPtr filter,
virNWFilterDefPtr next_filter; virNWFilterDefPtr next_filter;
virNWFilterDefPtr newNext_filter; virNWFilterDefPtr newNext_filter;
virNWFilterVarValuePtr val; virNWFilterVarValuePtr val;
virNWFilterHashTablePtr tmpvars;
for (i = 0; i < filter->nentries; i++) { for (i = 0; i < filter->nentries; i++) {
virNWFilterRuleDefPtr rule = filter->filterEntries[i]->rule; virNWFilterRuleDefPtr rule = filter->filterEntries[i]->rule;
@ -546,23 +536,14 @@ virNWFilterDetermineMissingVarsRec(virNWFilterDefPtr filter,
break; break;
} else if (inc) { } else if (inc) {
VIR_DEBUG("Following filter %s", inc->filterref); VIR_DEBUG("Following filter %s", inc->filterref);
obj = virNWFilterObjListFindByName(driver->nwfilters, inc->filterref); if (!(obj = virNWFilterObjListFindInstantiateFilter(driver->nwfilters,
if (obj) { inc->filterref))) {
if (virNWFilterObjWantRemoved(obj)) {
virReportError(VIR_ERR_NO_NWFILTER,
_("Filter '%s' is in use."),
inc->filterref);
rc = -1; rc = -1;
virNWFilterObjUnlock(obj);
break; break;
} }
/* create a temporary hashmap for depth-first tree traversal */ /* create a temporary hashmap for depth-first tree traversal */
virNWFilterHashTablePtr tmpvars = if (!(tmpvars = virNWFilterCreateVarsFrom(inc->params, vars))) {
virNWFilterCreateVarsFrom(inc->params,
vars);
if (!tmpvars) {
rc = -1; rc = -1;
virNWFilterObjUnlock(obj); virNWFilterObjUnlock(obj);
break; break;
@ -591,13 +572,6 @@ virNWFilterDetermineMissingVarsRec(virNWFilterDefPtr filter,
virNWFilterObjUnlock(obj); virNWFilterObjUnlock(obj);
if (rc < 0) if (rc < 0)
break; break;
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("referenced filter '%s' is missing"),
inc->filterref);
rc = -1;
break;
}
} }
} }
return rc; return rc;
@ -814,21 +788,9 @@ virNWFilterInstantiateFilterUpdate(virNWFilterDriverStatePtr driver,
VIR_DEBUG("filter name: %s", filtername); VIR_DEBUG("filter name: %s", filtername);
obj = virNWFilterObjListFindByName(driver->nwfilters, filtername); if (!(obj = virNWFilterObjListFindInstantiateFilter(driver->nwfilters,
if (!obj) { filtername)))
virReportError(VIR_ERR_NO_NWFILTER,
_("Could not find filter '%s'"),
filtername);
return -1; return -1;
}
if (virNWFilterObjWantRemoved(obj)) {
virReportError(VIR_ERR_NO_NWFILTER,
_("Filter '%s' is in use."),
filtername);
rc = -1;
goto err_exit;
}
virMacAddrFormat(macaddr, vmmacaddr); virMacAddrFormat(macaddr, vmmacaddr);
if (VIR_STRDUP(str_macaddr, vmmacaddr) < 0) { if (VIR_STRDUP(str_macaddr, vmmacaddr) < 0) {