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(a)redhat.com>
---
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