The nwfilter conf update mutex previously serialized
updates to the internal data structures for firewall
rules, and updates to the firewall itself. Since the
former is going to be turned into a read/write lock
instead of a mutex, a new lock is required to serialize
access to the firewall itself.
With this new lock, the lock ordering rules will be
for virNWFilter{Define,Undefine}
1. nwfilter driver lock
2. nwfilter update lock
3. virt driver lock
4. domain object lock
5. gentech driver lock
and VM start
1. nwfilter update lock
2. virt driver lock
3. domain object lock
4. gentech driver lock
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/nwfilter/nwfilter_driver.c | 4 +++-
src/nwfilter/nwfilter_gentech_driver.c | 19 +++++++++++++++++--
src/nwfilter/nwfilter_gentech_driver.h | 2 +-
3 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index d21dd82..112e8cb 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -200,7 +200,8 @@ nwfilterStateInitialize(bool privileged,
if (virNWFilterDHCPSnoopInit() < 0)
goto err_exit_learnshutdown;
- virNWFilterTechDriversInit(privileged);
+ if (virNWFilterTechDriversInit(privileged) < 0)
+ goto err_dhcpsnoop_shutdown;
if (virNWFilterConfLayerInit(virNWFilterDomainFWUpdateCB,
driverState) < 0)
@@ -251,6 +252,7 @@ error:
err_techdrivers_shutdown:
virNWFilterTechDriversShutdown();
+err_dhcpsnoop_shutdown:
virNWFilterDHCPSnoopShutdown();
err_exit_learnshutdown:
virNWFilterLearnShutdown();
diff --git a/src/nwfilter/nwfilter_gentech_driver.c
b/src/nwfilter/nwfilter_gentech_driver.c
index 89913cf8..d500963 100644
--- a/src/nwfilter/nwfilter_gentech_driver.c
+++ b/src/nwfilter/nwfilter_gentech_driver.c
@@ -55,15 +55,21 @@ static virNWFilterTechDriverPtr filter_tech_drivers[] = {
NULL
};
+/* Serializes execution of iptables/ip6tables/ebtables calls */
+static virMutex updateMutex;
-void virNWFilterTechDriversInit(bool privileged) {
+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);
i++;
}
+ return 0;
}
@@ -74,6 +80,7 @@ void virNWFilterTechDriversShutdown(void) {
filter_tech_drivers[i]->shutdown();
i++;
}
+ virMutexDestroy(&updateMutex);
}
@@ -936,6 +943,7 @@ _virNWFilterInstantiateFilter(virNWFilterDriverStatePtr driver,
int rc;
virNWFilterLockFilterUpdates();
+ virMutexLock(&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
@@ -965,6 +973,7 @@ _virNWFilterInstantiateFilter(virNWFilterDriverStatePtr driver,
cleanup:
virNWFilterUnlockFilterUpdates();
+ virMutexUnlock(&updateMutex);
return rc;
}
@@ -985,6 +994,7 @@ virNWFilterInstantiateFilterLate(virNWFilterDriverStatePtr driver,
bool foundNewFilter = false;
virNWFilterLockFilterUpdates();
+ virMutexLock(&updateMutex);
rc = __virNWFilterInstantiateFilter(driver,
vmuuid,
@@ -1010,6 +1020,7 @@ virNWFilterInstantiateFilterLate(virNWFilterDriverStatePtr driver,
}
virNWFilterUnlockFilterUpdates();
+ virMutexUnlock(&updateMutex);
return rc;
}
@@ -1133,7 +1144,11 @@ _virNWFilterTeardownFilter(const char *ifname)
int
virNWFilterTeardownFilter(const virDomainNetDef *net)
{
- return _virNWFilterTeardownFilter(net->ifname);
+ int ret;
+ virMutexLock(&updateMutex);
+ ret = _virNWFilterTeardownFilter(net->ifname);
+ virMutexUnlock(&updateMutex);
+ return ret;
}
diff --git a/src/nwfilter/nwfilter_gentech_driver.h
b/src/nwfilter/nwfilter_gentech_driver.h
index f4789e1..d72e040 100644
--- a/src/nwfilter/nwfilter_gentech_driver.h
+++ b/src/nwfilter/nwfilter_gentech_driver.h
@@ -31,7 +31,7 @@ virNWFilterTechDriverPtr virNWFilterTechDriverForName(const char
*name);
int virNWFilterRuleInstAddData(virNWFilterRuleInstPtr res,
void *data);
-void virNWFilterTechDriversInit(bool privileged);
+int virNWFilterTechDriversInit(bool privileged);
void virNWFilterTechDriversShutdown(void);
enum instCase {
--
1.8.4.2