[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