From 2383497282bbb1d2ecff921d4dac13bf36b0ec29 Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Wed, 9 Dec 2020 17:30:28 +0000 Subject: [PATCH] pressure-vessel: Make graphics drivers outside $HOME available, if used Since !173, we have been able to create symbolic links to graphics drivers anywhere on the filesystem, but that didn't mean the graphics driver would necessarily be usable, because the directory containing it would not necessarily be visible in the container. Add these directories to the list of directories to be "exported". Manual test (Debian on on Intel hardware, adjust as required for others): * Modify /usr/share/vulkan/icd.d/intel_icd.i686.json to use /opt/moved-from-usr/lib/i386-linux-gnu/libvulkan_intel.so * Move the real i386 libvulkan_intel.so to that location * ./run --verbose -- steam-runtime-system-info 2>&1 | tee container.log Resolves: #29 Resolves: https://github.com/ValveSoftware/steam-runtime/issues/313 Signed-off-by: Simon McVittie <smcv@collabora.com> --- pressure-vessel/exports.c | 82 +++++++++++++++++++++++++++++++++++++ pressure-vessel/exports.h | 28 +++++++++++++ pressure-vessel/meson.build | 2 + pressure-vessel/runtime.c | 14 ++++++- pressure-vessel/runtime.h | 2 + pressure-vessel/wrap.c | 8 +++- 6 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 pressure-vessel/exports.c create mode 100644 pressure-vessel/exports.h diff --git a/pressure-vessel/exports.c b/pressure-vessel/exports.c new file mode 100644 index 000000000..4c1f845a9 --- /dev/null +++ b/pressure-vessel/exports.c @@ -0,0 +1,82 @@ +/* + * Copyright © 2017-2020 Collabora Ltd. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "exports.h" + +#include <ftw.h> + +/* nftw() doesn't have a user_data argument so we need to use a global + * variable :-( */ +static struct +{ + FlatpakExports *exports; +} export_targets_data; + +static int +export_targets_helper (const char *fpath, + const struct stat *sb, + int typeflag, + struct FTW *ftwbuf) +{ + g_autofree gchar *target = NULL; + + switch (typeflag) + { + case FTW_SL: + target = glnx_readlinkat_malloc (-1, fpath, NULL, NULL); + + if (target[0] != '/') + break; + + if (g_str_has_prefix (target, "/run/host/")) + break; + + g_debug ("Exporting %s because %s points to it", + target, fpath); + flatpak_exports_add_path_expose (export_targets_data.exports, + FLATPAK_FILESYSTEM_MODE_READ_ONLY, + target); + break; + + default: + break; + } + + return 0; +} + +/** + * pv_export_symlink_targets: + * @exports: The #FlatpakExports + * @source: A copy of the overrides directory, for example + * `/tmp/tmp12345678/overrides/lib`. + * + * For every symbolic link in @source, if the target is absolute, mark + * it to be exported in @exports. + */ +void +pv_export_symlink_targets (FlatpakExports *exports, + const char *source) +{ + g_return_if_fail (export_targets_data.exports == NULL); + + export_targets_data.exports = exports; + nftw (source, export_targets_helper, 100, FTW_PHYS); + export_targets_data.exports = NULL; +} diff --git a/pressure-vessel/exports.h b/pressure-vessel/exports.h new file mode 100644 index 000000000..97d92691c --- /dev/null +++ b/pressure-vessel/exports.h @@ -0,0 +1,28 @@ +/* + * Copyright © 2017-2020 Collabora Ltd. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "libglnx/libglnx.h" + +#include "flatpak-exports-private.h" +#include "steam-runtime-tools/glib-backports-internal.h" + +void pv_export_symlink_targets (FlatpakExports *exports, + const char *source); diff --git a/pressure-vessel/meson.build b/pressure-vessel/meson.build index df7460776..ed93e41b7 100644 --- a/pressure-vessel/meson.build +++ b/pressure-vessel/meson.build @@ -191,6 +191,8 @@ executable( sources : [ 'bwrap.c', 'bwrap.h', + 'exports.c', + 'exports.h', 'flatpak-common-types-private.h', 'flatpak-context.c', 'flatpak-context-private.h', diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c index 8af25be2b..d39e2e63e 100644 --- a/pressure-vessel/runtime.c +++ b/pressure-vessel/runtime.c @@ -36,6 +36,7 @@ #include "bwrap-lock.h" #include "elf-utils.h" #include "enumtypes.h" +#include "exports.h" #include "flatpak-run-private.h" #include "tree-copy.h" #include "utils.h" @@ -1626,6 +1627,7 @@ bind_icd (PvRuntime *self, static gboolean bind_runtime (PvRuntime *self, + FlatpakExports *exports, FlatpakBwrap *bwrap, GHashTable *extra_locked_vars_to_unset, GHashTable *extra_locked_vars_to_inherit, @@ -1817,6 +1819,8 @@ bind_runtime (PvRuntime *self, return FALSE; } + pv_export_symlink_targets (exports, self->overrides); + if (self->mutable_sysroot == NULL) { /* self->overrides is in a temporary directory that will be @@ -3615,6 +3619,7 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self, gboolean pv_runtime_bind (PvRuntime *self, + FlatpakExports *exports, FlatpakBwrap *bwrap, GHashTable *extra_locked_vars_to_unset, GHashTable *extra_locked_vars_to_inherit, @@ -3623,13 +3628,18 @@ pv_runtime_bind (PvRuntime *self, g_autofree gchar *pressure_vessel_prefix = NULL; g_return_val_if_fail (PV_IS_RUNTIME (self), FALSE); + g_return_val_if_fail (exports != NULL, FALSE); g_return_val_if_fail (!pv_bwrap_was_finished (bwrap), FALSE); g_return_val_if_fail (extra_locked_vars_to_unset != NULL, FALSE); g_return_val_if_fail (extra_locked_vars_to_inherit != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (!bind_runtime (self, bwrap, extra_locked_vars_to_unset, - extra_locked_vars_to_inherit, error)) + if (!bind_runtime (self, + exports, + bwrap, + extra_locked_vars_to_unset, + extra_locked_vars_to_inherit, + error)) return FALSE; pressure_vessel_prefix = g_path_get_dirname (self->tools_dir); diff --git a/pressure-vessel/runtime.h b/pressure-vessel/runtime.h index 0b3d2944a..1d8ede2ad 100644 --- a/pressure-vessel/runtime.h +++ b/pressure-vessel/runtime.h @@ -27,6 +27,7 @@ #include "libglnx/libglnx.h" #include "flatpak-bwrap-private.h" +#include "flatpak-exports-private.h" #include "flatpak-utils-base-private.h" /** @@ -82,6 +83,7 @@ PvRuntime *pv_runtime_new (const char *source_files, gchar *pv_runtime_get_adverb (PvRuntime *self, FlatpakBwrap *adverb_args); gboolean pv_runtime_bind (PvRuntime *self, + FlatpakExports *exports, FlatpakBwrap *bwrap, GHashTable *extra_locked_vars_to_unset, GHashTable *extra_locked_vars_to_inherit, diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c index 5bfa3a7b3..0662960e2 100644 --- a/pressure-vessel/wrap.c +++ b/pressure-vessel/wrap.c @@ -1781,8 +1781,12 @@ main (int argc, if (runtime == NULL) goto out; - if (!pv_runtime_bind (runtime, bwrap, extra_locked_vars_to_unset, - extra_locked_vars_to_inherit, error)) + if (!pv_runtime_bind (runtime, + exports, + bwrap, + extra_locked_vars_to_unset, + extra_locked_vars_to_inherit, + error)) goto out; } else if (is_flatpak_env) -- GitLab