[libvirt] [PATCH 07/12] nwfilter: acquire a pidfile in the driver root directory

Daniel P. Berrangé berrange at redhat.com
Wed Jul 10 15:47:36 UTC 2019


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 at 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




More information about the libvir-list mailing list