[libvirt PATCH 1/4] remote: extract logic for probing for modular daemons

Jim Fehlig jfehlig at suse.com
Mon Jun 14 23:11:58 UTC 2021


On 6/10/21 7:43 AM, Daniel P. Berrangé wrote:
> When virtproxyd gets a NULL URI, it needs to implement probing logic
> similar to that found in virConnectOpen. The latter can't be used
> directly since it relied on directly calling into the internal drivers
> in libvirtd. virtproxyd approximates this behaviour by looking to see
> what modular daemon sockets exist, or what daemon binaries are installed.
> 
> This same logic is also going to be needed when the regular libvirt
> remote client switches to prefer modular daemons by default, as we
> don't want to continue spawning libvirtd going forward.
> 
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> ---
>   src/libvirt_remote.syms             |   5 +
>   src/remote/remote_daemon_dispatch.c |  98 +++++---------------
>   src/remote/remote_sockets.c         | 139 ++++++++++++++++++++++++++++
>   src/remote/remote_sockets.h         |   7 ++
>   4 files changed, 173 insertions(+), 76 deletions(-)
> 
> diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms
> index 11c9e2cb73..b4265adf2e 100644
> --- a/src/libvirt_remote.syms
> +++ b/src/libvirt_remote.syms
> @@ -14,6 +14,11 @@ xdr_*;
>   xdr_virNetMessageError;
>   
>   
> +# remote/remote_sockets.h
> +remoteProbeSessionDriverFromBinary;
> +remoteProbeSessionDriverFromSocket;
> +remoteProbeSystemDriverFromSocket;
> +
>   # rpc/virnetclient.h
>   virNetClientAddProgram;
>   virNetClientAddStream;
> diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
> index 838f4a925f..36d4d00b79 100644
> --- a/src/remote/remote_daemon_dispatch.c
> +++ b/src/remote/remote_daemon_dispatch.c
> @@ -24,6 +24,7 @@
>   
>   #include "remote_daemon_dispatch.h"
>   #include "remote_daemon.h"
> +#include "remote_sockets.h"
>   #include "libvirt_internal.h"
>   #include "datatypes.h"
>   #include "viralloc.h"
> @@ -1968,6 +1969,8 @@ static int
>   remoteDispatchProbeURI(bool readonly,
>                          char **probeduri)
>   {
> +    g_autofree char *driver = NULL;
> +    const char *suffix;
>       *probeduri = NULL;
>       VIR_DEBUG("Probing for driver daemon sockets");
>   
> @@ -1976,94 +1979,37 @@ remoteDispatchProbeURI(bool readonly,
>        * exists, or we're using socket activation so the socket exists
>        * too.
>        *
> -     * If running non-root, chances are that the daemon won't be
> -     * running, nor any socket activation is used. We need to
> -     * be able to auto-spawn the daemon. We thus just check to
> -     * see what daemons are installed. This is not a big deal as
> -     * only QEMU & VBox run as non-root, anyway.
> +     * If running non-root, the daemon may or may not already be
> +     * running, and socket activation probably isn't relevant.
> +     * So if no viable socket exists, we need to check which daemons
> +     * are actually installed. This is not a big deal as only QEMU &
> +     * VBox run as non-root, anyway.
>        */
>       if (geteuid() != 0) {
> -        /* Order these the same as virDriverLoadModule
> -         * calls in daemonInitialize */
> -        const char *drivers[] = {
> -# ifdef WITH_QEMU
> -            "qemu",
> -# endif
> -# ifdef WITH_VBOX
> -            "vbox",
> -# endif
> -        };
> -        ssize_t i;
> -
> -        for (i = 0; i < (ssize_t) G_N_ELEMENTS(drivers) && !*probeduri; i++) {
> -            g_autofree char *daemonname = NULL;
> -            g_autofree char *daemonpath = NULL;
> -
> -            daemonname = g_strdup_printf("virt%sd", drivers[i]);
> -
> -            if (!(daemonpath = virFileFindResource(daemonname,
> -                                                   abs_top_builddir "/src",
> -                                                   SBINDIR)))
> -                return -1;
> -
> -            if (!virFileExists(daemonpath)) {
> -                VIR_DEBUG("Missing daemon %s for driver %s", daemonpath, drivers[i]);
> -                continue;
> -            }
> +        if (remoteProbeSessionDriverFromSocket(false, &driver) < 0)
> +            return -1;
>   
> -            *probeduri = g_strdup_printf("%s:///session", drivers[i]);
> +        if (driver == NULL &&
> +            remoteProbeSessionDriverFromBinary(&driver) < 0)
> +            return -1;
>   
> -            VIR_DEBUG("Probed URI %s via daemon %s", *probeduri, daemonpath);
> -            return 0;
> -        }
> +        suffix = "session";
>       } else {
> -        /* Order these the same as virDriverLoadModule
> -         * calls in daemonInitialize */
> -        const char *drivers[] = {
> -# ifdef WITH_LIBXL
> -            "libxl",
> -# endif
> -# ifdef WITH_QEMU
> -            "qemu",
> -# endif
> -# ifdef WITH_LXC
> -            "lxc",
> -# endif
> -# ifdef WITH_VBOX
> -            "vbox",
> -# endif
> -# ifdef WITH_BHYVE
> -            "bhyve",
> -# endif
> -# ifdef WITH_VZ
> -            "vz",
> -# endif
> -        };
> -        ssize_t i;
> -
> -        for (i = 0; i < (ssize_t) G_N_ELEMENTS(drivers) && !*probeduri; i++) {
> -            g_autofree char *sockname = NULL;
> -
> -            sockname = g_strdup_printf("%s/libvirt/virt%sd-%s", RUNSTATEDIR,
> -                                       drivers[i], readonly ? "sock-ro" : "sock");
> -
> -            if (!virFileExists(sockname)) {
> -                VIR_DEBUG("Missing sock %s for driver %s", sockname, drivers[i]);
> -                continue;
> -            }
> -
> -            *probeduri = g_strdup_printf("%s:///system", drivers[i]);
> +        if (remoteProbeSystemDriverFromSocket(readonly, &driver) < 0)
> +            return -1;
>   
> -            VIR_DEBUG("Probed URI %s via sock %s", *probeduri, sockname);
> -            return 0;
> -        }
> +        suffix = "system";
>       }
>   
>       /* Even if we didn't probe any socket, we won't
>        * return error. Just let virConnectOpen's normal
>        * logic run which will likely return an error anyway
>        */
> -    VIR_DEBUG("No driver sock exists");
> +    if (!driver)
> +        return 0;
> +
> +    *probeduri = g_strdup_printf("%s:///%s", driver, suffix);
> +    VIR_DEBUG("Probed URI %s for driver %s", *probeduri, driver);
>       return 0;
>   }
>   #endif /* VIRTPROXYD */
> diff --git a/src/remote/remote_sockets.c b/src/remote/remote_sockets.c
> index 0f85b999fd..dd28c9dd5e 100644
> --- a/src/remote/remote_sockets.c
> +++ b/src/remote/remote_sockets.c
> @@ -146,6 +146,145 @@ remoteGetUNIXSocketHelper(remoteDriverTransport transport,
>       return sockname;
>   }
>   
> +/*
> + * Determine which driver is probably usable based on
> + * which modular daemon binaries are installed.
> + */
> +int
> +remoteProbeSessionDriverFromBinary(char **driver)
> +{
> +    /* Order these the same as virDriverLoadModule
> +     * calls in daemonInitialize, so we replicate
> +     * probing order that virConnectOpen would use
> +     * if running inside libvirtd */
> +    const char *drivers[] = {
> +#ifdef WITH_QEMU
> +        "qemu",
> +#endif
> +#ifdef WITH_VBOX
> +        "vbox",
> +#endif
> +    };
> +    ssize_t i;
> +
> +    VIR_DEBUG("Probing for driver from daemon binaries");
> +
> +    *driver = NULL;
> +
> +    for (i = 0; i < (ssize_t) G_N_ELEMENTS(drivers); i++) {
> +        g_autofree char *daemonname = NULL;
> +        g_autofree char *daemonpath = NULL;
> +
> +        daemonname = g_strdup_printf("virt%sd", drivers[i]);
> +        VIR_DEBUG("Probing driver '%s' via daemon %s", drivers[i], daemonpath);
> +
> +        if (!(daemonpath = virFileFindResource(daemonname,
> +                                               abs_top_builddir "/src",
> +                                               SBINDIR)))
> +            return -1;
> +
> +        if (virFileExists(daemonpath)) {
> +            VIR_DEBUG("Found driver '%s' via daemon %s", drivers[i], daemonpath);
> +            *driver = g_strdup(drivers[i]);
> +            return 0;
> +        }
> +
> +        VIR_DEBUG("Missing daemon %s for driver %s", daemonpath, drivers[i]);
> +    }
> +
> +    VIR_DEBUG("No more drivers to probe for");
> +    return 0;
> +}
> +
> +
> +int
> +remoteProbeSystemDriverFromSocket(bool readonly, char **driver)
> +{
> +    /* Order these the same as virDriverLoadModule
> +     * calls in daemonInitialize, so we replicate
> +     * probing order that virConnectOpen would use
> +     * if running inside libvirtd */
> +    const char *drivers[] = {
> +#ifdef WITH_LIBXL
> +        "libxl",

Pre-existing bug due to libxl vs xen naming fiasco, but here it should be "xen".

Regards,
Jim

> +#endif
> +#ifdef WITH_QEMU
> +        "qemu",
> +#endif
> +#ifdef WITH_LXC
> +        "lxc",
> +#endif
> +#ifdef WITH_VBOX
> +        "vbox",
> +#endif
> +#ifdef WITH_BHYVE
> +        "bhyve",
> +#endif
> +#ifdef WITH_VZ
> +        "vz",
> +#endif
> +    };
> +    ssize_t i;
> +
> +    for (i = 0; i < (ssize_t) G_N_ELEMENTS(drivers); i++) {
> +        g_autofree char *sockname =
> +            g_strdup_printf("%s/libvirt/virt%sd-%s", RUNSTATEDIR,
> +                            drivers[i], readonly ? "sock-ro" : "sock");
> +
> +        if (virFileExists(sockname)) {
> +            VIR_DEBUG("Probed driver '%s' via sock '%s'", drivers[i], sockname);
> +            *driver = g_strdup(drivers[i]);
> +            return 0;
> +        }
> +
> +        VIR_DEBUG("Missing sock %s for driver %s", sockname, drivers[i]);
> +    }
> +
> +    /* Even if we didn't probe any socket, we won't
> +     * return error. Just let virConnectOpen's normal
> +     * logic run which will likely return an error anyway
> +     */
> +    VIR_DEBUG("No more drivers to probe for");
> +    return 0;
> +}
> +
> +int
> +remoteProbeSessionDriverFromSocket(bool readonly, char **driver)
> +{
> +    /* Order these the same as virDriverLoadModule
> +     * calls in daemonInitialize */
> +    const char *drivers[] = {
> +#ifdef WITH_QEMU
> +        "qemu",
> +#endif
> +#ifdef WITH_VBOX
> +        "vbox",
> +#endif
> +    };
> +    ssize_t i;
> +
> +    for (i = 0; i < (ssize_t) G_N_ELEMENTS(drivers); i++) {
> +        g_autofree char *userdir = virGetUserRuntimeDirectory();
> +        g_autofree char *sockname =
> +            g_strdup_printf("%s/virt%sd-%s",
> +                            userdir, drivers[i], readonly ? "sock-ro" : "sock");
> +
> +        if (virFileExists(sockname)) {
> +            VIR_DEBUG("Probed driver '%s' via sock '%s'", drivers[i], sockname);
> +            *driver = g_strdup(drivers[i]);
> +            return 0;
> +        }
> +
> +        VIR_DEBUG("Missing sock %s for driver %s", sockname, drivers[i]);
> +    }
> +
> +    /* Even if we didn't probe any socket, we won't
> +     * return error. Just let virConnectOpen's normal
> +     * logic run which will likely return an error anyway
> +     */
> +    VIR_DEBUG("No more drivers to probe for");
> +    return 0;
> +}
>   
>   char *
>   remoteGetUNIXSocket(remoteDriverTransport transport,
> diff --git a/src/remote/remote_sockets.h b/src/remote/remote_sockets.h
> index 11934dbf70..00e654d46c 100644
> --- a/src/remote/remote_sockets.h
> +++ b/src/remote/remote_sockets.h
> @@ -62,6 +62,13 @@ remoteSplitURIScheme(virURI *uri,
>                        char **driver,
>                        remoteDriverTransport *transport);
>   
> +int
> +remoteProbeSessionDriverFromBinary(char **driver);
> +int
> +remoteProbeSystemDriverFromSocket(bool readonly, char **driver);
> +int
> +remoteProbeSessionDriverFromSocket(bool readonly, char **driver);
> +
>   char *
>   remoteGetUNIXSocket(remoteDriverTransport transport,
>                       remoteDriverMode mode,
> 





More information about the libvir-list mailing list