};
-/*
- * only one filter update allowed
- */
-static virRWLock updateLock;
-static bool initialized;
-
-void
-virNWFilterReadLockFilterUpdates(void)
-{
- virRWLockRead(&updateLock);
-}
-
-
-void
-virNWFilterWriteLockFilterUpdates(void)
-{
- virRWLockWrite(&updateLock);
-}
-
-
-void
-virNWFilterUnlockFilterUpdates(void)
-{
- virRWLockUnlock(&updateLock);
-}
-
-
/*
* attribute names for the rules XML
*/
return virBufferContentAndReset(&buf);
}
+static bool initialized;
static virNWFilterTriggerRebuildCallback rebuildCallback;
static void *rebuildOpaque;
initialized = true;
- if (virRWLockInit(&updateLock) < 0)
- return -1;
-
return 0;
}
if (!initialized)
return;
- virRWLockDestroy(&updateLock);
-
initialized = false;
rebuildCallback = NULL;
rebuildOpaque = NULL;
/* free inactive nwfilters */
virNWFilterObjListFree(driver->nwfilters);
+ virMutexDestroy(&driver->updateLock);
g_clear_pointer(&driver, g_free);
return 0;
driver = g_new0(virNWFilterDriverState, 1);
driver->lockFD = -1;
+ if (virMutexInitRecursive(&driver->updateLock) < 0)
+ goto err_free_driverstate;
+
driver->privileged = privileged;
if (!(driver->nwfilters = virNWFilterObjListNew()))
virNWFilterLearnThreadsTerminate(true);
VIR_WITH_MUTEX_LOCK_GUARD(&driverMutex) {
- virNWFilterWriteLockFilterUpdates();
-
- virNWFilterObjListLoadAllConfigs(driver->nwfilters, driver->configDir);
+ VIR_WITH_MUTEX_LOCK_GUARD(&driver->updateLock) {
+ virNWFilterObjListLoadAllConfigs(driver->nwfilters, driver->configDir);
+ }
- virNWFilterUnlockFilterUpdates();
virNWFilterBuildAll(driver, false);
}
return NULL;
}
- virNWFilterWriteLockFilterUpdates();
-
if (!(def = virNWFilterDefParseString(xml, flags)))
goto cleanup;
if (virNWFilterDefineXMLFlagsEnsureACL(conn, def) < 0)
goto cleanup;
- if (!(obj = virNWFilterObjListAssignDef(driver->nwfilters, def)))
- goto cleanup;
+ VIR_WITH_MUTEX_LOCK_GUARD(&driver->updateLock) {
+ if (!(obj = virNWFilterObjListAssignDef(driver->nwfilters, def)))
+ goto cleanup;
+ }
def = NULL;
objdef = virNWFilterObjGetDef(obj);
virNWFilterDefFree(def);
if (obj)
virNWFilterObjUnlock(obj);
-
- virNWFilterUnlockFilterUpdates();
return nwfilter;
}
virNWFilterDef *def;
int ret = -1;
- virNWFilterWriteLockFilterUpdates();
+ VIR_WITH_MUTEX_LOCK_GUARD(&driver->updateLock) {
+ if (!(obj = nwfilterObjFromNWFilter(nwfilter->uuid)))
+ goto cleanup;
+ def = virNWFilterObjGetDef(obj);
- if (!(obj = nwfilterObjFromNWFilter(nwfilter->uuid)))
- goto cleanup;
- def = virNWFilterObjGetDef(obj);
+ if (virNWFilterUndefineEnsureACL(nwfilter->conn, def) < 0)
+ goto cleanup;
- if (virNWFilterUndefineEnsureACL(nwfilter->conn, def) < 0)
- goto cleanup;
+ if (virNWFilterObjTestUnassignDef(obj) < 0) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s",
+ _("nwfilter is in use"));
+ goto cleanup;
+ }
- if (virNWFilterObjTestUnassignDef(obj) < 0) {
- virReportError(VIR_ERR_OPERATION_INVALID,
- "%s",
- _("nwfilter is in use"));
- goto cleanup;
- }
+ if (virNWFilterDeleteDef(driver->configDir, def) < 0)
+ goto cleanup;
- if (virNWFilterDeleteDef(driver->configDir, def) < 0)
- goto cleanup;
-
- virNWFilterObjListRemove(driver->nwfilters, obj);
- obj = NULL;
+ virNWFilterObjListRemove(driver->nwfilters, obj);
+ obj = NULL;
+ }
ret = 0;
cleanup:
if (obj)
virNWFilterObjUnlock(obj);
- virNWFilterUnlockFilterUpdates();
return ret;
}
if (!(ret = virGetNWFilterBinding(conn, def->portdevname, def->filter)))
goto cleanup;
- virNWFilterReadLockFilterUpdates();
- if (virNWFilterInstantiateFilter(driver, def) < 0) {
- virNWFilterUnlockFilterUpdates();
- virNWFilterBindingObjListRemove(driver->bindings, obj);
- g_clear_pointer(&ret, virObjectUnref);
- goto cleanup;
+ VIR_WITH_MUTEX_LOCK_GUARD(&driver->updateLock) {
+ if (virNWFilterInstantiateFilter(driver, def) < 0) {
+ virNWFilterBindingObjListRemove(driver->bindings, obj);
+ g_clear_pointer(&ret, virObjectUnref);
+ goto cleanup;
+ }
}
- virNWFilterUnlockFilterUpdates();
+
virNWFilterBindingObjSave(obj, driver->bindingDir);
cleanup:
if (virNWFilterBindingDeleteEnsureACL(binding->conn, def) < 0)
goto cleanup;
- virNWFilterReadLockFilterUpdates();
- virNWFilterTeardownFilter(def);
- virNWFilterUnlockFilterUpdates();
+ VIR_WITH_MUTEX_LOCK_GUARD(&driver->updateLock) {
+ virNWFilterTeardownFilter(def);
+ }
virNWFilterBindingObjDelete(obj, driver->bindingDir);
virNWFilterBindingObjListRemove(driver->bindings, obj);
NULL
};
-/*
- * Serializes instantiation of filters.
- *
- * When instantiating a filter, we need to resolve references
- * to other filters and acquire locks on them.
- *
- * We retain a lock on the referenced filter once found.
- * The order in which the locks are acquired depends on
- * the order in which filters reference each other.
- *
- * Filter A:
- * Reference Filter C
- * Reference Filter D
- *
- * Filter B:
- * Reference Filter D
- * Reference Filter C
- *
- * In one example, we lock A, C, D, in the other example
- * we lock A, D, C.
- *
- * Because C & D are locked in differing orders we are
- * once again at risk of deadlocks.
- *
- * There can be multiple levels of recursion, so it is
- * not viable to determine the lock order upfront, it
- * has to be done as we traverse the tree.
- *
- * Thus we serialize any code that needs to traverse
- * the filter references.
- *
- * This covers the following APIs:
- *
- * virNWFilterDefineXML
- * virNWFilterUndefine
- * virNWFilterBindingCreate
- * virNWFilterBindingDelete
- *
- * In addition to the asynchronous filter instantiation
- * triggered by the IP address learning backends.
- */
-static virMutex updateMutex;
-
int virNWFilterTechDriversInit(bool privileged)
{
size_t i = 0;
VIR_DEBUG("Initializing NWFilter technology drivers");
- if (virMutexInitRecursive(&updateMutex) < 0)
- return -1;
-
while (filter_tech_drivers[i]) {
if (!(filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED))
filter_tech_drivers[i]->init(privileged);
filter_tech_drivers[i]->shutdown();
i++;
}
- virMutexDestroy(&updateMutex);
}
bool *foundNewFilter)
{
int ifindex;
- VIR_LOCK_GUARD lock = virLockGuardLock(&updateMutex);
/* after grabbing the filter update lock check for the interface; if
it's not there anymore its filters will be or are being removed
virNWFilterBindingDef *binding,
int ifindex)
{
- int rc;
+ int rc = 0;
bool foundNewFilter = false;
- VIR_LOCK_GUARD lock = virLockGuardLock(&updateMutex);
-
- virNWFilterReadLockFilterUpdates();
+ VIR_LOCK_GUARD lock = virLockGuardLock(&driver->updateLock);
rc = virNWFilterInstantiateFilterUpdate(driver, true,
binding, ifindex,
}
}
- virNWFilterUnlockFilterUpdates();
-
return rc;
}
int
virNWFilterTeardownFilter(virNWFilterBindingDef *binding)
{
- VIR_LOCK_GUARD lock = virLockGuardLock(&updateMutex);
-
return _virNWFilterTeardownFilter(binding->portdevname);
}