When we allow multiple instances of the driver for the same user
account, using a separate root directory, we need to ensure mutual
exclusion. Use a pidfile to guarantee this.
In privileged libvirtd this ends up locking
/var/run/libvirt/nwfilter/driver.pid
In unprivileged libvirtd this ends up locking
/run/user/$UID/libvirt/nwfilter/run/driver.pid
NB, the latter can vary depending on $XDG_RUNTIME_DIR
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/conf/virnwfilterobj.h | 4 ++++
src/nwfilter/nwfilter_driver.c | 19 +++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/src/conf/virnwfilterobj.h b/src/conf/virnwfilterobj.h
index bdf5c51fe2..a6bdfb3864 100644
--- a/src/conf/virnwfilterobj.h
+++ b/src/conf/virnwfilterobj.h
@@ -36,10 +36,14 @@ struct _virNWFilterDriverState {
virMutex lock;
bool privileged;
+ /* pid file FD, ensures two copies of the driver can't use the same root */
+ int lockFD;
+
virNWFilterObjListPtr nwfilters;
virNWFilterBindingObjListPtr bindings;
+ char *stateDir;
char *configDir;
char *bindingDir;
};
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index fdfc6f48fa..43561241f6 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -38,6 +38,7 @@
#include "nwfilter_gentech_driver.h"
#include "configmake.h"
#include "virfile.h"
+#include "virpidfile.h"
#include "virstring.h"
#include "viraccessapicheck.h"
@@ -188,6 +189,7 @@ nwfilterStateInitialize(bool privileged,
if (VIR_ALLOC(driver) < 0)
return -1;
+ driver->lockFD = -1;
if (virMutexInit(&driver->lock) < 0)
goto err_free_driverstate;
@@ -203,6 +205,19 @@ nwfilterStateInitialize(bool privileged,
nwfilterDriverLock();
+ if (VIR_STRDUP(driver->stateDir, LOCALSTATEDIR "/run/libvirt/nwfilter")
< 0)
+ goto error;
+
+ if (virFileMakePathWithMode(driver->stateDir, S_IRWXU) < 0) {
+ virReportSystemError(errno, _("cannot create state directory
'%s'"),
+ driver->stateDir);
+ goto error;
+ }
+
+ if ((driver->lockFD =
+ virPidFileAcquire(driver->stateDir, "driver", true, getpid())) <
0)
+ goto error;
+
if (virNWFilterIPAddrMapInit() < 0)
goto err_free_driverstate;
if (virNWFilterLearnInit() < 0)
@@ -346,6 +361,10 @@ nwfilterStateCleanup(void)
nwfilterDriverRemoveDBusMatches();
+ if (driver->lockFD != -1)
+ virPidFileRelease(driver->stateDir, "driver",
driver->lockFD);
+
+ VIR_FREE(driver->stateDir);
VIR_FREE(driver->configDir);
VIR_FREE(driver->bindingDir);
nwfilterDriverUnlock();
--
2.21.0