qemu: acquire a pidfile in the driver root directory

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@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2019-05-23 11:34:08 +01:00
parent 95f8e3237e
commit 1af03e2714
2 changed files with 12 additions and 0 deletions

View File

@ -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;

View File

@ -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);