After the previous commit we have VIR_LOCK_MANAGER_ACQUIRE_KEEP_OPEN flag. This is not enough because it will keep connection open for only one instance of drvAcquire + drvRelease call. And when starting up a domain there will be a lot of such calls as there will be a lot of paths to relabel and thus lock. Therfore, VIR_LOCK_MANAGER_RELEASE_KEEP_OPEN flag was introduced which allows us to keep connection open even after the drvAcquire + drvRelease pair. In order to close the connection after all locking has been done virLockManagerCloseConn is introduced. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/locking/lock_driver.h | 22 ++++++++++++++++++++++ src/locking/lock_driver_lockd.c | 24 ++++++++++++++++++++++++ src/locking/lock_driver_nop.c | 8 ++++++++ src/locking/lock_manager.c | 11 +++++++++++ src/locking/lock_manager.h | 4 ++++ 6 files changed, 70 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 42f15f117e..bca5a51ba0 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1294,6 +1294,7 @@ virDomainLockProcessStart; virLockManagerAcquire; virLockManagerAddResource; virLockManagerClearResources; +virLockManagerCloseConn; virLockManagerFree; virLockManagerInquire; virLockManagerNew; diff --git a/src/locking/lock_driver.h b/src/locking/lock_driver.h index 7e3ffc58b5..d81767707b 100644 --- a/src/locking/lock_driver.h +++ b/src/locking/lock_driver.h @@ -282,6 +282,27 @@ typedef int (*virLockDriverRelease)(virLockManagerPtr man, char **state, unsigned int flags); +/** + * virLockDriverCloseConn: + * @man: the lock manager context + * @flags: optional flags, currently unused + * + * Close any connection that was saved via + * VIR_LOCK_MANAGER_ACQUIRE_KEEP_OPEN or + * VIR_LOCK_MANAGER_RELEASE_KEEP_OPEN flags. + * However, if there is still a resource locked, do not actually + * close the connection as it would result in killing the + * resource owner. This is similar to refcounting when all + * threads call virLockDriverCloseConn() but only the last one + * actually closes the connection. + * + * Returns: 0 on success and connection not actually closed, + * 1 on success and connection closed, + * -1 otherwise + */ +typedef int (*virLockDriverCloseConn)(virLockManagerPtr man, + unsigned int flags); + /** * virLockDriverInquire: * @manager: the lock manager context @@ -328,6 +349,7 @@ struct _virLockDriver { virLockDriverAcquire drvAcquire; virLockDriverRelease drvRelease; + virLockDriverCloseConn drvCloseConn; virLockDriverInquire drvInquire; }; diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c index 14f9eae760..aec768b0df 100644 --- a/src/locking/lock_driver_lockd.c +++ b/src/locking/lock_driver_lockd.c @@ -937,6 +937,28 @@ static int virLockManagerLockDaemonRelease(virLockManagerPtr lock, } +static int virLockManagerLockDaemonCloseConn(virLockManagerPtr lock, + unsigned int flags) +{ + virLockManagerLockDaemonPrivatePtr priv = lock->privateData; + + virCheckFlags(0, -1); + + if (priv->clientRefs) + return 0; + + virNetClientClose(priv->client); + virObjectUnref(priv->client); + virObjectUnref(priv->program); + + priv->client = NULL; + priv->program = NULL; + priv->counter = 0; + + return 1; +} + + static int virLockManagerLockDaemonInquire(virLockManagerPtr lock ATTRIBUTE_UNUSED, char **state, unsigned int flags) @@ -966,5 +988,7 @@ virLockDriver virLockDriverImpl = .drvAcquire = virLockManagerLockDaemonAcquire, .drvRelease = virLockManagerLockDaemonRelease, + .drvCloseConn = virLockManagerLockDaemonCloseConn, + .drvInquire = virLockManagerLockDaemonInquire, }; diff --git a/src/locking/lock_driver_nop.c b/src/locking/lock_driver_nop.c index 26b36061fb..52f78a4721 100644 --- a/src/locking/lock_driver_nop.c +++ b/src/locking/lock_driver_nop.c @@ -102,6 +102,12 @@ static int virLockManagerNopInquire(virLockManagerPtr lock ATTRIBUTE_UNUSED, return 0; } +static int virLockManagerLockNopCloseConn(virLockManagerPtr lock ATTRIBUTE_UNUSED, + unsigned int flags_unused ATTRIBUTE_UNUSED) +{ + return 1; +} + static void virLockManagerNopFree(virLockManagerPtr lock ATTRIBUTE_UNUSED) { } @@ -123,5 +129,7 @@ virLockDriver virLockDriverNop = .drvAcquire = virLockManagerNopAcquire, .drvRelease = virLockManagerNopRelease, + .drvCloseConn = virLockManagerLockNopCloseConn, + .drvInquire = virLockManagerNopInquire, }; diff --git a/src/locking/lock_manager.c b/src/locking/lock_manager.c index 292b142c14..30a0fd996e 100644 --- a/src/locking/lock_manager.c +++ b/src/locking/lock_manager.c @@ -382,6 +382,17 @@ int virLockManagerRelease(virLockManagerPtr lock, } +int virLockManagerCloseConn(virLockManagerPtr lock, + unsigned int flags) +{ + VIR_DEBUG("lock=%p flags=0x%x", lock, flags); + + CHECK_MANAGER(drvCloseConn, -1); + + return lock->driver->drvCloseConn(lock, flags); +} + + int virLockManagerInquire(virLockManagerPtr lock, char **state, unsigned int flags) diff --git a/src/locking/lock_manager.h b/src/locking/lock_manager.h index 8e0049ce0b..3a0ad12969 100644 --- a/src/locking/lock_manager.h +++ b/src/locking/lock_manager.h @@ -64,6 +64,10 @@ int virLockManagerAcquire(virLockManagerPtr manager, int virLockManagerRelease(virLockManagerPtr manager, char **state, unsigned int flags); + +int virLockManagerCloseConn(virLockManagerPtr lock, + unsigned int flags); + int virLockManagerInquire(virLockManagerPtr manager, char **state, unsigned int flags); -- 2.16.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list