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);
+            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;
     }
 
-- 
2.53.0

Reply via email to