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 | 15 ++++++++++++---
src/nwfilter/nwfilter_gentech_driver.h | 2 +-
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index 2972731..8518e90 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 f0e78ed..af7505e 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);
}
@@ -935,7 +942,7 @@ _virNWFilterInstantiateFilter(virNWFilterDriverStatePtr driver,
int ifindex;
int rc;
-
+ 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
(while holding the lock) and we don't want to build new ones */
@@ -963,7 +970,7 @@ _virNWFilterInstantiateFilter(virNWFilterDriverStatePtr driver,
foundNewFilter);
cleanup:
-
+ virMutexUnlock(&updateMutex);
return rc;
}
@@ -982,6 +989,7 @@ virNWFilterInstantiateFilterLate(virNWFilterDriverStatePtr driver,
int rc;
bool foundNewFilter = false;
+ virMutexLock(&updateMutex);
rc = __virNWFilterInstantiateFilter(driver,
vmuuid,
true,
@@ -1005,6 +1013,7 @@ virNWFilterInstantiateFilterLate(virNWFilterDriverStatePtr driver,
}
}
+ virMutexUnlock(&updateMutex);
return rc;
}
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