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@xxxxxxxxxx> --- 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