]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
remote: add support for probing drivers with modular daemons
authorDaniel P. Berrangé <berrange@redhat.com>
Tue, 25 May 2021 09:45:06 +0000 (10:45 +0100)
committerDaniel P. Berrangé <berrange@redhat.com>
Fri, 18 Jun 2021 15:19:53 +0000 (16:19 +0100)
With the traditional libvirtd, the virConnectOpen call will probe active
drivers server side to find which one to use when the URI is NULL/empty.

With the modular daemons though, the remote client does not know which
daemon to connect in the first place, so we can't rely on virConnectOpen
probing. Currently the virtproxyd daemon has code to probe for a
possible driver by looking at which sockets are listening or which
binaries are installed. The remote client can thus connect to virtproxyd
which in turn can connect to a real hypervisor driver.

The virtproxyd probing code though isn't something that needs to live in
virtproxyd. By moving it into the remote client we can get probing
client side in all scenarios and avoid the extra trip via virtproxyd in
the common case.

Tested-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
meson.build
src/remote/remote_sockets.c

index 02900ff73850f7cd7a7f35ed2af5c5db538ec795..9caae5521b4e4df9e83065236d479f7f001266c5 100644 (file)
@@ -1421,8 +1421,10 @@ if not get_option('driver_remote').disabled()
   endif
 endif
 
-remote_default_mode = get_option('remote_default_mode').to_upper()
-conf.set('REMOTE_DRIVER_MODE_DEFAULT', 'REMOTE_DRIVER_MODE_@0@'.format(remote_default_mode))
+remote_default_mode = get_option('remote_default_mode')
+if remote_default_mode == 'direct'
+  conf.set('REMOTE_DRIVER_AUTOSTART_DIRECT', '1')
+endif
 
 if not get_option('driver_libvirtd').disabled()
   use_libvirtd = true
index 85295f1bc2107bc6307d818a847b5850a05b39b4..2979576680e8983a05a4150d73323e41b488e5c3 100644 (file)
@@ -299,6 +299,9 @@ remoteGetUNIXSocket(remoteDriverTransport transport,
     g_autofree char *daemon_name = NULL;
     g_autofree char *direct_sock_name = NULL;
     g_autofree char *legacy_sock_name = NULL;
+#ifdef REMOTE_DRIVER_AUTOSTART_DIRECT
+    g_autofree char *guessdriver = NULL;
+#endif
 #ifndef WIN32
     const char *env_name = remoteGetDaemonPathEnv();
 #else
@@ -310,12 +313,35 @@ remoteGetUNIXSocket(remoteDriverTransport transport,
               remoteDriverModeTypeToString(mode),
               driver, flags);
 
+#ifdef REMOTE_DRIVER_AUTOSTART_DIRECT
+    if (!driver && mode != REMOTE_DRIVER_MODE_LEGACY) {
+        VIR_DEBUG("Client side modular daemon probe");
+        /*
+         * If we don't have a driver (because URI is empty)
+         * in the direct case, we don't know which daemon
+         * to connect to. This logic attempts to be a rough
+         * equivalent of auto-probing from virConnectOpen
+         * in the libvirtd days.
+         */
+        if (geteuid() != 0) {
+            if (remoteProbeSessionDriverFromSocket(false, &guessdriver) < 0)
+                return NULL;
+
+            if (guessdriver == NULL &&
+                remoteProbeSessionDriverFromBinary(&guessdriver) < 0)
+                return NULL;
+        } else {
+            if (remoteProbeSystemDriverFromSocket(flags & REMOTE_DRIVER_OPEN_RO,
+                                                  &guessdriver) < 0)
+                return NULL;
+        }
+        driver = guessdriver;
+    }
+#endif
+
     if (driver) {
         direct_daemon = g_strdup_printf("virt%sd", driver);
         direct_sock_name = remoteGetUNIXSocketHelper(transport, direct_daemon, flags);
-    } else {
-        direct_daemon = g_strdup("virtproxyd");
-        direct_sock_name = remoteGetUNIXSocketHelper(transport, "libvirt", flags);
     }
 
     legacy_daemon = g_strdup("libvirtd");
@@ -323,18 +349,29 @@ remoteGetUNIXSocket(remoteDriverTransport transport,
 
     if (mode == REMOTE_DRIVER_MODE_AUTO) {
         if (transport == REMOTE_DRIVER_TRANSPORT_UNIX) {
+            /*
+             * When locally accessing libvirtd, we pick legacy or
+             * modular daemons depending on which sockets we see
+             * existing.
+             */
             if (direct_sock_name && virFileExists(direct_sock_name)) {
                 mode = REMOTE_DRIVER_MODE_DIRECT;
             } else if (virFileExists(legacy_sock_name)) {
                 mode = REMOTE_DRIVER_MODE_LEGACY;
             } else {
-                /*
-                 * This constant comes from the configure script and
-                 * maps to either the direct or legacy mode constant
-                 */
-                mode = REMOTE_DRIVER_MODE_DEFAULT;
+#ifdef REMOTE_DRIVER_AUTOSTART_DIRECT
+                mode = REMOTE_DRIVER_MODE_DIRECT;
+#else
+                mode = REMOTE_DRIVER_MODE_LEGACY;
+#endif
             }
         } else {
+            /*
+             * When remotely accessing libvirtd, we always default to a legacy socket
+             * path, as there's no way for us to probe what's configured. This does
+             * not matter, since 'virt-ssh-helper' will be used if it is available
+             * and thus probe from context of the remote host
+             */
             mode = REMOTE_DRIVER_MODE_LEGACY;
         }
     }