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/qemu/driver.pid
In unprivileged libvirtd this ends up locking
/run/user/$UID/libvirt/qemu/run/driver.pid
NB, the latter can vary depending on $XDG_RUNTIME_DIR
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/qemu/qemu_conf.h | 3 +++
src/qemu/qemu_driver.c | 9 +++++++++
2 files changed, 12 insertions(+)
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index e51514a344..2229b76e89 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -221,6 +221,9 @@ struct _virQEMUDriver {
* then lockless thereafter */
virQEMUDriverConfigPtr config;
+ /* pid file FD, ensures two copies of the driver can't use the same root */
+ int lockFD;
+
/* Immutable pointer, self-locking APIs */
virThreadPoolPtr workerPool;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5a75f23981..8bc069d3e2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -70,6 +70,7 @@
#include "node_device_conf.h"
#include "virpci.h"
#include "virusb.h"
+#include "virpidfile.h"
#include "virprocess.h"
#include "libvirt_internal.h"
#include "virxml.h"
@@ -587,6 +588,8 @@ qemuStateInitialize(bool privileged,
if (VIR_ALLOC(qemu_driver) < 0)
return -1;
+ qemu_driver->lockFD = -1;
+
if (virMutexInit(&qemu_driver->lock) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot initialize mutex"));
@@ -673,6 +676,10 @@ qemuStateInitialize(bool privileged,
goto error;
}
+ if ((qemu_driver->lockFD =
+ virPidFileAcquire(cfg->stateDir, "driver", true, getpid())) <
0)
+ goto error;
+
qemu_driver->qemuImgBinary = virFindFileInPath("qemu-img");
if (!(qemu_driver->lockManager =
@@ -1032,6 +1039,8 @@ qemuStateCleanup(void)
if (!qemu_driver)
return -1;
+ if (qemu_driver->lockFD != -1)
+ virPidFileRelease(qemu_driver->config->stateDir, "driver",
qemu_driver->lockFD);
virThreadPoolFree(qemu_driver->workerPool);
virObjectUnref(qemu_driver->config);
virObjectUnref(qemu_driver->hostdevMgr);
--
2.21.0