[libvirt] [PATCH 02/12] secrets: acquire a pidfile in the driver root directory

Daniel P. Berrangé berrange at redhat.com
Wed Jul 10 15:47:31 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/secrets/driver.pid

In unprivileged libvirtd this ends up locking

  /run/user/$UID/libvirt/secrets/run/driver.pid

NB, the latter can vary depending on $XDG_RUNTIME_DIR

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/secret/secret_driver.c | 44 +++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
index ac85f5d195..9344948db4 100644
--- a/src/secret/secret_driver.c
+++ b/src/secret/secret_driver.c
@@ -37,6 +37,7 @@
 #include "viruuid.h"
 #include "virerror.h"
 #include "virfile.h"
+#include "virpidfile.h"
 #include "configmake.h"
 #include "virstring.h"
 #include "viraccessapicheck.h"
@@ -56,8 +57,12 @@ struct _virSecretDriverState {
     virMutex lock;
     bool privileged; /* readonly */
     virSecretObjListPtr secrets;
+    char *stateDir;
     char *configDir;
 
+    /* pid file FD, ensures two copies of the driver can't use the same root */
+    int lockFD;
+
     /* Immutable pointer, self-locking APIs */
     virObjectEventStatePtr secretEventState;
 };
@@ -434,6 +439,10 @@ secretStateCleanup(void)
 
     virObjectUnref(driver->secretEventState);
 
+    if (driver->lockFD != -1)
+        virPidFileRelease(driver->stateDir, "driver", driver->lockFD);
+
+    VIR_FREE(driver->stateDir);
     secretDriverUnlock();
     virMutexDestroy(&driver->lock);
     VIR_FREE(driver);
@@ -447,11 +456,10 @@ secretStateInitialize(bool privileged,
                       virStateInhibitCallback callback ATTRIBUTE_UNUSED,
                       void *opaque ATTRIBUTE_UNUSED)
 {
-    char *base = NULL;
-
     if (VIR_ALLOC(driver) < 0)
         return -1;
 
+    driver->lockFD = -1;
     if (virMutexInit(&driver->lock) < 0) {
         VIR_FREE(driver);
         return -1;
@@ -462,15 +470,26 @@ secretStateInitialize(bool privileged,
     driver->privileged = privileged;
 
     if (privileged) {
-        if (VIR_STRDUP(base, SYSCONFDIR "/libvirt") < 0)
+        if (virAsprintf(&driver->configDir,
+                        "%s/libvirt/secrets", SYSCONFDIR) < 0)
+            goto error;
+        if (virAsprintf(&driver->stateDir,
+                        "%s/run/libvirt/secrets", LOCALSTATEDIR) < 0)
             goto error;
     } else {
-        if (!(base = virGetUserConfigDirectory()))
+        VIR_AUTOFREE(char *) rundir = NULL;
+        VIR_AUTOFREE(char *) cfgdir = NULL;
+
+        if (!(cfgdir = virGetUserConfigDirectory()))
+            goto error;
+        if (virAsprintf(&driver->configDir, "%s/secrets/", cfgdir) < 0)
+            goto error;
+
+        if (!(rundir = virGetUserRuntimeDirectory()))
+            goto error;
+        if (virAsprintf(&driver->stateDir, "%s/secrets/run", rundir) < 0)
             goto error;
     }
-    if (virAsprintf(&driver->configDir, "%s/secrets", base) < 0)
-        goto error;
-    VIR_FREE(base);
 
     if (virFileMakePathWithMode(driver->configDir, S_IRWXU) < 0) {
         virReportSystemError(errno, _("cannot create config directory '%s'"),
@@ -478,6 +497,16 @@ secretStateInitialize(bool privileged,
         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 (!(driver->secrets = virSecretObjListNew()))
         goto error;
 
@@ -488,7 +517,6 @@ secretStateInitialize(bool privileged,
     return 0;
 
  error:
-    VIR_FREE(base);
     secretDriverUnlock();
     secretStateCleanup();
     return -1;
-- 
2.21.0




More information about the libvir-list mailing list