diff --git a/pressure-vessel/bwrap.c b/pressure-vessel/bwrap.c
index 754b2ffcfe804b0a74f87e713fde8bf921f25ce8..99e47752a69ecf4f9738937316f9f7da620d82ad 100644
--- a/pressure-vessel/bwrap.c
+++ b/pressure-vessel/bwrap.c
@@ -23,7 +23,7 @@
 
 #include "bwrap.h"
 
-#include "resolve-in-sysroot.h"
+#include "steam-runtime-tools/resolve-in-sysroot-internal.h"
 
 /**
  * pv_bwrap_run_sync:
diff --git a/pressure-vessel/meson.build b/pressure-vessel/meson.build
index 8281b56ddeaf66aaeb37d8ce0c6b46b3d3be143d..e6de0fb184a995359d7e9846ca478b87eab8e077 100644
--- a/pressure-vessel/meson.build
+++ b/pressure-vessel/meson.build
@@ -57,7 +57,6 @@ endforeach
 
 # Headers to scan for enum/flags types.
 headers = [
-  'resolve-in-sysroot.h',
   'runtime.h',
 ]
 
@@ -86,8 +85,6 @@ pressure_vessel_utils = static_library(
     'flatpak-utils-base-private.h',
     'flatpak-utils.c',
     'flatpak-utils-private.h',
-    'resolve-in-sysroot.c',
-    'resolve-in-sysroot.h',
     'tree-copy.c',
     'tree-copy.h',
     'utils.c',
diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c
index d449eda5d75905d57bf074121c12ad6ce4d1f121..b0ddafd4eed62617e112e5c921932f7741acd72f 100644
--- a/pressure-vessel/runtime.c
+++ b/pressure-vessel/runtime.c
@@ -29,13 +29,14 @@
 #include "libglnx/libglnx.h"
 
 #include <steam-runtime-tools/steam-runtime-tools.h>
+#include "steam-runtime-tools/resolve-in-sysroot-internal.h"
+#include "steam-runtime-tools/utils-internal.h"
 
 #include "bwrap.h"
 #include "bwrap-lock.h"
 #include "elf-utils.h"
 #include "enumtypes.h"
 #include "flatpak-run-private.h"
-#include "resolve-in-sysroot.h"
 #include "tree-copy.h"
 #include "utils.h"
 
@@ -1590,8 +1591,8 @@ bind_runtime (PvRuntime *self,
   /* If we are in a Flatpak environment, we need to test if these files are
    * available in the host, and not in the current environment, because we will
    * run bwrap in the host system */
