From 401a017691186669f72ba60f35564443ae7e7bc7 Mon Sep 17 00:00:00 2001
From: Ludovico de Nittis <ludovico.denittis@collabora.com>
Date: Tue, 23 Jun 2020 17:05:22 +0200
Subject: [PATCH] runtime: handle merged-/usr host OS with non merged-/usr
 container

Prioritize "/usr/" over "/lib/" if it is available to avoid issues when
we use a non merged-/usr container with a host system that is
merged-/usr

(Fixes: T22125)

Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
---
 src/runtime.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/runtime.c b/src/runtime.c
index cd61d80e0..fd399848b 100644
--- a/src/runtime.c
+++ b/src/runtime.c
@@ -2452,18 +2452,22 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
                   /* We are assuming that in the glibc "Makeconfig", $(libdir) was the same as
                    * $(slibdir) (this is the upstream default) or the same as "/usr$(slibdir)"
                    * (like in Debian without the mergerd /usr). We also assume that $(gconvdir)
-                   * had its default value "$(libdir)/gconv". */
-                  gconv_dir_in_host = g_build_filename (dir, "gconv", NULL);
-
-                  if (g_file_test (gconv_dir_in_host, G_FILE_TEST_IS_DIR))
+                   * had its default value "$(libdir)/gconv".
+                   * We check /usr first because otherwise, if the host is merged-/usr and the
+                   * container is not, we might end up binding /lib instead of /usr/lib
+                   * and that could cause issues. */
+                  if (!g_str_has_prefix (dir, "/usr/"))
                     {
-                      g_hash_table_add (gconv_from_host, g_steal_pointer (&gconv_dir_in_host));
-                      found = TRUE;
+                      gconv_dir_in_host = g_build_filename ("/usr", dir, "gconv", NULL);
+                      if (g_file_test (gconv_dir_in_host, G_FILE_TEST_IS_DIR))
+                        {
+                          g_hash_table_add (gconv_from_host, g_steal_pointer (&gconv_dir_in_host));
+                          found = TRUE;
+                        }
                     }
-                  else if (!g_str_has_prefix (dir, "/usr/"))
+                  else
                     {
-                      g_free (gconv_dir_in_host);
-                      gconv_dir_in_host = g_build_filename ("/usr", dir, "gconv", NULL);
+                      gconv_dir_in_host = g_build_filename (dir, "gconv", NULL);
                       if (g_file_test (gconv_dir_in_host, G_FILE_TEST_IS_DIR))
                         {
                           g_hash_table_add (gconv_from_host, g_steal_pointer (&gconv_dir_in_host));
@@ -2474,8 +2478,8 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
                   if (!found)
                     {
                       g_debug ("We were expecting to have the gconv modules directory in the "
-                               "host to be located in \"%s\", but instead it is missing",
-                               gconv_dir_in_host);
+                               "host to be located in \"%s/gconv\", but instead it is missing",
+                               dir);
                     }
                 }
 
-- 
GitLab