On Wed, Apr 08, 2026 at 00:10:38 -0400, Laine Stump via Devel wrote:
> From: Laine Stump <[email protected]>
> 
> When running in session/unprivileged mode, nearly all paths are
> prefixed with the returns from one of glib's g_get_user_*_dir()
> functions, which in turn base their selected paths on the settings of
> a few items in the user's environment ($XDG_*, or a subdirectory of
> $HOME if the relevant $XDG_* isn't set).
> 
> This patch logs the settings of these directories in the log banner in
> an attempt to help diagnose the problem when a file/socket open/create
> fails.
> 
> An example of the banner:
> 
> libvirt version: 12.3.0, package: 1.fc43 (Unknown, 2026-04-07-22:43:30, vhost)
> hostname: 83be0e173e02, user: qemu, uid: 107
> home dir: '/' (HOME='/')
> runtime dir: '/.cache' (XDG_RUNTIME_DIR='(unset)')
> config dir: '/.config' (XDG_CONFIG_HOME='(unset)')
> log dir: '/.cache' (XDG_CACHE_HOME='(unset)')
> libvirt: XML-RPC error : Cannot create user runtime directory 
> '/.cache/libvirt': Permission denied
> 
> Resolves: https://redhat.atlassian.net/browse/RHEL-70222
> Resolves: https://redhat.atlassian.net/browse/RHEL-105490
> Signed-off-by: Laine Stump <[email protected]>
> ---
> 
> We could obviously add more information here (or less); it's difficult
> to know where to draw the line. Also, the astute reviewer will notice
> that all this code is executed once for each log target - we could do
> it all once at a higher level and cache it if we really wanted to. I'm
> not sure if it's worth the trouble though).
> 
> Changes in V2: modified the format/labeling of the data as Peter
> suggested, and included an example in the commit log.
> 
> src/util/virlog.c | 37 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
> 
> diff --git a/src/util/virlog.c b/src/util/virlog.c
> index ccdf66c396..d2882d16ee 100644
> --- a/src/util/virlog.c
> +++ b/src/util/virlog.c
> @@ -540,6 +540,43 @@ virLogToOneTarget(virLogSource *source,
>                                    g_get_host_name(), username, uid);
>          virLogOneInitMsg(timestamp, hoststr, outputFunc, data);
>  
> +        /* This info is only relevant when running as something other than 
> root */
> +        if (uid != 0) {
> +            g_autofree char *envHOME = NULL;
> +            g_autofree char *envXDG_RUNTIME_DIR = NULL;
> +            g_autofree char *envXDG_CONFIG_HOME = NULL;
> +            g_autofree char *envXDG_CACHE_HOME = NULL;
> +
> +            g_autofree char *envstr1 = NULL;
> +            g_autofree char *envstr2 = NULL;
> +            g_autofree char *envstr3 = NULL;
> +            g_autofree char *envstr4 = NULL;
> +
> +            if (!(envHOME = g_strdup(g_getenv("HOME"))))
> +                envHOME = g_strdup("(unset)");
> +            if (!(envXDG_RUNTIME_DIR = 
> g_strdup(g_getenv("XDG_RUNTIME_DIR"))))
> +                envXDG_RUNTIME_DIR = g_strdup("(unset)");
> +            if (!(envXDG_CONFIG_HOME = 
> g_strdup(g_getenv("XDG_CONFIG_HOME"))))
> +                envXDG_CONFIG_HOME = g_strdup("(unset)");
> +            if (!(envXDG_CACHE_HOME = g_strdup(g_getenv("XDG_CACHE_HOME"))))
> +                envXDG_CACHE_HOME = g_strdup("(unset)");
> +
> +            envstr1 = g_strdup_printf("home dir: '%s' (HOME='%s')",
> +                                      g_get_home_dir(), envHOME);

I wonder if the '(unset)' string is even required. The code could be
simplified, if we decide that e.g. empty string is okay to denote we
won't need the extra variables:

            envstr1 = g_strdup_printf("home dir: '%s' (HOME='%s')",
                                      g_get_home_dir(), 
NULLSTR_EMPTY(g_getenv("HOME")));


> +            virLogOneInitMsg(timestamp, envstr1, outputFunc, data);
> +
> +            envstr2 = g_strdup_printf("runtime dir: '%s' 
> (XDG_RUNTIME_DIR='%s')",
> +                                      g_get_user_runtime_dir(), 
> envXDG_RUNTIME_DIR);
> +            virLogOneInitMsg(timestamp, envstr2, outputFunc, data);
> +
> +            envstr3 = g_strdup_printf("config dir: '%s' 
> (XDG_CONFIG_HOME='%s')",
> +                                      g_get_user_config_dir(), 
> envXDG_CONFIG_HOME);
> +            virLogOneInitMsg(timestamp, envstr3, outputFunc, data);
> +
> +            envstr4 = g_strdup_printf("log dir: '%s' (XDG_CACHE_HOME='%s')",
> +                                      g_get_user_cache_dir(), 
> envXDG_CACHE_HOME);
> +            virLogOneInitMsg(timestamp, envstr4, outputFunc, data);
> +        }
>          *needInit = false;
>      }

However you decide about the '(unset)' vs '' for unset env variables:

Reviewed-by: Peter Krempa <[email protected]>

Reply via email to