@@ -1,4 +1,6 @@
1−{ lib, callPackage, runCommandLocal, writeShellScriptBin, coreutils, bubblewrap }:
1+{ lib, callPackage, runCommandLocal, writeShellScriptBin, glibc, pkgsi686Linux, coreutils, bubblewrap }:
3+let buildFHSEnv = callPackage ./env.nix { }; in
@@ -60,21 +62,45 @@ let
60 in concatStringsSep "\n "
62 in concatStringsSep "\n "
61 (map (file: "--ro-bind-try /etc/${file} /etc/${file}") files);
63 (map (file: "--ro-bind-try /etc/${file} /etc/${file}") files);
65+ # Create this on the fly instead of linking from /nix
66+ # The container might have to modify it and re-run ldconfig if there are
67+ # issues running some binary with LD_LIBRARY_PATH
68+ createLdConfCache = ''
69+ cat > /etc/ld.so.conf <<EOF
71+ /lib/x86_64-linux-gnu
74+ /usr/lib/x86_64-linux-gnu
78+ /usr/lib/i386-linux-gnu
81+ ldconfig &> /dev/null
63 init = run: writeShellScriptBin "${name}-init" ''
83 init = run: writeShellScriptBin "${name}-init" ''
64 source /etc/profile
84 source /etc/profile
65 exec ${run} "$@"
86 exec ${run} "$@"
68 bwrapCmd = { initArgs ? "" }: ''
89 bwrapCmd = { initArgs ? "" }: ''
69 blacklist=(/nix /dev /proc /etc)
90 blacklist=(/nix /dev /proc /etc)
70 ro_mounts=()
91 ro_mounts=()
71 for i in ${env}/*; do
93 for i in ${env}/*; do
72 path="/''${i##*/}"
94 path="/''${i##*/}"
73 if [[ $path == '/etc' ]]; then
95 if [[ $path == '/etc' ]]; then
97+ elif [[ -L $i ]]; then
98+ symlinks+=(--symlink "$(readlink "$i")" "$path")
101+ ro_mounts+=(--ro-bind "$i" "$path")
102+ blacklist+=("$path")
76− ro_mounts+=(--ro-bind "$i" "$path")
80 if [[ -d ${env}/etc ]]; then
106 if [[ -d ${env}/etc ]]; then
@@ -112,8 +138,26 @@ let
112 ${lib.optionalString unshareCgroup "--unshare-cgroup"}
138 ${lib.optionalString unshareCgroup "--unshare-cgroup"}
113 --die-with-parent
139 --die-with-parent
114 --ro-bind /nix /nix
140 --ro-bind /nix /nix
141+ # Our glibc will look for the cache in its own path in `/nix/store`.
142+ # As such, we need a cache to exist there, because pressure-vessel
143+ # depends on the existence of an ld cache. However, adding one
144+ # globally proved to be a bad idea (see #100655), the solution we
145+ # settled on being mounting one via bwrap.
146+ # Also, the cache needs to go to both 32 and 64 bit glibcs, for games
147+ # of both architectures to work.
148+ --tmpfs ${glibc}/etc \
149+ --symlink /etc/ld.so.conf ${glibc}/etc/ld.so.conf \
150+ --symlink /etc/ld.so.cache ${glibc}/etc/ld.so.cache \
151+ --ro-bind ${glibc}/etc/rpc ${glibc}/etc/rpc \
152+ --remount-ro ${glibc}/etc \
153+ --tmpfs ${pkgsi686Linux.glibc}/etc \
154+ --symlink /etc/ld.so.conf ${pkgsi686Linux.glibc}/etc/ld.so.conf \
155+ --symlink /etc/ld.so.cache ${pkgsi686Linux.glibc}/etc/ld.so.cache \
156+ --ro-bind ${pkgsi686Linux.glibc}/etc/rpc ${pkgsi686Linux.glibc}/etc/rpc \
157+ --remount-ro ${pkgsi686Linux.glibc}/etc \
115 ${etcBindFlags}
158 ${etcBindFlags}
116 "''${ro_mounts[@]}"
159 "''${ro_mounts[@]}"
117 "''${auto_mounts[@]}"
161 "''${auto_mounts[@]}"
118 ${init runScript}/bin/${name}-init ${initArgs}
162 ${init runScript}/bin/${name}-init ${initArgs}