When a hypervisor driver is not compiled in and a user enables the
monolithic libvirtd, they get the following misleading error:
$ virsh -c qemu:///system
error: failed to connect to the hypervisor
error: Failed to connect socket to '/var/run/libvirt/virtqemud-sock': No such
file or directory
The issue is that the daemon side of the remote driver can't find the
appropriate driver, but the remote driver always accepts everything and
thus attempts to delegate further, which in case of libvirtd makes no
sense.
Refuse opening a connection for local URIS even when the requested
driver is not registered in case when we are inside 'libvirtd' as
libvirtd doesn't have anything to delegate to.
$ virsh -c qemu:///system
error: failed to connect to the hypervisor
error: no connection driver available for qemu:///system
Discovered when investigating
https://gitlab.com/libvirt/libvirt/-/issues/370
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/remote/remote_driver.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 33cc6b1fce..a4efe101a3 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -73,6 +73,7 @@ VIR_LOG_INIT("remote.remote_driver");
#endif
static bool inside_daemon;
+static bool monolithic_daemon;
struct private_data {
virMutex lock;
@@ -168,7 +169,7 @@ static void
make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapsho
static int
remoteStateInitialize(bool privileged G_GNUC_UNUSED,
const char *root G_GNUC_UNUSED,
- bool monolithic G_GNUC_UNUSED,
+ bool monolithic,
virStateInhibitCallback callback G_GNUC_UNUSED,
void *opaque G_GNUC_UNUSED)
{
@@ -176,6 +177,7 @@ remoteStateInitialize(bool privileged G_GNUC_UNUSED,
* re-entering ourselves
*/
inside_daemon = true;
+ monolithic_daemon = monolithic;
return VIR_DRV_STATE_INIT_COMPLETE;
}
@@ -1244,16 +1246,22 @@ remoteConnectOpen(virConnectPtr conn,
if (!conn->uri)
return VIR_DRV_OPEN_DECLINED;
- /* If there's a driver registered we must defer to that.
- * If there isn't a driver, we must connect in "direct"
- * mode - see doRemoteOpen.
- * One exception is if we are trying to connect to an
- * unknown socket path as that might be proxied to remote
- * host */
- if (!conn->uri->server &&
- virHasDriverForURIScheme(driver) &&
- !virURICheckUnixSocket(conn->uri))
- return VIR_DRV_OPEN_DECLINED;
+ /* Handle deferring to local drivers if we are dealing with a default
+ * local URI. (Unknown local socket paths may be proxied to a remote
+ * host so they are treated as remote too).
+ *
+ * Deferring to a local driver is needed if:
+ * - the driver is registered in the current daemon
+ * - if we are running monolithic libvirtd, in which case we consider
+ * even un-registered drivers as local
+ */
+ if (!conn->uri->server && !virURICheckUnixSocket(conn->uri)) {
+ if (virHasDriverForURIScheme(driver))
+ return VIR_DRV_OPEN_DECLINED;
+
+ if (monolithic_daemon)
+ return VIR_DRV_OPEN_DECLINED;
+ }
}
if (!(priv = remoteAllocPrivateData()))
--
2.37.1