When the test suite is running, we don't want to be triggering the
startup of daemons for the secondary drivers. Thus we must provide a way
to set a custom connection for the secondary drivers, to override the
default logic which opens a new connection.
This will also be useful for code where we have a whole set of separate
functions calls all needing the secret driver. Currently the connection
to the secret driver is opened & closed many times in quick
succession. This will allow us to pre-open a connection temporarily,
improving the performance of startup.
Reviewed-by: John Ferlan <jferlan(a)redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/driver.c | 184 +++++++++++++++++++++++++++++++++++++++++++++--
src/driver.h | 7 ++
src/libvirt_private.syms | 6 ++
3 files changed, 191 insertions(+), 6 deletions(-)
diff --git a/src/driver.c b/src/driver.c
index a6a7ff925a..52e1ae345a 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -28,6 +28,7 @@
#include "viralloc.h"
#include "virfile.h"
#include "virlog.h"
+#include "virthread.h"
#include "configmake.h"
VIR_LOG_INIT("driver");
@@ -168,32 +169,203 @@ virDriverLoadModule(const char *name,
/* XXX unload modules, but we can't until we can unregister libvirt drivers */
+virThreadLocal connectInterface;
+virThreadLocal connectNetwork;
+virThreadLocal connectNWFilter;
+virThreadLocal connectNodeDev;
+virThreadLocal connectSecret;
+virThreadLocal connectStorage;
+
+static int
+virConnectCacheOnceInit(void)
+{
+ if (virThreadLocalInit(&connectInterface, NULL) < 0)
+ return -1;
+ if (virThreadLocalInit(&connectNetwork, NULL) < 0)
+ return -1;
+ if (virThreadLocalInit(&connectNWFilter, NULL) < 0)
+ return -1;
+ if (virThreadLocalInit(&connectNodeDev, NULL) < 0)
+ return -1;
+ if (virThreadLocalInit(&connectSecret, NULL) < 0)
+ return -1;
+ if (virThreadLocalInit(&connectStorage, NULL) < 0)
+ return -1;
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virConnectCache);
+
virConnectPtr virGetConnectInterface(void)
{
- return virConnectOpen(geteuid() == 0 ? "interface:///system" :
"interface:///session");
+ virConnectPtr conn;
+
+ if (virConnectCacheInitialize() < 0)
+ return NULL;
+
+ conn = virThreadLocalGet(&connectInterface);
+ if (conn) {
+ VIR_DEBUG("Return cached interface connection %p", conn);
+ virObjectRef(conn);
+ } else {
+ conn = virConnectOpen(geteuid() == 0 ? "interface:///system" :
"interface:///session");
+ VIR_DEBUG("Opened new interface connection %p", conn);
+ }
+ return conn;
}
virConnectPtr virGetConnectNetwork(void)
{
- return virConnectOpen(geteuid() == 0 ? "network:///system" :
"network:///session");
+ virConnectPtr conn;
+
+ if (virConnectCacheInitialize() < 0)
+ return NULL;
+
+ conn = virThreadLocalGet(&connectNetwork);
+ if (conn) {
+ VIR_DEBUG("Return cached network connection %p", conn);
+ virObjectRef(conn);
+ } else {
+ conn = virConnectOpen(geteuid() == 0 ? "network:///system" :
"network:///session");
+ VIR_DEBUG("Opened new network connection %p", conn);
+ }
+ return conn;
}
virConnectPtr virGetConnectNWFilter(void)
{
- return virConnectOpen(geteuid() == 0 ? "nwfilter:///system" :
"nwfilter:///session");
+ virConnectPtr conn;
+
+ if (virConnectCacheInitialize() < 0)
+ return NULL;
+
+ conn = virThreadLocalGet(&connectNWFilter);
+ if (conn) {
+ VIR_DEBUG("Return cached nwfilter connection %p", conn);
+ virObjectRef(conn);
+ } else {
+ conn = virConnectOpen(geteuid() == 0 ? "nwfilter:///system" :
"nwfilter:///session");
+ VIR_DEBUG("Opened new nwfilter connection %p", conn);
+ }
+ return conn;
}
virConnectPtr virGetConnectNodeDev(void)
{
- return virConnectOpen(geteuid() == 0 ? "nodedev:///system" :
"nodedev:///session");
+ virConnectPtr conn;
+
+ if (virConnectCacheInitialize() < 0)
+ return NULL;
+
+ conn = virThreadLocalGet(&connectNodeDev);
+ if (conn) {
+ VIR_DEBUG("Return cached nodedev connection %p", conn);
+ virObjectRef(conn);
+ } else {
+ conn = virConnectOpen(geteuid() == 0 ? "nodedev:///system" :
"nodedev:///session");
+ VIR_DEBUG("Opened new nodedev connection %p", conn);
+ }
+ return conn;
}
virConnectPtr virGetConnectSecret(void)
{
- return virConnectOpen(geteuid() == 0 ? "secret:///system" :
"secret:///session");
+ virConnectPtr conn;
+
+ if (virConnectCacheInitialize() < 0)
+ return NULL;
+
+ conn = virThreadLocalGet(&connectSecret);
+ if (conn) {
+ VIR_DEBUG("Return cached secret connection %p", conn);
+ virObjectRef(conn);
+ } else {
+ conn = virConnectOpen(geteuid() == 0 ? "secret:///system" :
"secret:///session");
+ VIR_DEBUG("Opened new secret connection %p", conn);
+ }
+ return conn;
}
virConnectPtr virGetConnectStorage(void)
{
- return virConnectOpen(geteuid() == 0 ? "storage:///system" :
"storage:///session");
+ virConnectPtr conn;
+
+ if (virConnectCacheInitialize() < 0)
+ return NULL;
+
+ conn = virThreadLocalGet(&connectStorage);
+ if (conn) {
+ VIR_DEBUG("Return cached storage connection %p", conn);
+ virObjectRef(conn);
+ } else {
+ conn = virConnectOpen(geteuid() == 0 ? "storage:///system" :
"storage:///session");
+ VIR_DEBUG("Opened new storage connection %p", conn);
+ }
+ return conn;
+}
+
+
+int
+virSetConnectInterface(virConnectPtr conn)
+{
+ if (virConnectCacheInitialize() < 0)
+ return -1;
+
+ VIR_DEBUG("Override interface connection with %p", conn);
+ return virThreadLocalSet(&connectInterface, conn);
+}
+
+
+int
+virSetConnectNetwork(virConnectPtr conn)
+{
+ if (virConnectCacheInitialize() < 0)
+ return -1;
+
+ VIR_DEBUG("Override network connection with %p", conn);
+ return virThreadLocalSet(&connectNetwork, conn);
+}
+
+
+int
+virSetConnectNWFilter(virConnectPtr conn)
+{
+ if (virConnectCacheInitialize() < 0)
+ return -1;
+
+ VIR_DEBUG("Override nwfilter connection with %p", conn);
+ return virThreadLocalSet(&connectNWFilter, conn);
+}
+
+
+int
+virSetConnectNodeDev(virConnectPtr conn)
+{
+ if (virConnectCacheInitialize() < 0)
+ return -1;
+
+ VIR_DEBUG("Override nodedev connection with %p", conn);
+ return virThreadLocalSet(&connectNodeDev, conn);
+}
+
+
+int
+virSetConnectSecret(virConnectPtr conn)
+{
+ if (virConnectCacheInitialize() < 0)
+ return -1;
+
+ VIR_DEBUG("Override secret connection with %p", conn);
+ return virThreadLocalSet(&connectSecret, conn);
+}
+
+
+int
+virSetConnectStorage(virConnectPtr conn)
+{
+ if (virConnectCacheInitialize() < 0)
+ return -1;
+
+ VIR_DEBUG("Override storage connection with %p", conn);
+ return virThreadLocalSet(&connectStorage, conn);
}
diff --git a/src/driver.h b/src/driver.h
index fe0cec0923..c86da85481 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -112,4 +112,11 @@ virConnectPtr virGetConnectNodeDev(void);
virConnectPtr virGetConnectSecret(void);
virConnectPtr virGetConnectStorage(void);
+int virSetConnectInterface(virConnectPtr conn);
+int virSetConnectNetwork(virConnectPtr conn);
+int virSetConnectNWFilter(virConnectPtr conn);
+int virSetConnectNodeDev(virConnectPtr conn);
+int virSetConnectSecret(virConnectPtr conn);
+int virSetConnectStorage(virConnectPtr conn);
+
#endif /* __VIR_DRIVER_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3b14d7d158..7b05e4418f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1202,6 +1202,12 @@ virGetConnectNodeDev;
virGetConnectNWFilter;
virGetConnectSecret;
virGetConnectStorage;
+virSetConnectInterface;
+virSetConnectNetwork;
+virSetConnectNodeDev;
+virSetConnectNWFilter;
+virSetConnectSecret;
+virSetConnectStorage;
# libvirt_internal.h
--
2.14.3