[libvirt] [PATCH 24/29] remote: open secondary drivers via remote driver if needed

Daniel P. Berrangé berrange at redhat.com
Thu Jul 11 16:05:11 UTC 2019


When the client has a connection to one of the hypervisor specific
daemons (eg virtqemud), the app may still expect to use the secondary
driver APIs (storage, network, etc). None of these will be registered in
the hypervisor daemon, so we must explicitly open a connection to each
of the daemons for the secondary drivers we need.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/remote/remote_daemon_dispatch.c | 82 ++++++++++++++++++++++++-----
 1 file changed, 69 insertions(+), 13 deletions(-)

diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
index 856c5e48e7..c8a605c709 100644
--- a/src/remote/remote_daemon_dispatch.c
+++ b/src/remote/remote_daemon_dispatch.c
@@ -1954,6 +1954,9 @@ remoteDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED,
     unsigned int flags;
     struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
     int rv = -1;
+#ifndef LIBVIRTD
+    const char *type = NULL;
+#endif
 
     VIR_DEBUG("priv=%p conn=%p", priv, priv->conn);
     virMutexLock(&priv->lock);
@@ -1972,20 +1975,73 @@ remoteDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED,
     if (virNetServerClientGetReadonly(client))
         flags |= VIR_CONNECT_RO;
 
-    priv->conn =
-        flags & VIR_CONNECT_RO
-        ? virConnectOpenReadOnly(name)
-        : virConnectOpen(name);
-
-    if (priv->conn == NULL)
-        goto cleanup;
+#define OPEN_DRIVER(var, uri) \
+    do {                                 \
+        VIR_DEBUG("Opening driver %s", uri); \
+        if (!(priv->var = flags & VIR_CONNECT_RO  \
+                    ? virConnectOpenReadOnly(uri) \
+                    : virConnectOpen(uri))) \
+          goto cleanup; \
+        VIR_DEBUG("Opened %p", priv->var); \
+    } while (0)
 
-    priv->interfaceConn = virObjectRef(priv->conn);
-    priv->networkConn = virObjectRef(priv->conn);
-    priv->nodedevConn = virObjectRef(priv->conn);
-    priv->nwfilterConn = virObjectRef(priv->conn);
-    priv->secretConn = virObjectRef(priv->conn);
-    priv->storageConn = virObjectRef(priv->conn);
+    OPEN_DRIVER(conn, name);
+
+#ifndef LIBVIRTD
+    if (!(type = virConnectGetType(priv->conn)))
+        goto cleanup;
+
+    VIR_DEBUG("Primary driver type is '%s'", type);
+    if (STREQ(type, "QEMU") ||
+        STREQ(type, "LIBXL") ||
+        STREQ(type, "LXC") ||
+        STREQ(type, "VBOX") ||
+        STREQ(type, "bhyve") ||
+        STREQ(type, "vz") ||
+        STREQ(type, "Parallels")) {
+        VIR_DEBUG("Hypervisor driver found, opening connections to secondary drivers");
+        OPEN_DRIVER(interfaceConn, getuid() == 0 ? "interface:///system" : "interface:///session");
+        OPEN_DRIVER(networkConn, getuid() == 0 ? "network:///system" : "network:///session");
+        OPEN_DRIVER(nodedevConn, getuid() == 0 ? "nodedev:///system" : "nodedev:///session");
+        if (getuid() == 0)
+            OPEN_DRIVER(nwfilterConn, "nwfilter:///system");
+        OPEN_DRIVER(secretConn, getuid() == 0 ? "secret:///system" : "secret:///session");
+        OPEN_DRIVER(storageConn, getuid() == 0 ? "storage:///system" : "storage:///session");
+    } else if (STREQ(type, "interface")) {
+        VIR_DEBUG("Interface driver found");
+        priv->interfaceConn = virObjectRef(priv->conn);
+    } else if (STREQ(type, "network")) {
+        VIR_DEBUG("Network driver found");
+        priv->networkConn = virObjectRef(priv->conn);
+    } else if (STREQ(type, "nodedev")) {
+        VIR_DEBUG("Nodedev driver found");
+        priv->nodedevConn = virObjectRef(priv->conn);
+    } else if (STREQ(type, "nwfilter")) {
+        VIR_DEBUG("NWFilter driver found");
+        priv->nwfilterConn = virObjectRef(priv->conn);
+    } else if (STREQ(type, "secret")) {
+        VIR_DEBUG("Secret driver found");
+        priv->secretConn = virObjectRef(priv->conn);
+    } else if (STREQ(type, "storage")) {
+        VIR_DEBUG("Storage driver found");
+        priv->storageConn = virObjectRef(priv->conn);
+
+        /* Co-open the secret driver, as apps using the storage driver may well
+         * need access to secrets for storage auth
+         */
+        OPEN_DRIVER(secretConn, getuid == 0 ? "secret:///system" : "secret:///session");
+    } else {
+#endif /* LIBVIRTD */
+        VIR_DEBUG("Pointing secondary drivers to primary");
+        priv->interfaceConn = virObjectRef(priv->conn);
+        priv->networkConn = virObjectRef(priv->conn);
+        priv->nodedevConn = virObjectRef(priv->conn);
+        priv->nwfilterConn = virObjectRef(priv->conn);
+        priv->secretConn = virObjectRef(priv->conn);
+        priv->storageConn = virObjectRef(priv->conn);
+#ifndef LIBVIRTD
+    }
+#endif /* LIBVIRTD */
 
     /* force update the @readonly attribute which was inherited from the
      * virNetServerService object - this is important for sockets that are RW
-- 
2.21.0




More information about the libvir-list mailing list