[libvirt] [PATCH 27/29] remote: switch to connect to per-driver daemons by default

Michal Privoznik mprivozn at redhat.com
Fri Jul 12 13:36:57 UTC 2019


On 7/11/19 6:05 PM, Daniel P. Berrangé wrote:
> Historically URIs handled by the remote driver will always connect to
> the libvirtd UNIX socket. There will now be one daemon per driver, and
> each of these has its own UNIX sockets to connect to.
> 
> It will still be possible to run the traditional monolithic libvirtd too
> which will have the original UNIX socket path.
> 
> In addition there is a virproxyd daemon that doesn't run any drivers,
> but provides proxying for clients accessing libvirt over IP sockets, or
> tunnelling to the legacy libvirtd UNIX socket path.
> 
> Finally when running inside a daemon, the remote driver must not reject
> connections unconditionally. For example, the QEMU driver needs to be
> able to connect to the network driver. The remote driver must thus be
> willing to handle connections even when inside the daemon, provided no
> local driver is registered.
> 
> This refactoring causes the remote driver to prefer connecting to the
> per-driver daemons. The URI parameter "no_direct=1" can be used to
> force connecting to the legacy libvirtd UNIX socket.
> 
> The remote driver will only ever spawn the per-driver daemons, or
> the legacy libvirtd. It won't ever try to spawn virtproxyd, as
> that is only there for IP based connectivity, or for access from
> legacy remote clients.
> 
> The $HOME/.config/libvirt/libvirt.conf can also be set to have a
> parameter 'remote_direct=0|1' to hardcode the behaviour for all
> clients.
> 
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> ---
>   src/driver.h               |   2 +
>   src/libvirt.c              |  24 +++++
>   src/remote/remote_driver.c | 202 +++++++++++++++++++++++++++++++++----
>   src/remote/remote_driver.h |   3 -
>   4 files changed, 207 insertions(+), 24 deletions(-)
> 
> diff --git a/src/driver.h b/src/driver.h
> index 898fb96df4..f7d667a03c 100644
> --- a/src/driver.h
> +++ b/src/driver.h
> @@ -108,6 +108,8 @@ int virSetSharedNWFilterDriver(virNWFilterDriverPtr driver) ATTRIBUTE_RETURN_CHE
>   int virSetSharedSecretDriver(virSecretDriverPtr driver) ATTRIBUTE_RETURN_CHECK;
>   int virSetSharedStorageDriver(virStorageDriverPtr driver) ATTRIBUTE_RETURN_CHECK;
>   
> +bool virHasDriverForURIScheme(const char *scheme);
> +
>   int virDriverLoadModule(const char *name,
>                           const char *regfunc,
>                           bool required);
> diff --git a/src/libvirt.c b/src/libvirt.c
> index 7e665b6cba..e21cad0e2e 100644
> --- a/src/libvirt.c
> +++ b/src/libvirt.c
> @@ -601,6 +601,30 @@ virRegisterConnectDriver(virConnectDriverPtr driver,
>   }
>   
>   
> +/**
> + * virHasDriverForURIScheme:
> + * @scheme: the URI scheme
> + *
> + * Determine if there is a driver registered that explicitly
> + * handles URIs with the scheme @scheme.
> + *
> + * Returns: true if a driver is registered
> + */
> +bool virHasDriverForURIScheme(const char *scheme)
> +{
> +    size_t i, j;
> +    for (i = 0; i < virConnectDriverTabCount; i++) {
> +        if (!virConnectDriverTab[i]->uriSchemes)
> +            continue;
> +        for (j = 0; virConnectDriverTab[i]->uriSchemes[j]; j++) {
> +            if (STREQ(virConnectDriverTab[i]->uriSchemes[j], scheme))
> +                return true;
> +        }
> +    }
> +
> +    return false;
> +}
> +
>   /**
>    * virRegisterStateDriver:
>    * @driver: pointer to a driver block
> diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
> index c6905dffff..98a165e163 100644
> --- a/src/remote/remote_driver.c
> +++ b/src/remote/remote_driver.c
> @@ -72,6 +72,22 @@ VIR_ENUM_IMPL(remoteDriverTransport,
>                 REMOTE_DRIVER_TRANSPORT_LAST,
>                 "tls", "unix", "ssh", "libssh2", "ext", "tcp", "libssh");
>   
> +typedef enum {
> +    /* Prefer per-driver virt*d daemons, but fallback to legacy libvirtd */
> +    REMOTE_DRIVER_MODE_AUTO,
> +    /* Always use the legacy libvirtd */
> +    REMOTE_DRIVER_MODE_LEGACY,
> +    /* Always use the per-driver virt*d daemons */
> +    REMOTE_DRIVER_MODE_DIRECT,
> +
> +    REMOTE_DRIVER_MODE_LAST
> +} remoteDriverMode;
> +
> +VIR_ENUM_DECL(remoteDriverMode);
> +VIR_ENUM_IMPL(remoteDriverMode,
> +              REMOTE_DRIVER_MODE_LAST,
> +              "auto", "legacy", "direct");
> +
>   #if SIZEOF_LONG < 8
>   # define HYPER_TO_TYPE(_type, _to, _from) \
>       do { \
> @@ -92,6 +108,7 @@ VIR_ENUM_IMPL(remoteDriverTransport,
>   
>   static bool inside_daemon;
>   
> +
>   struct private_data {
>       virMutex lock;
>   
> @@ -740,8 +757,9 @@ remoteConnectSupportsFeatureUnlocked(virConnectPtr conn,
>   
>   
>   static char *
> -remoteGetUNIXSocket(remoteDriverTransport transport,
> -                    unsigned int flags)
> +remoteGetUNIXSocketHelper(remoteDriverTransport transport,
> +                          const char *sock_prefix,
> +                          unsigned int flags)
>   {
>       char *sockname = NULL;
>       VIR_AUTOFREE(char *userdir);
> @@ -758,21 +776,125 @@ remoteGetUNIXSocket(remoteDriverTransport transport,
>           if (!(userdir = virGetUserRuntimeDirectory()))
>               return NULL;
>   
> -        if (virAsprintf(&sockname,
> -                        "%s/" LIBVIRTD_USER_UNIX_SOCKET, userdir) < 0)
> +        if (virAsprintf(&sockname, "%s/%s-sock",
> +                        userdir, sock_prefix) < 0)
>               return NULL;
>       } else {
> -        if (VIR_STRDUP(sockname,
> -                       flags & VIR_DRV_OPEN_REMOTE_RO ?
> -                       LIBVIRTD_PRIV_UNIX_SOCKET_RO :
> -                       LIBVIRTD_PRIV_UNIX_SOCKET) < 0)
> +        if (virAsprintf(&sockname, "%s/run/libvirt/%s-%s",
> +                        LOCALSTATEDIR, sock_prefix,
> +                        flags & VIR_DRV_OPEN_REMOTE_RO ?
> +                        "sock-ro" : "sock") < 0)
>               return NULL;
>       }
>   
> -    VIR_DEBUG("Chosen UNIX sockname %s", sockname);
> +    VIR_DEBUG("Built UNIX sockname %s for transport %s prefix %s flags=0x%x",
> +              sockname, remoteDriverTransportTypeToString(transport),
> +              sock_prefix, flags);
>       return sockname;
>   }
>   
> +
> +#define DRIVER_SCHEME_CHRS "abcdefghijklmnopqrstuvwxyz"
> +static char *
> +remoteGetUNIXSocket(remoteDriverTransport transport,
> +                    remoteDriverMode mode,
> +                    const char *driver,
> +                    char **daemon,
> +                    unsigned int flags)
> +{
> +    char *sock_name = NULL;
> +    VIR_AUTOFREE(char *) direct_daemon = NULL;
> +    VIR_AUTOFREE(char *) legacy_daemon = NULL;
> +    VIR_AUTOFREE(char *) direct_sock_name = NULL;
> +    VIR_AUTOFREE(char *) legacy_sock_name = NULL;
> +
> +    if (strspn(driver, DRIVER_SCHEME_CHRS) < strlen(driver)) {

Note that if no connection URI was provided then @driver is going to be 
NULL here and thus calling strlen() over it is going to crash.

> +        virReportError(VIR_ERR_INVALID_ARG,
> +                       _("Invalid character in driver '%s'"), driver);
> +        return NULL;
> +    }

Michal




More information about the libvir-list mailing list