From 7cefe61172cedb1959d56a3c1525ea75f9cae6a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 23 May 2019 11:34:08 +0100 Subject: [PATCH] vz: acquire a pidfile in the driver root directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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/vz/driver.pid In unprivileged libvirtd this ends up locking /run/user/$UID/libvirt/vz/run/driver.pid NB, the latter can vary depending on $XDG_RUNTIME_DIR Signed-off-by: Daniel P. Berrangé --- src/vz/vz_driver.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c index 50c883feca..75430fb0d9 100644 --- a/src/vz/vz_driver.c +++ b/src/vz/vz_driver.c @@ -41,6 +41,7 @@ #include "vircommand.h" #include "configmake.h" #include "virfile.h" +#include "virpidfile.h" #include "virstoragefile.h" #include "virstring.h" #include "cpu/cpu.h" @@ -59,8 +60,13 @@ VIR_LOG_INIT("parallels.parallels_driver"); #define PRLCTL "prlctl" +#define VZ_STATEDIR LOCALSTATEDIR "/run/libvirt/vz" + static virClassPtr vzDriverClass; +static bool vz_driver_privileged; +/* pid file FD, ensures two copies of the driver can't use the same root */ +static int vz_driver_lock_fd = -1; static virMutex vz_driver_lock; static vzDriverPtr vz_driver; static vzConnPtr vz_conn_list; @@ -166,6 +172,11 @@ VIR_ONCE_GLOBAL_INIT(vzDriver); vzDriverPtr vzGetDriverConnection(void) { + if (!vz_driver_privileged) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("vz state driver is not active")); + return NULL; + } virMutexLock(&vz_driver_lock); if (!vz_driver) vz_driver = vzDriverObjNew(); @@ -4090,18 +4101,37 @@ static virConnectDriver vzConnectDriver = { static int vzStateCleanup(void) { - virObjectUnref(vz_driver); - vz_driver = NULL; - virMutexDestroy(&vz_driver_lock); - prlsdkDeinit(); + if (vz_driver_privileged) { + virObjectUnref(vz_driver); + vz_driver = NULL; + if (vz_driver_lock_fd != -1) + virPidFileRelease(VZ_STATEDIR, "driver", vz_driver_lock_fd); + virMutexDestroy(&vz_driver_lock); + prlsdkDeinit(); + } return 0; } static int -vzStateInitialize(bool privileged ATTRIBUTE_UNUSED, +vzStateInitialize(bool privileged, virStateInhibitCallback callback ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED) { + if (!privileged) + return 0; + + vz_driver_privileged = privileged; + + if (virFileMakePathWithMode(VZ_STATEDIR, S_IRWXU) < 0) { + virReportSystemError(errno, _("cannot create state directory '%s'"), + VZ_STATEDIR); + return -1; + } + + if ((vz_driver_lock_fd = + virPidFileAcquire(VZ_STATEDIR, "driver", true, getpid())) < 0) + return -1; + if (prlsdkInit() < 0) { VIR_DEBUG("%s", _("Can't initialize Parallels SDK")); return -1;