remote: Don't attempt remote connection from libvirtd

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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2022-09-08 17:04:01 +02:00
parent 4b70a0519c
commit 93c3e3d49e

View File

@ -73,6 +73,7 @@ VIR_LOG_INIT("remote.remote_driver");
#endif #endif
static bool inside_daemon; static bool inside_daemon;
static bool monolithic_daemon;
struct private_data { struct private_data {
virMutex lock; virMutex lock;
@ -168,7 +169,7 @@ static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapsho
static int static int
remoteStateInitialize(bool privileged G_GNUC_UNUSED, remoteStateInitialize(bool privileged G_GNUC_UNUSED,
const char *root G_GNUC_UNUSED, const char *root G_GNUC_UNUSED,
bool monolithic G_GNUC_UNUSED, bool monolithic,
virStateInhibitCallback callback G_GNUC_UNUSED, virStateInhibitCallback callback G_GNUC_UNUSED,
void *opaque G_GNUC_UNUSED) void *opaque G_GNUC_UNUSED)
{ {
@ -176,6 +177,7 @@ remoteStateInitialize(bool privileged G_GNUC_UNUSED,
* re-entering ourselves * re-entering ourselves
*/ */
inside_daemon = true; inside_daemon = true;
monolithic_daemon = monolithic;
return VIR_DRV_STATE_INIT_COMPLETE; return VIR_DRV_STATE_INIT_COMPLETE;
} }
@ -1244,16 +1246,22 @@ remoteConnectOpen(virConnectPtr conn,
if (!conn->uri) if (!conn->uri)
return VIR_DRV_OPEN_DECLINED; return VIR_DRV_OPEN_DECLINED;
/* If there's a driver registered we must defer to that. /* Handle deferring to local drivers if we are dealing with a default
* If there isn't a driver, we must connect in "direct" * local URI. (Unknown local socket paths may be proxied to a remote
* mode - see doRemoteOpen. * host so they are treated as remote too).
* One exception is if we are trying to connect to an *
* unknown socket path as that might be proxied to remote * Deferring to a local driver is needed if:
* host */ * - the driver is registered in the current daemon
if (!conn->uri->server && * - if we are running monolithic libvirtd, in which case we consider
virHasDriverForURIScheme(driver) && * even un-registered drivers as local
!virURICheckUnixSocket(conn->uri)) */
return VIR_DRV_OPEN_DECLINED; 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())) if (!(priv = remoteAllocPrivateData()))