@@ -1,4 +1,6 @@
1−{ lib, callPackage, runCommandLocal, writeShellScriptBin, coreutils, bubblewrap }:
1+{ lib, callPackage, runCommandLocal, writeShellScriptBin, glibc, pkgsi686Linux, coreutils, bubblewrap }:
2+
3+let buildFHSEnv = callPackage ./env.nix { }; in
24
35args @ {
46 name
@@ -60,21 +62,45 @@ let
6062 in concatStringsSep "\n "
6163 (map (file: "--ro-bind-try /etc/${file} /etc/${file}") files);
6264
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
70+ /lib
71+ /lib/x86_64-linux-gnu
72+ /lib64
73+ /usr/lib
74+ /usr/lib/x86_64-linux-gnu
75+ /usr/lib64
76+ /lib/i386-linux-gnu
77+ /lib32
78+ /usr/lib/i386-linux-gnu
79+ /usr/lib32
80+ EOF
81+ ldconfig &> /dev/null
82+ '';
6383 init = run: writeShellScriptBin "${name}-init" ''
6484 source /etc/profile
85+ ${createLdConfCache}
6586 exec ${run} "$@"
6687 '';
6788
6889 bwrapCmd = { initArgs ? "" }: ''
6990 blacklist=(/nix /dev /proc /etc)
7091 ro_mounts=()
92+ symlinks=()
7193 for i in ${env}/*; do
7294 path="/''${i##*/}"
7395 if [[ $path == '/etc' ]]; then
74− continue
96+ :
97+ elif [[ -L $i ]]; then
98+ symlinks+=(--symlink "$(readlink "$i")" "$path")
99+ blacklist+=("$path")
100+ else
101+ ro_mounts+=(--ro-bind "$i" "$path")
102+ blacklist+=("$path")
75103 fi
76− ro_mounts+=(--ro-bind "$i" "$path")
77− blacklist+=("$path")
78104 done
79105
80106 if [[ -d ${env}/etc ]]; then
@@ -112,8 +138,26 @@ let
112138 ${lib.optionalString unshareCgroup "--unshare-cgroup"}
113139 --die-with-parent
114140 --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 \
115158 ${etcBindFlags}
116159 "''${ro_mounts[@]}"
160+ "''${symlinks[@]}"
117161 "''${auto_mounts[@]}"
118162 ${init runScript}/bin/${name}-init ${initArgs}
119163 )