-  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/machine-id",
-                               G_FILE_TEST_EXISTS))
+  if (_srt_file_test_in_sysroot (self->host_in_current_namespace, -1,
+                                 "/etc/machine-id", G_FILE_TEST_EXISTS))
     {
       flatpak_bwrap_add_args (bwrap,
                               "--ro-bind", "/etc/machine-id", "/etc/machine-id",
@@ -1602,8 +1603,9 @@ bind_runtime (PvRuntime *self,
   /* We leave this for completeness but in practice we do not expect to have
    * access to the "/var" host directory because Flatpak usually just binds
    * the host's "etc" and "usr". */
-  else if (pv_file_test_in_sysroot (self->host_in_current_namespace,
-                                    "/var/lib/dbus/machine-id", G_FILE_TEST_EXISTS))
+  else if (_srt_file_test_in_sysroot (self->host_in_current_namespace, -1,
+                                      "/var/lib/dbus/machine-id",
+                                      G_FILE_TEST_EXISTS))
     {
       flatpak_bwrap_add_args (bwrap,
                               "--ro-bind", "/var/lib/dbus/machine-id",
@@ -1613,34 +1615,34 @@ bind_runtime (PvRuntime *self,
                               NULL);
     }
 
-  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/resolv.conf",
-                               G_FILE_TEST_EXISTS))
+  if (_srt_file_test_in_sysroot (self->host_in_current_namespace, -1,
+                                 "/etc/resolv.conf", G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/resolv.conf", "/etc/resolv.conf",
                             NULL);
 
-  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/host.conf",
-                               G_FILE_TEST_EXISTS))
+  if (_srt_file_test_in_sysroot (self->host_in_current_namespace, -1,
+                                 "/etc/host.conf", G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/host.conf", "/etc/host.conf",
                             NULL);
 
-  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/hosts",
-                               G_FILE_TEST_EXISTS))
+  if (_srt_file_test_in_sysroot (self->host_in_current_namespace, -1,
+                                 "/etc/hosts", G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/hosts", "/etc/hosts",
                             NULL);
 
   /* TODO: Synthesize a passwd with only the user and nobody,
    * like Flatpak does? */
-  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/passwd",
-                               G_FILE_TEST_EXISTS))
+  if (_srt_file_test_in_sysroot (self->host_in_current_namespace, -1,
+                                 "/etc/passwd", G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/passwd", "/etc/passwd",
                             NULL);
 
-  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/group",
-                               G_FILE_TEST_EXISTS))
+  if (_srt_file_test_in_sysroot (self->host_in_current_namespace, -1,
+                                 "/etc/group", G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/group", "/etc/group",
                             NULL);
@@ -1665,8 +1667,8 @@ bind_runtime (PvRuntime *self,
    * non-existing targets), in which case we don't want to attempt to create
    * bogus symlinks or bind mounts, as that will cause flatpak run to fail.
    */
-  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/localtime",
-                               G_FILE_TEST_EXISTS))
+  if (_srt_file_test_in_sysroot (self->host_in_current_namespace, -1,
+                                 "/etc/localtime", G_FILE_TEST_EXISTS))
     {
       g_autofree char *target = NULL;
       gboolean is_reachable = FALSE;
@@ -1734,15 +1736,15 @@ pv_runtime_take_from_provider (PvRuntime *self,
 
   if (flags & TAKE_FROM_PROVIDER_FLAGS_IF_DIR)
     {
-      if (!pv_file_test_in_sysroot (self->provider_in_current_namespace,
-                                    source_in_provider, G_FILE_TEST_IS_DIR))
+      if (!_srt_file_test_in_sysroot (self->provider_in_current_namespace, -1,
+                                      source_in_provider, G_FILE_TEST_IS_DIR))
         return TRUE;
     }
 
   if (flags & TAKE_FROM_PROVIDER_FLAGS_IF_EXISTS)
     {
-      if (!pv_file_test_in_sysroot (self->provider_in_current_namespace,
-                                    source_in_provider, G_FILE_TEST_EXISTS))
+      if (!_srt_file_test_in_sysroot (self->provider_in_current_namespace, -1,
+                                      source_in_provider, G_FILE_TEST_EXISTS))
         return TRUE;
     }
 
@@ -1756,10 +1758,10 @@ pv_runtime_take_from_provider (PvRuntime *self,
       glnx_autofd int parent_dirfd = -1;
 
       parent_in_container = g_path_get_dirname (dest_in_container);
-      parent_dirfd = pv_resolve_in_sysroot (self->mutable_sysroot_fd,
-                                            parent_in_container,
-                                            PV_RESOLVE_FLAGS_MKDIR_P,
-                                            NULL, error);
+      parent_dirfd = _srt_resolve_in_sysroot (self->mutable_sysroot_fd,
+                                              parent_in_container,
+                                              SRT_RESOLVE_FLAGS_MKDIR_P,
+                                              NULL, error);
 
       if (parent_dirfd < 0)
         return FALSE;
@@ -1783,9 +1785,9 @@ pv_runtime_take_from_provider (PvRuntime *self,
                                    FALSE, &sysroot_fd, error))
                 return FALSE;
 
-              file_fd = pv_resolve_in_sysroot (sysroot_fd, source_in_provider,
-                                               PV_RESOLVE_FLAGS_READABLE,
-                                               NULL, error);
+              file_fd = _srt_resolve_in_sysroot (sysroot_fd, source_in_provider,
+                                                 SRT_RESOLVE_FLAGS_READABLE,
+                                                 NULL, error);
               if (file_fd < 0)
                 return FALSE;
 
@@ -1904,10 +1906,10 @@ pv_runtime_remove_overridden_libraries (PvRuntime *self,
         {
           g_autoptr(GError) local_error = NULL;
 
-          libdir_fd = pv_resolve_in_sysroot (self->mutable_sysroot_fd,
-                                             multiarch_libdirs[i],
-                                             PV_RESOLVE_FLAGS_READABLE,
-                                             NULL, &local_error);
+          libdir_fd = _srt_resolve_in_sysroot (self->mutable_sysroot_fd,
+                                               multiarch_libdirs[i],
+                                               SRT_RESOLVE_FLAGS_READABLE,
+                                               NULL, &local_error);
 
           if (libdir_fd < 0)
             {
@@ -2018,9 +2020,9 @@ pv_runtime_remove_overridden_libraries (PvRuntime *self,
                 }
             }
 
-          libfd = pv_resolve_in_sysroot (self->mutable_sysroot_fd, path,
-                                         PV_RESOLVE_FLAGS_READABLE, NULL,
-                                         &local_error);
+          libfd = _srt_resolve_in_sysroot (self->mutable_sysroot_fd, path,
+                                           SRT_RESOLVE_FLAGS_READABLE, NULL,
+                                           &local_error);
 
           if (libfd < 0)
             {
@@ -2120,9 +2122,9 @@ pv_runtime_take_ld_so_from_provider (PvRuntime *self,
   if (!glnx_opendirat (-1, self->provider_in_current_namespace, FALSE, &provider_fd, error))
     return FALSE;
 
-  path_fd = pv_resolve_in_sysroot (provider_fd,
-                                   arch->ld_so, PV_RESOLVE_FLAGS_READABLE,
-                                   &ld_so_relative_to_provider, error);
+  path_fd = _srt_resolve_in_sysroot (provider_fd,
+                                     arch->ld_so, SRT_RESOLVE_FLAGS_READABLE,
+                                     &ld_so_relative_to_provider, error);
 
   if (path_fd < 0)
     return glnx_throw_errno_prefix (error,
@@ -2192,8 +2194,8 @@ pv_runtime_search_in_path_and_bin (PvRuntime *self,
       g_autofree gchar *test_path = g_build_filename (common_bin_dirs[i],
                                                       program_name,
                                                       NULL);
-      if (pv_file_test_in_sysroot (self->host_in_current_namespace,
-                                   test_path, G_FILE_TEST_IS_EXECUTABLE))
+      if (_srt_file_test_in_sysroot (self->host_in_current_namespace, -1,
+                                     test_path, G_FILE_TEST_IS_EXECUTABLE))
         return g_steal_pointer (&test_path);
     }
 
@@ -2341,11 +2343,11 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
             {
               glnx_autofd int fd = -1;
 
-              fd = pv_resolve_in_sysroot (self->mutable_sysroot_fd,
-                                          arch->ld_so,
-                                          PV_RESOLVE_FLAGS_NONE,
-                                          &ld_so_in_runtime,
-                                          error);
+              fd = _srt_resolve_in_sysroot (self->mutable_sysroot_fd,
+                                            arch->ld_so,
+                                            SRT_RESOLVE_FLAGS_NONE,
+                                            &ld_so_in_runtime,
+                                            error);
 
               if (fd < 0)
                 return FALSE;
@@ -2608,8 +2610,10 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
 
                   gconv_dir_in_provider = g_build_filename ("/usr", dir, "gconv", NULL);
 
-                  if (pv_file_test_in_sysroot (self->provider_in_current_namespace,
-                                               gconv_dir_in_provider, G_FILE_TEST_IS_DIR))
+                  if (_srt_file_test_in_sysroot (self->provider_in_current_namespace,
+                                                 -1,
+                                                 gconv_dir_in_provider,
+                                                 G_FILE_TEST_IS_DIR))
                     {
                       g_hash_table_add (gconv_in_provider, g_steal_pointer (&gconv_dir_in_provider));
                       found = TRUE;
@@ -2638,8 +2642,10 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
                       g_clear_pointer (&gconv_dir_in_provider, g_free);
                       gconv_dir_in_provider = g_build_filename ("/usr", dir, "gconv", NULL);
 
-                      if (pv_file_test_in_sysroot (self->provider_in_current_namespace,
-                                                   gconv_dir_in_provider, G_FILE_TEST_IS_DIR))
+                      if (_srt_file_test_in_sysroot (self->provider_in_current_namespace,
+                                                     -1,
+                                                     gconv_dir_in_provider,
+                                                     G_FILE_TEST_IS_DIR))
                         {
                           g_hash_table_add (gconv_in_provider, g_steal_pointer (&gconv_dir_in_provider));
                           found = TRUE;
@@ -2696,8 +2702,10 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self,
 
                   libdrm_dir_in_provider = g_build_filename (dir, "share", "libdrm", NULL);
 
-                  if (pv_file_test_in_sysroot (self->provider_in_current_namespace,
-                                               libdrm_dir_in_provider, G_FILE_TEST_IS_DIR))
+                  if (_srt_file_test_in_sysroot (self->provider_in_current_namespace,
+                                                 -1,
+                                                 libdrm_dir_in_provider,
+                                                 G_FILE_TEST_IS_DIR))
                     {
                       g_hash_table_add (libdrm_data_in_provider,
                                         g_steal_pointer (&libdrm_dir_in_provider));
@@ -3188,10 +3196,10 @@ pv_runtime_bind (PvRuntime *self,
       g_autofree gchar *dest = NULL;
       glnx_autofd int parent_dirfd = -1;
 
-      parent_dirfd = pv_resolve_in_sysroot (self->mutable_sysroot_fd,
-                                            "/usr/lib/pressure-vessel",
-                                            PV_RESOLVE_FLAGS_MKDIR_P,
-                                            NULL, error);
+      parent_dirfd = _srt_resolve_in_sysroot (self->mutable_sysroot_fd,
+                                              "/usr/lib/pressure-vessel",
+                                              SRT_RESOLVE_FLAGS_MKDIR_P,
+                                              NULL, error);
 
       if (parent_dirfd < 0)
         return FALSE;
diff --git a/pressure-vessel/utils.c b/pressure-vessel/utils.c
index 4236f3328078d93194c642dfb3fb6e989fd1a0ad..5c4add5b7ce75b9456a4325f07800ad8c1031dd9 100644
--- a/pressure-vessel/utils.c
+++ b/pressure-vessel/utils.c
@@ -36,12 +36,11 @@
 #include "libglnx/libglnx.h"
 
 #include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/resolve-in-sysroot-internal.h"
 #include "flatpak-bwrap-private.h"
 #include "flatpak-utils-base-private.h"
 #include "flatpak-utils-private.h"
 
-#include "resolve-in-sysroot.h"
-
 static void
 child_setup_cb (gpointer user_data)
 {
@@ -920,74 +919,3 @@ pv_current_namespace_path_to_host_path (const gchar *current_env_path)
 
   return path_on_host;
 }
-
-/**
- * pv_file_test_in_sysroot:
- * @sysroot: (type filename): A path used as the root
- * @filename: (type filename): A path below the root directory, either
- *  absolute or relative (to the root)
- * @test: The test to perform on the resolved file in @sysroot.
- *  G_FILE_TEST_IS_SYMLINK is not a valid GFileTest value because the
- *  path is resolved following symlinks too.
- *
- * Returns: %TRUE if the @filename resolved in @sysroot passes the @test.
- */
-gboolean
-pv_file_test_in_sysroot (const char *sysroot,
-                         const char *filename,
-                         GFileTest test)
-{
-  glnx_autofd int file_fd = -1;
-  glnx_autofd int sysroot_fd = -1;
-  struct stat stat_buf;
-  g_autofree gchar *file_realpath_in_sysroot = NULL;
-  g_autoptr(GError) error = NULL;
-
-  g_return_val_if_fail (sysroot != NULL, FALSE);
-  g_return_val_if_fail (filename != NULL, FALSE);
-  /* We reject G_FILE_TEST_IS_SYMLINK because the provided filename is resolved
-   * in sysroot, following the eventual symlinks too. So it is not possible for
-   * the resolved filename to be a symlink */
-  g_return_val_if_fail ((test & (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_EXECUTABLE
-                                 | G_FILE_TEST_IS_REGULAR
-                                 | G_FILE_TEST_IS_DIR)) == test, FALSE);
-
-  if (!glnx_opendirat (-1, sysroot, FALSE, &sysroot_fd, &error))
-    {
-      g_debug ("An error occurred trying to open %s: %s", sysroot,
-               error->message);
-      return FALSE;
-    }
-
-  file_fd = pv_resolve_in_sysroot (sysroot_fd,
-                                   filename, PV_RESOLVE_FLAGS_NONE,
-                                   &file_realpath_in_sysroot, &error);
-
-  if (file_fd < 0)
-    {
-      g_debug ("An error occurred trying to resolve %s in sysroot: %s",
-               filename, error->message);
-      return FALSE;
-    }
-
-  if (fstat (file_fd, &stat_buf) != 0)
-    {
-      g_debug ("fstat %s/%s: %s",
-               sysroot, file_realpath_in_sysroot, g_strerror (errno));
-      return FALSE;
-    }
-
-  if (test & G_FILE_TEST_EXISTS)
-    return TRUE;
-
-  if ((test & G_FILE_TEST_IS_EXECUTABLE) && (stat_buf.st_mode & 0111))
-    return TRUE;
-
-  if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (stat_buf.st_mode))
-    return TRUE;
-
-  if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (stat_buf.st_mode))
-    return TRUE;
-
-  return FALSE;
-}
diff --git a/pressure-vessel/utils.h b/pressure-vessel/utils.h
index 3809104722f8c3475c3160270e14e5ec695ae9f8..a30011e09a2c4189e5518be57603cd296b02bf37 100644
--- a/pressure-vessel/utils.h
+++ b/pressure-vessel/utils.h
@@ -71,7 +71,3 @@ gboolean pv_terminate_all_child_processes (GTimeSpan wait_period,
                                            GError **error);
 
 gchar *pv_current_namespace_path_to_host_path (const gchar *current_env_path);
-
-gboolean pv_file_test_in_sysroot (const char *sysroot,
-                                  const char *filename,
-                                  GFileTest test);
diff --git a/steam-runtime-tools/graphics.c b/steam-runtime-tools/graphics.c
index 861c3a696a8e912d2b720539b24e087933338a81..d5e82151c667a0d6581d304c1d6c7a5d1eb2a0ff 100644
--- a/steam-runtime-tools/graphics.c
+++ b/steam-runtime-tools/graphics.c
@@ -1743,8 +1743,7 @@ srt_icd_write_to_file (const SrtIcd *self,
 
 /*
  * load_json_dir:
- * @sysroot: (nullable): Interpret directory names as being inside this
- *  sysroot, mainly for unit testing
+ * @sysroot: (not nullable): The root directory, usually `/`
  * @dir: A directory to search
  * @suffix: (nullable): A path to append to @dir, such as `"vulkan/icd.d"`
  * @sort: (nullable): If not %NULL, load ICDs sorted by filename in this order
@@ -1761,6 +1760,7 @@ load_json_dir (const char *sysroot,
 {
   g_autoptr(GError) error = NULL;
   g_autoptr(GDir) dir_iter = NULL;
+  g_autofree gchar *canon = NULL;
   g_autofree gchar *sysrooted_dir = NULL;
   g_autofree gchar *suffixed_dir = NULL;
   const char *iter_dir;
@@ -1768,26 +1768,28 @@ load_json_dir (const char *sysroot,
   g_autoptr(GPtrArray) members = NULL;
   gsize i;
 
+  g_return_if_fail (sysroot != NULL);
   g_return_if_fail (load_json_cb != NULL);
 
   if (dir == NULL)
     return;
 
+  if (!g_path_is_absolute (dir))
+    {
+      canon = g_canonicalize_filename (dir, NULL);
+      dir = canon;
+    }
+
   if (suffix != NULL)
     {
       suffixed_dir = g_build_filename (dir, suffix, NULL);
       dir = suffixed_dir;
     }
 
-  iter_dir = dir;
+  sysrooted_dir = g_build_filename (sysroot, dir, NULL);
+  iter_dir = sysrooted_dir;
 
-  if (sysroot != NULL)
-    {
-      sysrooted_dir = g_build_filename (sysroot, dir, NULL);
-      iter_dir = sysrooted_dir;
-    }
-
-  g_debug ("Looking for ICDs in %s...", dir);
+  g_debug ("Looking for ICDs in %s (in sysroot %s)...", dir, sysroot);
 
   dir_iter = g_dir_open (iter_dir, 0, &error);
 
@@ -1823,8 +1825,7 @@ load_json_dir (const char *sysroot,
 
 /*
  * load_json_dir:
- * @sysroot: (nullable): Interpret directory names as being inside this
- *  sysroot, mainly for unit testing
+ * @sysroot: (not nullable): The root directory, usually `/`
  * @search_paths: Directories to search
  * @suffix: (nullable): A path to append to @dir, such as `"vulkan/icd.d"`
  * @sort: (nullable): If not %NULL, load ICDs sorted by filename in this order
@@ -1841,6 +1842,7 @@ load_json_dirs (const char *sysroot,
 {
   gchar **iter;
 
+  g_return_if_fail (sysroot != NULL);
   g_return_if_fail (load_json_cb != NULL);
 
   for (iter = search_paths;
@@ -2322,8 +2324,7 @@ srt_egl_icd_get_library_path (SrtEglIcd *self)
 
 /*
  * egl_icd_load_json:
- * @sysroot: Interpret the filename as being inside this sysroot,
- *  mainly for unit testing
+ * @sysroot: (not nullable): The root directory, usually `/`
  * @filename: The filename of the metadata
  * @list: (element-type SrtEglIcd) (inout): Prepend the
  *  resulting #SrtEglIcd to this list
@@ -2336,16 +2337,22 @@ egl_icd_load_json (const char *sysroot,
                    GList **list)
 {
   g_autoptr(GError) error = NULL;
+  g_autofree gchar *canon = NULL;
   g_autofree gchar *in_sysroot = NULL;
   g_autofree gchar *library_path = NULL;
 
+  g_return_if_fail (sysroot != NULL);
   g_return_if_fail (list != NULL);
 
-  if (sysroot != NULL)
-    in_sysroot = g_build_filename (sysroot, filename, NULL);
+  if (!g_path_is_absolute (filename))
+    {
+      canon = g_canonicalize_filename (filename, NULL);
+      filename = canon;
+    }
+
+  in_sysroot = g_build_filename (sysroot, filename, NULL);
 
-  if (load_json (SRT_TYPE_EGL_ICD,
-                 in_sysroot == NULL ? filename : in_sysroot,
+  if (load_json (SRT_TYPE_EGL_ICD, in_sysroot,
                  NULL, &library_path, &error))
     {
       g_assert (library_path != NULL);
@@ -2473,7 +2480,7 @@ get_glvnd_datadir (void)
 
 /*
  * _srt_load_egl_icds:
- * @sysroot: (nullable): Look in this directory instead of the real root
+ * @sysroot: (not nullable): The root directory, usually `/`
  * @envp: (array zero-terminated=1): Behave as though `environ` was this
  *  array
  * @multiarch_tuples: (nullable): If not %NULL, and a Flatpak environment
@@ -2497,6 +2504,7 @@ _srt_load_egl_icds (const char *sysroot,
    * then reverse it at the end. */
   GList *ret = NULL;
 
+  g_return_val_if_fail (sysroot != NULL, NULL);
   g_return_val_if_fail (_srt_check_not_setuid (), NULL);
 
   if (envp == NULL)
@@ -2527,8 +2535,7 @@ _srt_load_egl_icds (const char *sysroot,
 
       value = g_environ_getenv (envp, "__EGL_VENDOR_LIBRARY_DIRS");
 
-      flatpak_info = g_build_filename (sysroot != NULL ? sysroot : "/",
-                                       ".flatpak-info", NULL);
+      flatpak_info = g_build_filename (sysroot, ".flatpak-info", NULL);
 
       if (value != NULL)
         {
@@ -3288,7 +3295,7 @@ out:
 
 /**
  * _srt_get_modules_full:
- * @sysroot: (nullable): Look in this directory instead of the real root
+ * @sysroot: (not nullable): The root directory, usually `/`
  * @envp: (array zero-terminated=1): Behave as though `environ` was this array
  * @helpers_path: (nullable): An optional path to find "inspect-library" helper, PATH is used if %NULL
  * @multiarch_tuple: (not nullable) (type filename): A Debian-style multiarch tuple
@@ -3331,6 +3338,7 @@ _srt_get_modules_full (const char *sysroot,
 
   g_return_if_fail (multiarch_tuple != NULL);
   g_return_if_fail (drivers_out != NULL);
+  g_return_if_fail (sysroot != NULL);
   g_return_if_fail (_srt_check_not_setuid ());
 
   switch (module)
@@ -3369,9 +3377,6 @@ _srt_get_modules_full (const char *sysroot,
       ld_library_path = g_getenv ("LD_LIBRARY_PATH");
     }
 
-  if (sysroot == NULL)
-    sysroot = "/";
-
   flatpak_info = g_build_filename (sysroot, ".flatpak-info", NULL);
   drivers_set = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
@@ -3661,7 +3666,7 @@ out:
 
 /*
  * _srt_list_glx_icds:
- * @sysroot: (nullable): Look in this directory instead of the real root
+ * @sysroot: (not nullable): The root directory, usually `/`
  * @envp: (array zero-terminated=1): Behave as though `environ` was this array
  * @helpers_path: (nullable): An optional path to find "capsule-capture-libs" helper,
  *  PATH is used if %NULL
@@ -3687,6 +3692,7 @@ _srt_list_glx_icds (const char *sysroot,
   gchar *overrides_path = NULL;
   GHashTable *known_libs = NULL;
 
+  g_return_if_fail (sysroot != NULL);
   g_return_if_fail (multiarch_tuple != NULL);
   g_return_if_fail (drivers_out != NULL);
   g_return_if_fail (_srt_check_not_setuid ());
@@ -3713,7 +3719,7 @@ _srt_list_glx_icds (const char *sysroot,
   /* When in a container we might miss valid GLX drivers because the `ld.so.cache` in
    * use doesn't have a reference about them. To fix that we also include every
    * "libGLX_*.so.*" libraries that we find in the "/overrides/lib/${multiarch}" folder */
-  overrides_path = sysroot ? g_build_filename (sysroot, "/overrides", NULL) : g_strdup ("/overrides");
+  overrides_path = g_build_filename (sysroot, "/overrides", NULL);
   if (g_file_test (overrides_path, G_FILE_TEST_IS_DIR))
     {
       overrides_tmp_dir = g_dir_make_tmp ("glx-icds-XXXXXX", &error);
@@ -3757,7 +3763,7 @@ out:
 
 /**
  * _srt_list_graphics_modules:
- * @sysroot: (nullable): Look in this directory instead of the real root
+ * @sysroot: (not nullable): The root directory, usually `/`
  * @envp: (array zero-terminated=1): Behave as though `environ` was this array
  * @helpers_path: (nullable): An optional path to find "inspect-library" helper, PATH is used if %NULL
  * @multiarch_tuple: (not nullable) (type filename): A Debian-style multiarch tuple
@@ -3786,6 +3792,7 @@ _srt_list_graphics_modules (const char *sysroot,
 {
   GList *drivers = NULL;
 
+  g_return_val_if_fail (sysroot != NULL, NULL);
   g_return_val_if_fail (multiarch_tuple != NULL, NULL);
 
   if (which == SRT_GRAPHICS_GLX_MODULE)
@@ -4747,8 +4754,7 @@ srt_vulkan_icd_new_replace_library_path (SrtVulkanIcd *self,
 
 /*
  * vulkan_icd_load_json:
- * @sysroot: Interpret the filename as being inside this sysroot,
- *  mainly for unit testing
+ * @sysroot: (not nullable): The root directory, usually `/`
  * @filename: The filename of the metadata
  * @list: (element-type SrtVulkanIcd) (inout): Prepend the
  *  resulting #SrtVulkanIcd to this list
@@ -4761,17 +4767,22 @@ vulkan_icd_load_json (const char *sysroot,
                       GList **list)
 {
   g_autoptr(GError) error = NULL;
+  g_autofree gchar *canon = NULL;
   g_autofree gchar *in_sysroot = NULL;
   g_autofree gchar *api_version = NULL;
   g_autofree gchar *library_path = NULL;
 
   g_return_if_fail (list != NULL);
 
-  if (sysroot != NULL)
-    in_sysroot = g_build_filename (sysroot, filename, NULL);
+  if (!g_path_is_absolute (filename))
+    {
+      canon = g_canonicalize_filename (filename, NULL);
+      filename = canon;
+    }
+
+  in_sysroot = g_build_filename (sysroot, filename, NULL);
 
-  if (load_json (SRT_TYPE_VULKAN_ICD,
-                 in_sysroot == NULL ? filename : in_sysroot,
+  if (load_json (SRT_TYPE_VULKAN_ICD, in_sysroot,
                  &api_version, &library_path, &error))
     {
       g_assert (api_version != NULL);
@@ -4814,7 +4825,7 @@ get_vulkan_sysconfdir (void)
 
 /*
  * _srt_load_vulkan_icds:
- * @sysroot: (nullable): Look in this directory instead of the real root
+ * @sysroot: (not nullable): The root directory, usually `/`
  * @envp: (array zero-terminated=1): Behave as though `environ` was this
  *  array
  * @multiarch_tuples: (nullable): If not %NULL, and a Flatpak environment
@@ -4898,8 +4909,7 @@ _srt_load_vulkan_icds (const char *sysroot,
         load_json_dir (sysroot, "/etc", VULKAN_ICD_SUFFIX,
                        READDIR_ORDER, vulkan_icd_load_json_cb, &ret);
 
-      flatpak_info = g_build_filename (sysroot != NULL ? sysroot : "/",
-                                       ".flatpak-info", NULL);
+      flatpak_info = g_build_filename (sysroot, ".flatpak-info", NULL);
 
       /* freedesktop-sdk patches the Vulkan loader to look here. */
       if (g_file_test (flatpak_info, G_FILE_TEST_EXISTS)
diff --git a/steam-runtime-tools/meson.build b/steam-runtime-tools/meson.build
index 86e8b85cceaf0df574ade38a861e36b48931d867..4030b0052060581c6467eaf4ab7ec9777ad47163 100644
--- a/steam-runtime-tools/meson.build
+++ b/steam-runtime-tools/meson.build
@@ -38,6 +38,8 @@ libsteamrt_sources = [
     'locale.c',
     'os-internal.h',
     'os.c',
+    'resolve-in-sysroot-internal.h',
+    'resolve-in-sysroot.c',
     'runtime-internal.h',
     'runtime.c',
     'steam-internal.h',
diff --git a/steam-runtime-tools/os-internal.h b/steam-runtime-tools/os-internal.h
index 01cd0cfa567762b0c8bcb8e3bba7322397fd3d27..959b184e7d2d96d2e8e2b1bf30fea42cd2559be6 100644
--- a/steam-runtime-tools/os-internal.h
+++ b/steam-runtime-tools/os-internal.h
@@ -46,7 +46,8 @@ typedef struct
 
 G_GNUC_INTERNAL void _srt_os_release_init (SrtOsRelease *self);
 G_GNUC_INTERNAL void _srt_os_release_populate (SrtOsRelease *self,
-                                               const char *sysroot);
+                                               const char *sysroot,
+                                               int sysroot_fd);
 G_GNUC_INTERNAL void _srt_os_release_clear (SrtOsRelease *self);
 void _srt_os_release_populate_from_report (JsonObject *json_obj,
                                            SrtOsRelease *self);
diff --git a/steam-runtime-tools/os.c b/steam-runtime-tools/os.c
index e408e5430175646949ff35aec5d9e380aba0e68e..3f0a4a00a52a4777d3ea8864e89ae534ec3bc2a3 100644
--- a/steam-runtime-tools/os.c
+++ b/steam-runtime-tools/os.c
@@ -141,7 +141,8 @@ do_line (SrtOsRelease *self,
 
 G_GNUC_INTERNAL void
 _srt_os_release_populate (SrtOsRelease *self,
-                          const char *sysroot)
+                          const char *sysroot,
+                          int sysroot_fd)
 {
   gsize i;
 
@@ -155,33 +156,28 @@ _srt_os_release_populate (SrtOsRelease *self,
   g_return_if_fail (self->variant_id == NULL);
   g_return_if_fail (self->version_codename == NULL);
   g_return_if_fail (self->version_id == NULL);
+  g_return_if_fail (sysroot != NULL);
+  g_return_if_fail (sysroot_fd >= 0);
 
   for (i = 0; i < G_N_ELEMENTS (os_release_paths); i++)
     {
+      g_autoptr(GError) local_error = NULL;
       const char *path = os_release_paths[i].path;
       gboolean only_in_run_host = os_release_paths[i].only_in_run_host;
-      gchar *built_path = NULL;
-      gchar *contents = NULL;
+      g_autofree gchar *contents = NULL;
       char *beginning_of_line;
-      GError *local_error = NULL;
       gsize len;
       gsize j;
 
       if (only_in_run_host
-          && (sysroot == NULL || !g_str_has_suffix (sysroot, "/run/host")))
+          && !g_str_has_suffix (sysroot, "/run/host"))
         continue;
 
-      if (sysroot != NULL)
+      if (!_srt_file_get_contents_in_sysroot (sysroot_fd, path,
+                                              &contents, &len,
+                                              &local_error))
         {
-          built_path = g_build_filename (sysroot, path, NULL);
-          path = built_path;
-        }
-
-      if (!g_file_get_contents (path, &contents, &len, &local_error))
-        {
-          g_debug ("Unable to open %s: %s", path, local_error->message);
-          g_clear_error (&local_error);
-          g_free (built_path);
+          g_debug ("%s", local_error->message);
           continue;
         }
 
@@ -201,9 +197,6 @@ _srt_os_release_populate (SrtOsRelease *self,
 
       /* Collect a possible partial line */
       do_line (self, path, beginning_of_line);
-
-      g_free (contents);
-      g_free (built_path);
       break;
     }
 
diff --git a/pressure-vessel/resolve-in-sysroot.h b/steam-runtime-tools/resolve-in-sysroot-internal.h
similarity index 51%
rename from pressure-vessel/resolve-in-sysroot.h
rename to steam-runtime-tools/resolve-in-sysroot-internal.h
index 2941030c63d2328301b0e1df4fe80541d3bcf17a..7d47024e76d347b474ebdea332486d4dbc93a10f 100644
--- a/pressure-vessel/resolve-in-sysroot.h
+++ b/steam-runtime-tools/resolve-in-sysroot-internal.h
@@ -22,31 +22,35 @@
 #include <glib.h>
 
 /*
- * PvResolveFlags:
- * @PV_RESOLVE_FLAGS_MKDIR_P: Create the filename to be resolved and
+ * SrtResolveFlags:
+ * @SRT_RESOLVE_FLAGS_MKDIR_P: Create the filename to be resolved and
  *  all of its ancestors as directories. If any already exist, they
  *  must be directories or symlinks to directories.
- * @PV_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK: If the last component of
+ * @SRT_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK: If the last component of
  *  the path is a symlink, return a fd pointing to the symlink itself.
- * @PV_RESOLVE_FLAGS_REJECT_SYMLINKS: If any component of
+ * @SRT_RESOLVE_FLAGS_REJECT_SYMLINKS: If any component of
  *  the path is a symlink, fail with %G_IO_ERROR_TOO_MANY_LINKS.
- * @PV_RESOLVE_FLAGS_READABLE: Open the last component of the path
+ * @SRT_RESOLVE_FLAGS_READABLE: Open the last component of the path
  *  for reading, instead of just as `O_PATH`.
- * @PV_RESOLVE_FLAGS_NONE: No special behaviour.
+ * @SRT_RESOLVE_FLAGS_DIRECTORY: Open the last component of the path
+ *  for reading, and it must be a directory.
+ * @SRT_RESOLVE_FLAGS_NONE: No special behaviour.
  *
- * Flags affecting how pv_resolve_in_sysroot() behaves.
+ * Flags affecting how _srt_resolve_in_sysroot() behaves.
  */
 typedef enum
 {
-  PV_RESOLVE_FLAGS_MKDIR_P = (1 << 0),
-  PV_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK = (1 << 1),
-  PV_RESOLVE_FLAGS_REJECT_SYMLINKS = (1 << 2),
-  PV_RESOLVE_FLAGS_READABLE = (1 << 3),
-  PV_RESOLVE_FLAGS_NONE = 0
-} PvResolveFlags;
+  SRT_RESOLVE_FLAGS_MKDIR_P = (1 << 0),
+  SRT_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK = (1 << 1),
+  SRT_RESOLVE_FLAGS_REJECT_SYMLINKS = (1 << 2),
+  SRT_RESOLVE_FLAGS_READABLE = (1 << 3),
+  SRT_RESOLVE_FLAGS_DIRECTORY = (1 << 4),
+  SRT_RESOLVE_FLAGS_NONE = 0
+} SrtResolveFlags;
 
-int pv_resolve_in_sysroot (int sysroot,
-                           const char *descendant,
-                           PvResolveFlags flags,
-                           gchar **real_path_out,
-                           GError **error) G_GNUC_WARN_UNUSED_RESULT;
+G_GNUC_INTERNAL
+int _srt_resolve_in_sysroot (int sysroot,
+                             const char *descendant,
+                             SrtResolveFlags flags,
+                             gchar **real_path_out,
+                             GError **error) G_GNUC_WARN_UNUSED_RESULT;
diff --git a/pressure-vessel/resolve-in-sysroot.c b/steam-runtime-tools/resolve-in-sysroot.c
similarity index 91%
rename from pressure-vessel/resolve-in-sysroot.c
rename to steam-runtime-tools/resolve-in-sysroot.c
index 58a74bc7702ca5f4faf5a21a143f6cd220d455b7..21965157ee34bc16262527ab77dfc6487fe2496e 100644
--- a/pressure-vessel/resolve-in-sysroot.c
+++ b/steam-runtime-tools/resolve-in-sysroot.c
@@ -17,7 +17,7 @@
  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "resolve-in-sysroot.h"
+#include "steam-runtime-tools/resolve-in-sysroot-internal.h"
 
 #include <glib.h>
 #include <glib/gstdio.h>
@@ -67,7 +67,7 @@ fd_array_take (GArray *fds,
 }
 
 /*
- * pv_resolve_in_sysroot:
+ * _srt_resolve_in_sysroot:
  * @sysroot: (transfer none): A file descriptor representing the root
  * @descendant: (type filename): A path below the root directory, either
  *  absolute or relative (to the root)
@@ -78,7 +78,7 @@ fd_array_take (GArray *fds,
  *
  * Open @descendant as though @sysroot was the root directory.
  *
- * If %PV_RESOLVE_FLAGS_MKDIR_P is in @flags, each path segment in
+ * If %SRT_RESOLVE_FLAGS_MKDIR_P is in @flags, each path segment in
  * @descendant must be a directory, a symbolic link to a directory,
  * or nonexistent (in which case a directory will be created, currently
  * with hard-coded 0700 permissions).
@@ -87,11 +87,11 @@ fd_array_take (GArray *fds,
  *  or -1 on error
  */
 int
-pv_resolve_in_sysroot (int sysroot,
-                       const char *descendant,
-                       PvResolveFlags flags,
-                       gchar **real_path_out,
-                       GError **error)
+_srt_resolve_in_sysroot (int sysroot,
+                         const char *descendant,
+                         SrtResolveFlags flags,
+                         gchar **real_path_out,
+                         GError **error)
 {
   g_autoptr(GString) current_path = g_string_new ("");
   /* Array of fds pointing to directories beneath @sysroot.
@@ -196,7 +196,7 @@ pv_resolve_in_sysroot (int sysroot,
       fd = TEMP_FAILURE_RETRY (openat (g_array_index (fds, int, fds->len - 1),
                                        next, open_flags));
 
-      if (fd < 0 && errno == ENOENT && (flags & PV_RESOLVE_FLAGS_MKDIR_P) != 0)
+      if (fd < 0 && errno == ENOENT && (flags & SRT_RESOLVE_FLAGS_MKDIR_P) != 0)
         {
           if (TEMP_FAILURE_RETRY (mkdirat (g_array_index (fds, int, fds->len - 1),
                                            next, 0700)) != 0)
@@ -225,13 +225,13 @@ pv_resolve_in_sysroot (int sysroot,
 
       if (target != NULL)   /* Yes, it's a symlink */
         {
-          if (flags & PV_RESOLVE_FLAGS_REJECT_SYMLINKS)
+          if (flags & SRT_RESOLVE_FLAGS_REJECT_SYMLINKS)
             {
               g_set_error (error, G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS,
                            "\"%s/%s\" is a symlink", current_path->str, next);
               return -1;
             }
-          else if ((flags & PV_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK) != 0 &&
+          else if ((flags & SRT_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK) != 0 &&
                    remaining == NULL)
             {
               /* Treat as though not a symlink. */
@@ -273,7 +273,7 @@ pv_resolve_in_sysroot (int sysroot,
         {
           /* If we are emulating mkdir -p, or if we will go on to open
            * a member of @fd, then it had better be a directory. */
-          if ((flags & PV_RESOLVE_FLAGS_MKDIR_P) != 0 ||
+          if ((flags & SRT_RESOLVE_FLAGS_MKDIR_P) != 0 ||
               remaining != NULL)
             {
               struct stat stat_buf;
@@ -303,15 +303,23 @@ pv_resolve_in_sysroot (int sysroot,
         }
     }
 
-  if (flags & PV_RESOLVE_FLAGS_READABLE)
+  if (flags & (SRT_RESOLVE_FLAGS_READABLE|SRT_RESOLVE_FLAGS_DIRECTORY))
     {
       g_autofree char *proc_fd_name = g_strdup_printf ("/proc/self/fd/%d",
                                                        g_array_index (fds, int,
                                                                       fds->len - 1));
       glnx_autofd int fd = -1;
 
-      if (!glnx_openat_rdonly (-1, proc_fd_name, TRUE, &fd, error))
-        return -1;
+      if (flags & SRT_RESOLVE_FLAGS_DIRECTORY)
+        {
+          if (!glnx_opendirat (-1, proc_fd_name, TRUE, &fd, error))
+            return -1;
+        }
+      else
+        {
+          if (!glnx_openat_rdonly (-1, proc_fd_name, TRUE, &fd, error))
+            return -1;
+        }
 
       if (real_path_out != NULL)
         *real_path_out = g_string_free (g_steal_pointer (&current_path), FALSE);
diff --git a/steam-runtime-tools/system-info.c b/steam-runtime-tools/system-info.c
index a4fab61ece18277dccfbb21fd15e7b5d0c91ceae..770c701d059d89ff11e569af1ad4613377689bdf 100644
--- a/steam-runtime-tools/system-info.c
+++ b/steam-runtime-tools/system-info.c
@@ -35,6 +35,7 @@
 #include "steam-runtime-tools/library-internal.h"
 #include "steam-runtime-tools/locale-internal.h"
 #include "steam-runtime-tools/os-internal.h"
+#include "steam-runtime-tools/resolve-in-sysroot-internal.h"
 #include "steam-runtime-tools/runtime-internal.h"
 #include "steam-runtime-tools/steam-internal.h"
 #include "steam-runtime-tools/utils-internal.h"
@@ -95,7 +96,7 @@ struct _SrtSystemInfo
   GObject parent;
   /* "" if we have tried and failed to auto-detect */
   gchar *expectations;
-  /* Fake root directory, or %NULL to use the real root */
+  /* Root directory to inspect, usually "/" */
   gchar *sysroot;
   /* Fake environment variables, or %NULL to use the real environment */
   gchar **env;
@@ -170,6 +171,7 @@ struct _SrtSystemInfo
   gchar **cached_driver_environment;
   /* (element-type Abi) */
   GPtrArray *abis;
+  int sysroot_fd;
 };
 
 struct _SrtSystemInfoClass
@@ -310,6 +312,7 @@ static void
 srt_system_info_init (SrtSystemInfo *self)
 {
   self->can_write_uinput = TRI_MAYBE;
+  self->sysroot_fd = -1;
 
   /* Assume that in practice we will usually add two ABIs: amd64 and i386 */
   self->abis = g_ptr_array_new_full (2, abi_free);
@@ -317,6 +320,8 @@ srt_system_info_init (SrtSystemInfo *self)
   _srt_os_release_init (&self->os_release);
 
   self->container.type = SRT_CONTAINER_TYPE_UNKNOWN;
+
+  srt_system_info_set_sysroot (self, "/");
 }
 
 static void
@@ -480,6 +485,7 @@ srt_system_info_finalize (GObject *object)
   g_free (self->expectations);
   g_free (self->helpers_path);
   g_free (self->sysroot);
+  glnx_close_fd (&self->sysroot_fd);
   g_strfreev (self->env);
   g_clear_pointer (&self->cached_driver_environment, g_strfreev);
   if (self->cached_hidden_deps)
@@ -1024,7 +1030,7 @@ ensure_overrides_cached (SrtSystemInfo *self)
       if (g_strcmp0 (runtime, "/") != 0)
         goto out;
 
-      if (!g_spawn_sync (self->sysroot == NULL ? "/" : self->sysroot, /* working directory */
+      if (!g_spawn_sync (self->sysroot,     /* working directory */
                         (gchar **) argv,
                         get_environ (self),
                         G_SPAWN_SEARCH_PATH,
@@ -1908,9 +1914,14 @@ void
 srt_system_info_set_sysroot (SrtSystemInfo *self,
                              const char *root)
 {
+  g_autoptr(GError) local_error = NULL;
+
   g_return_if_fail (SRT_IS_SYSTEM_INFO (self));
   g_return_if_fail (!self->immutable_values);
 
+  if (root == NULL)
+    root = "/";
+
   forget_container_info (self);
   forget_graphics_modules (self);
   forget_libraries (self);
@@ -1919,7 +1930,19 @@ srt_system_info_set_sysroot (SrtSystemInfo *self,
   forget_os (self);
   forget_overrides (self);
   g_free (self->sysroot);
+  glnx_close_fd (&self->sysroot_fd);
+
   self->sysroot = g_strdup (root);
+
+  if (!glnx_opendirat (-1,
+                       self->sysroot,
+                       FALSE,
+                       &self->sysroot_fd,
+                       &local_error))
+    {
+      g_debug ("Unable to open sysroot %s: %s",
+               self->sysroot, local_error->message);
+    }
 }
 
 static void
@@ -2078,8 +2101,11 @@ srt_system_info_dup_steam_bin32_path (SrtSystemInfo *self)
 static void
 ensure_os_cached (SrtSystemInfo *self)
 {
-  if (!self->os_release.populated && !self->immutable_values)
-    _srt_os_release_populate (&self->os_release, self->sysroot);
+  if (!self->os_release.populated
+      && !self->immutable_values
+      && self->sysroot_fd >= 0)
+    _srt_os_release_populate (&self->os_release, self->sysroot,
+                              self->sysroot_fd);
 }
 
 /**
@@ -3215,114 +3241,98 @@ container_type_from_name (const char *name)
 static void
 ensure_container_info (SrtSystemInfo *self)
 {
-  const char *sysroot = NULL;
-  gchar *contents = NULL;
-  gchar *filename = NULL;
+  g_autofree gchar *contents = NULL;
+  g_autofree gchar *run_host_path = NULL;
+  glnx_autofd int run_host_fd = -1;
 
   if (self->container.have_data || self->immutable_values)
     return;
 
   g_assert (self->container.host_directory == NULL);
   g_assert (self->container.type == SRT_CONTAINER_TYPE_UNKNOWN);
+  g_assert (self->sysroot != NULL);
 
-  sysroot = self->sysroot;
+  if (self->sysroot_fd < 0)
+    {
+      g_debug ("Cannot find container info: previously failed to open "
+               "sysroot %s", self->sysroot);
+      goto out;
+    }
 
-  if (sysroot == NULL)
-    sysroot = "/";
+  g_debug ("Finding container info in sysroot %s...", self->sysroot);
 
-  g_debug ("Finding container info in sysroot %s...", sysroot);
+  run_host_fd = _srt_resolve_in_sysroot (self->sysroot_fd, "/run/host",
+                                         SRT_RESOLVE_FLAGS_DIRECTORY,
+                                         &run_host_path, NULL);
 
-  filename = g_build_filename (sysroot, "run", "systemd", "container", NULL);
+  if (run_host_path != NULL)
+    self->container.host_directory = g_build_filename (self->sysroot,
+                                                       run_host_path,
+                                                       NULL);
 
-  if (g_file_get_contents (filename, &contents, NULL, NULL))
+  if (_srt_file_get_contents_in_sysroot (self->sysroot_fd,
+                                         "/run/systemd/container",
+                                         &contents, NULL, NULL))
     {
       g_strchomp (contents);
       self->container.type = container_type_from_name (contents);
-      g_debug ("Type %d based on %s", self->container.type, filename);
+      g_debug ("Type %d based on /run/systemd/container",
+               self->container.type);
       goto out;
     }
 
-  g_clear_pointer (&filename, g_free);
-  filename = g_build_filename (sysroot, ".flatpak-info", NULL);
-
-  if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
+  if (_srt_file_test_in_sysroot (self->sysroot, self->sysroot_fd,
+                                 "/.flatpak-info", G_FILE_TEST_IS_REGULAR))
     {
       self->container.type = SRT_CONTAINER_TYPE_FLATPAK;
-      g_debug ("Flatpak based on %s", filename);
+      g_debug ("Flatpak based on /.flatpak-info");
       goto out;
     }
 
-  g_clear_pointer (&filename, g_free);
-  filename = g_build_filename (sysroot, "run", "pressure-vessel", NULL);
-
-  if (g_file_test (filename, G_FILE_TEST_IS_DIR))
+  if (_srt_file_test_in_sysroot (self->sysroot, self->sysroot_fd,
+                                 "/run/pressure-vessel", G_FILE_TEST_IS_DIR))
     {
       self->container.type = SRT_CONTAINER_TYPE_PRESSURE_VESSEL;
-      g_debug ("pressure-vessel based on %s", filename);
+      g_debug ("pressure-vessel based on /run/pressure-vessel");
       goto out;
     }
 
-  g_clear_pointer (&filename, g_free);
-  filename = g_build_filename (sysroot, ".dockerenv", NULL);
-
-  if (g_file_test (filename, G_FILE_TEST_EXISTS))
+  if (_srt_file_test_in_sysroot (self->sysroot, self->sysroot_fd,
+                                 "/.dockerenv", G_FILE_TEST_EXISTS))
     {
       self->container.type = SRT_CONTAINER_TYPE_DOCKER;
-      g_debug ("Docker based on %s", filename);
+      g_debug ("Docker based on /.dockerenv");
       goto out;
     }
 
-  g_clear_pointer (&filename, g_free);
-  filename = g_build_filename (sysroot, "proc", "1", "cgroup", NULL);
-
-  if (g_file_get_contents (filename, &contents, NULL, NULL))
+  if (_srt_file_get_contents_in_sysroot (self->sysroot_fd,
+                                         "/proc/1/cgroup",
+                                         &contents, NULL, NULL))
     {
       if (strstr (contents, "/docker/") != NULL)
         self->container.type = SRT_CONTAINER_TYPE_DOCKER;
 
       if (self->container.type != SRT_CONTAINER_TYPE_UNKNOWN)
         {
-          g_debug ("Type %d based on %s", self->container.type, filename);
+          g_debug ("Type %d based on /proc/1/cgroup", self->container.type);
           goto out;
         }
-    }
 
-  g_clear_pointer (&filename, g_free);
-  filename = g_build_filename (sysroot, "run", "host", NULL);
+      g_clear_pointer (&contents, g_free);
+    }
 
-  if (g_file_test (filename, G_FILE_TEST_IS_DIR))
+  if (run_host_fd >= 0)
     {
-      g_debug ("Unknown container technology based on %s", filename);
+      g_debug ("Unknown container technology based on /run/host");
       self->container.type = SRT_CONTAINER_TYPE_UNKNOWN;
-      self->container.host_directory = g_steal_pointer (&filename);
       goto out;
     }
 
-  g_clear_pointer (&filename, g_free);
-
   /* We haven't found any particular evidence of being in a container */
   g_debug ("Probably not a container");
   self->container.type = SRT_CONTAINER_TYPE_NONE;
 
 out:
-  g_free (contents);
-  g_free (filename);
-
-  switch (self->container.type)
-    {
-      case SRT_CONTAINER_TYPE_FLATPAK:
-      case SRT_CONTAINER_TYPE_PRESSURE_VESSEL:
-        self->container.host_directory = g_build_filename (sysroot, "run",
-                                                           "host", NULL);
-        break;
-
-      case SRT_CONTAINER_TYPE_DOCKER:
-      case SRT_CONTAINER_TYPE_UNKNOWN:
-      case SRT_CONTAINER_TYPE_NONE:
-      default:
-        break;
-    }
-
   self->container.have_data = TRUE;
 }
 
diff --git a/steam-runtime-tools/utils-internal.h b/steam-runtime-tools/utils-internal.h
index 308e60a1b9ec084a34820ab3d0ae549ae775e423..dc5d7c92cca8997275e46ec252244b0dabdb5c60 100644
--- a/steam-runtime-tools/utils-internal.h
+++ b/steam-runtime-tools/utils-internal.h
@@ -87,3 +87,16 @@ gchar ** _srt_json_array_to_strv (JsonObject *json_obj,
 gboolean _srt_rm_rf (const char *directory);
 
 FILE *_srt_divert_stdout_to_stderr (GError **error);
+
+G_GNUC_INTERNAL
+gboolean _srt_file_get_contents_in_sysroot (int sysroot_fd,
+                                            const char *path,
+                                            gchar **contents,
+                                            gsize *len,
+                                            GError **error);
+
+G_GNUC_INTERNAL
+gboolean _srt_file_test_in_sysroot (const char *sysroot,
+                                    int sysroot_fd,
+                                    const char *filename,
+                                    GFileTest test);
diff --git a/steam-runtime-tools/utils.c b/steam-runtime-tools/utils.c
index cd059711b13c33d3820ee7a33a99befa83287921..223a0656518c9845842bd2893e9d211d248717f5 100644
--- a/steam-runtime-tools/utils.c
+++ b/steam-runtime-tools/utils.c
@@ -44,6 +44,7 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 #include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/resolve-in-sysroot-internal.h"
 
 #ifdef HAVE_GETAUXVAL
 #define getauxval_AT_SECURE() getauxval (AT_SECURE)
@@ -862,3 +863,136 @@ _srt_divert_stdout_to_stderr (GError **error)
 
   return g_steal_pointer (&original_stdout);
 }
+
+/*
+ * _srt_file_get_contents_in_sysroot:
+ * @sysroot_fd: A directory fd opened on the sysroot or `/`
+ * @path: Absolute or root-relative path within @sysroot_fd
+ * @contents: (out) (not optional): Used to return contents
+ * @len: (out) (optional): Used to return length
+ * @error: Used to return error on failure
+ *
+ * Like g_file_get_contents(), but the file is in a sysroot, and we
+ * follow symlinks as though @sysroot_fd was the root directory
+ * (similar to `fakechroot`).
+ *
+ * Returns: %TRUE if successful
+ */
+gboolean
+_srt_file_get_contents_in_sysroot (int sysroot_fd,
+                                   const char *path,
+                                   gchar **contents,
+                                   gsize *len,
+                                   GError **error)
+{
+  g_autofree gchar *real_path = NULL;
+  g_autofree gchar *fd_path = NULL;
+  g_autofree gchar *ignored = NULL;
+  glnx_autofd int fd = -1;
+
+  g_return_val_if_fail (sysroot_fd >= 0, FALSE);
+  g_return_val_if_fail (path != NULL, FALSE);
+  g_return_val_if_fail (contents != NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  if (contents == NULL)
+    contents = &ignored;
+
+  fd = _srt_resolve_in_sysroot (sysroot_fd,
+                                path,
+                                SRT_RESOLVE_FLAGS_READABLE,
+                                &real_path,
+                                error);
+
+  if (fd < 0)
+    return FALSE;
+
+  fd_path = g_strdup_printf ("/proc/self/fd/%d", fd);
+
+  if (!g_file_get_contents (fd_path, contents, len, error))
+    {
+      g_prefix_error (error, "Unable to read %s: ", real_path);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+/*
+ * _srt_file_test_in_sysroot:
+ * @sysroot: (type filename): A path used as the root
+ * @sysroot_fd: A file descriptor opened on @sysroot, or negative to
+ *  reopen it
+ * @filename: (type filename): A path below the root directory, either
+ *  absolute or relative (to the root)
+ * @test: The test to perform on the resolved file in @sysroot.
+ *  G_FILE_TEST_IS_SYMLINK is not a valid GFileTest value because the
+ *  path is resolved following symlinks too.
+ *
+ * Returns: %TRUE if the @filename resolved in @sysroot passes the @test.
+ */
+gboolean
+_srt_file_test_in_sysroot (const char *sysroot,
+                           int sysroot_fd,
+                           const char *filename,
+                           GFileTest test)
+{
+  glnx_autofd int file_fd = -1;
+  glnx_autofd int local_sysroot_fd = -1;
+  struct stat stat_buf;
+  g_autofree gchar *file_realpath_in_sysroot = NULL;
+  g_autoptr(GError) error = NULL;
+
+  g_return_val_if_fail (sysroot != NULL, FALSE);
+  g_return_val_if_fail (filename != NULL, FALSE);
+  /* We reject G_FILE_TEST_IS_SYMLINK because the provided filename is resolved
+   * in sysroot, following the eventual symlinks too. So it is not possible for
+   * the resolved filename to be a symlink */
+  g_return_val_if_fail ((test & (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_EXECUTABLE
+                                 | G_FILE_TEST_IS_REGULAR
+                                 | G_FILE_TEST_IS_DIR)) == test, FALSE);
+
+  if (sysroot_fd < 0)
+    {
+      if (!glnx_opendirat (-1, sysroot, FALSE, &local_sysroot_fd, &error))
+        {
+          g_debug ("An error occurred trying to open %s: %s", sysroot,
+                   error->message);
+          return FALSE;
+        }
+
+      sysroot_fd = local_sysroot_fd;
+    }
+
+  file_fd = _srt_resolve_in_sysroot (sysroot_fd,
+                                     filename, SRT_RESOLVE_FLAGS_NONE,
+                                     &file_realpath_in_sysroot, &error);
+
+  if (file_fd < 0)
+    {
+      g_debug ("An error occurred trying to resolve %s in sysroot: %s",
+               filename, error->message);
+      return FALSE;
+    }
+
+  if (fstat (file_fd, &stat_buf) != 0)
+    {
+      g_debug ("fstat %s/%s: %s",
+               sysroot, file_realpath_in_sysroot, g_strerror (errno));
+      return FALSE;
+    }
+
+  if (test & G_FILE_TEST_EXISTS)
+    return TRUE;
+
+  if ((test & G_FILE_TEST_IS_EXECUTABLE) && (stat_buf.st_mode & 0111))
+    return TRUE;
+
+  if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (stat_buf.st_mode))
+    return TRUE;
+
+  if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (stat_buf.st_mode))
+    return TRUE;
+
+  return FALSE;
+}
diff --git a/tests/pressure-vessel/resolve-in-sysroot.c b/tests/pressure-vessel/resolve-in-sysroot.c
index df57deab13f16ea3480771c19dfdc5b9119c11b8..bade3586d342b48abf63d1188f8a3992e5ada64d 100644
--- a/tests/pressure-vessel/resolve-in-sysroot.c
+++ b/tests/pressure-vessel/resolve-in-sysroot.c
@@ -30,9 +30,9 @@
 #include <glib/gstdio.h>
 
 #include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/resolve-in-sysroot-internal.h"
 #include "libglnx/libglnx.h"
 
-#include "resolve-in-sysroot.h"
 #include "tests/test-utils.h"
 #include "utils.h"
 
@@ -91,7 +91,7 @@ typedef struct
   struct
   {
     const char *path;
-    PvResolveFlags flags;
+    SrtResolveFlags flags;
     ResolveCallFlags test_flags;
   } call;
   struct
@@ -110,6 +110,10 @@ test_resolve_in_sysroot (Fixture *f,
     "a/b/c/d/e",
     "a/b2/c2/d2/e2",
   };
+  static const char * const prepare_files[] =
+  {
+    "a/b/c/file",
+  };
   static const Symlink prepare_symlinks[] =
   {
     { "a/b/symlink_to_c", "c" },
@@ -123,60 +127,75 @@ test_resolve_in_sysroot (Fixture *f,
   {
     { { "a/b/c/d" }, { "a/b/c/d" } },
     {
-      { "a/b/c/d", PV_RESOLVE_FLAGS_NONE, RESOLVE_CALL_FLAGS_IGNORE_PATH },
+      { "a/b/c/d", SRT_RESOLVE_FLAGS_NONE, RESOLVE_CALL_FLAGS_IGNORE_PATH },
       { "a/b/c/d" },
     },
-    { { "a/b/c/d", PV_RESOLVE_FLAGS_MKDIR_P }, { "a/b/c/d" } },
+    { { "a/b/c/d", SRT_RESOLVE_FLAGS_MKDIR_P }, { "a/b/c/d" } },
     {
-      { "a/b/c/d", PV_RESOLVE_FLAGS_MKDIR_P, RESOLVE_CALL_FLAGS_IGNORE_PATH },
+      { "a/b/c/d", SRT_RESOLVE_FLAGS_MKDIR_P, RESOLVE_CALL_FLAGS_IGNORE_PATH },
       { "a/b/c/d" },
     },
     { { "create_me" }, { NULL, G_IO_ERROR_NOT_FOUND } },
     {
-      { "create_me", PV_RESOLVE_FLAGS_NONE, RESOLVE_CALL_FLAGS_IGNORE_PATH },
+      { "create_me", SRT_RESOLVE_FLAGS_NONE, RESOLVE_CALL_FLAGS_IGNORE_PATH },
       { NULL, G_IO_ERROR_NOT_FOUND }
     },
-    { { "a/b/c/d", PV_RESOLVE_FLAGS_MKDIR_P }, { "a/b/c/d" } },
+    { { "a/b/c/d", SRT_RESOLVE_FLAGS_MKDIR_P }, { "a/b/c/d" } },
+    { { "a/b/c/d", SRT_RESOLVE_FLAGS_READABLE }, { "a/b/c/d" } },
+    { { "a/b/c/d", SRT_RESOLVE_FLAGS_DIRECTORY }, { "a/b/c/d" } },
+    {
+      { "a/b/c/d", SRT_RESOLVE_FLAGS_READABLE|SRT_RESOLVE_FLAGS_DIRECTORY },
+      { "a/b/c/d" }
+    },
+    { { "a/b/c/file", SRT_RESOLVE_FLAGS_READABLE }, { "a/b/c/file" } },
+    {
+      { "a/b/c/file", SRT_RESOLVE_FLAGS_DIRECTORY },
+      { NULL, G_IO_ERROR_NOT_DIRECTORY }
+    },
+    {
+      { "a/b/c/file", SRT_RESOLVE_FLAGS_READABLE|SRT_RESOLVE_FLAGS_DIRECTORY },
+      { NULL, G_IO_ERROR_NOT_DIRECTORY }
+    },
     { { "a/b///////.////./././///././c/d" }, { "a/b/c/d" } },
     { { "/a/b///////.////././../b2////././c2/d2" }, { "a/b2/c2/d2" } },
     { { "a/b/c/d/e/f" }, { NULL, G_IO_ERROR_NOT_FOUND } },
-    { { "a/b/c/d/e/f", PV_RESOLVE_FLAGS_MKDIR_P }, { "a/b/c/d/e/f" } },
+    { { "a/b/c/d/e/f", SRT_RESOLVE_FLAGS_MKDIR_P }, { "a/b/c/d/e/f" } },
     { { "a/b/c/d/e/f" }, { "a/b/c/d/e/f" } },
-    { { "a/b/c/d/e/f", PV_RESOLVE_FLAGS_MKDIR_P }, { "a/b/c/d/e/f" } },
+    { { "a/b/c/d/e/f", SRT_RESOLVE_FLAGS_MKDIR_P }, { "a/b/c/d/e/f" } },
     { { "a3/b3/c3" }, { NULL, G_IO_ERROR_NOT_FOUND } },
-    { { "a3/b3/c3", PV_RESOLVE_FLAGS_MKDIR_P }, { "a3/b3/c3" } },
+    { { "a3/b3/c3", SRT_RESOLVE_FLAGS_MKDIR_P }, { "a3/b3/c3" } },
     { { "a/b/symlink_to_c" }, { "a/b/c" } },
     { { "a/b/symlink_to_c/d" }, { "a/b/c/d" } },
     {
-      { "a/b/symlink_to_c/d", PV_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK },
+      { "a/b/symlink_to_c/d", SRT_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK },
       { "a/b/c/d" }
     },
     {
-      { "a/b/symlink_to_c/d", PV_RESOLVE_FLAGS_REJECT_SYMLINKS },
+      { "a/b/symlink_to_c/d", SRT_RESOLVE_FLAGS_REJECT_SYMLINKS },
       { NULL, G_IO_ERROR_TOO_MANY_LINKS }
     },
     { { "a/b/symlink_to_b2" }, { "a/b2" } },
     { { "a/b/symlink_to_c2" }, { "a/b2/c2" } },
     { { "a/b/abs_symlink_to_run" }, { NULL, G_IO_ERROR_NOT_FOUND } },
     {
-      { "a/b/abs_symlink_to_run", PV_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK },
+      { "a/b/abs_symlink_to_run", SRT_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK },
       { "a/b/abs_symlink_to_run" }
     },
     { { "run" }, { NULL, G_IO_ERROR_NOT_FOUND } },    /* Wasn't created yet */
-    { { "a/b/abs_symlink_to_run", PV_RESOLVE_FLAGS_MKDIR_P }, { "run" } },
+    { { "a/b/abs_symlink_to_run", SRT_RESOLVE_FLAGS_MKDIR_P }, { "run" } },
     { { "a/b/abs_symlink_to_run/host" }, { NULL, G_IO_ERROR_NOT_FOUND } },
-    { { "a/b/abs_symlink_to_run/host", PV_RESOLVE_FLAGS_MKDIR_P }, { "run/host" } },
+    { { "a/b/abs_symlink_to_run/host", SRT_RESOLVE_FLAGS_MKDIR_P }, { "run/host" } },
     { { "a/b/long_symlink_to_dev" }, { NULL, G_IO_ERROR_NOT_FOUND } },
     { { "a/b/long_symlink_to_dev/shm" }, { NULL, G_IO_ERROR_NOT_FOUND } },
-    { { "a/b/long_symlink_to_dev/shm", PV_RESOLVE_FLAGS_MKDIR_P }, { "dev/shm" } },
-    { { "a/b/../b2/c2/../c3", PV_RESOLVE_FLAGS_MKDIR_P }, { "a/b2/c3" } },
+    { { "a/b/long_symlink_to_dev/shm", SRT_RESOLVE_FLAGS_MKDIR_P }, { "dev/shm" } },
+    { { "a/b/../b2/c2/../c3", SRT_RESOLVE_FLAGS_MKDIR_P }, { "a/b2/c3" } },
     { { "x" }, { NULL, G_IO_ERROR_NOT_FOUND } },
-    { { "x", PV_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK }, { "x" } },
+    { { "x", SRT_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK }, { "x" } },
     /* This is a bit odd: unlike mkdir -p, we create targets for dangling
      * symlinks. It's easier to do this than not, and for pressure-vessel's
      * use-case it probably even makes more sense than not. */
     { { "x/y" }, { NULL, G_IO_ERROR_NOT_FOUND } },
-    { { "x/y", PV_RESOLVE_FLAGS_MKDIR_P }, { "create_me/y" } },
+    { { "x/y", SRT_RESOLVE_FLAGS_MKDIR_P }, { "create_me/y" } },
   };
   g_autoptr(GError) error = NULL;
   g_auto(GLnxTmpDir) tmpdir = { FALSE };
@@ -193,6 +212,16 @@ test_resolve_in_sysroot (Fixture *f,
       g_assert_no_error (error);
     }
 
+  for (i = 0; i < G_N_ELEMENTS (prepare_files); i++)
+    {
+      const char *it = prepare_files[i];
+
+      glnx_file_replace_contents_at (tmpdir.fd, it,
+                                     (guint8 *) "hello", 5,
+                                     0, NULL, &error);
+      g_assert_no_error (error);
+    }
+
   for (i = 0; i < G_N_ELEMENTS (prepare_symlinks); i++)
     {
       const Symlink *it = &prepare_symlinks[i];
@@ -212,15 +241,21 @@ test_resolve_in_sysroot (Fixture *f,
 
       old_fds = tests_check_fd_leaks_enter ();
 
-      if (it->call.flags & PV_RESOLVE_FLAGS_MKDIR_P)
+      if (it->call.flags & SRT_RESOLVE_FLAGS_MKDIR_P)
         g_string_append (description, " (creating directories)");
 
-      if (it->call.flags & PV_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK)
+      if (it->call.flags & SRT_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK)
         g_string_append (description, " (not following final symlink)");
 
-      if (it->call.flags & PV_RESOLVE_FLAGS_REJECT_SYMLINKS)
+      if (it->call.flags & SRT_RESOLVE_FLAGS_REJECT_SYMLINKS)
         g_string_append (description, " (not following any symlink)");
 
+      if (it->call.flags & SRT_RESOLVE_FLAGS_DIRECTORY)
+        g_string_append (description, " (must be a directory)");
+
+      if (it->call.flags & SRT_RESOLVE_FLAGS_READABLE)
+        g_string_append (description, " (open for reading)");
+
       g_test_message ("%" G_GSIZE_FORMAT ": Resolving %s%s",
                       i, it->call.path, description->str);
 
@@ -229,8 +264,8 @@ test_resolve_in_sysroot (Fixture *f,
       else
         out_path = &path;
 
-      fd = pv_resolve_in_sysroot (tmpdir.fd, it->call.path,
-                                  it->call.flags, out_path, &error);
+      fd = _srt_resolve_in_sysroot (tmpdir.fd, it->call.path,
+                                    it->call.flags, out_path, &error);
 
       if (it->expect.path != NULL)
         {
diff --git a/tests/pressure-vessel/utils.c b/tests/pressure-vessel/utils.c
index 5b396fa89a1f6f3c33c4201ff29cbf8181d37692..f400bc7de22bb6ef1466885ead504a42ead9352e 100644
--- a/tests/pressure-vessel/utils.c
+++ b/tests/pressure-vessel/utils.c
@@ -30,6 +30,7 @@
 #include <glib/gstdio.h>
 
 #include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/utils-internal.h"
 #include "libglnx/libglnx.h"
 
 #include "tests/test-utils.h"
@@ -374,7 +375,8 @@ test_file_in_sysroot (Fixture *f,
     {
       const InSysrootTest *it = &tests[i];
 
-      g_assert_cmpint (pv_file_test_in_sysroot (tmpdir.path, it->path, it->test),
+      g_assert_cmpint (_srt_file_test_in_sysroot (tmpdir.path, -1,
+                                                  it->path, it->test),
                        ==, it->expected_result);
     }
 }
diff --git a/tests/system-info.c b/tests/system-info.c
index 9ba94ba51ef767338f9f78e8969c150e60007e4e..a5162237d2fc4bf7fc5a8263f38efe9ee5cef415 100644
--- a/tests/system-info.c
+++ b/tests/system-info.c
@@ -2227,14 +2227,14 @@ static const ContainerTest container_tests[] =
     "debian10", SRT_CONTAINER_TYPE_UNKNOWN, NULL },
   { "Has 'docker' in /run/systemd/container",
     "fedora", SRT_CONTAINER_TYPE_DOCKER, NULL },
-  { "Has /.flatpak-info",
+  { "Has /.flatpak-info and /run/host",
     "flatpak-example", SRT_CONTAINER_TYPE_FLATPAK, "/run/host" },
   { "Has /run/host",
     "invalid-os-release", SRT_CONTAINER_TYPE_UNKNOWN, "/run/host" },
   { "Has no evidence of being a container",
     "no-os-release", SRT_CONTAINER_TYPE_NONE, NULL },
   { "Has /run/pressure-vessel",
-    "steamrt", SRT_CONTAINER_TYPE_PRESSURE_VESSEL, "/run/host" },
+    "steamrt", SRT_CONTAINER_TYPE_PRESSURE_VESSEL, NULL },
   { "Has a Docker-looking /proc/1/cgroup",
     "steamrt-unofficial", SRT_CONTAINER_TYPE_DOCKER, NULL },
 };