diff --git a/src/opt/apps/cn.flamescion.bookworm-compatibility-mode/files/bin/bookworm-init b/src/opt/apps/cn.flamescion.bookworm-compatibility-mode/files/bin/bookworm-init index 70c63ec..d02265f 100755 --- a/src/opt/apps/cn.flamescion.bookworm-compatibility-mode/files/bin/bookworm-init +++ b/src/opt/apps/cn.flamescion.bookworm-compatibility-mode/files/bin/bookworm-init @@ -190,6 +190,126 @@ ln -sfv /flamescion-container-tools/bin-override/host-spawn-$(uname -m) /flamesc apt install --reinstall /flamescion-container-tools/ace-host-integration.deb + + +### Do NVIDIA Integration + +echo "ACE: NVIDIA Integration" + + ensureTargetDir() { + targetFile=$1 + t=$(dirname "$targetFile") + mkdir -p "$t" + } + + + lib32_dir="/usr/lib/" + lib64_dir="/usr/lib/" + if [ -e "/usr/lib/x86_64-linux-gnu" ]; then + lib64_dir="/usr/lib/x86_64-linux-gnu/" + elif [ -e "/usr/lib64" ]; then + lib64_dir="/usr/lib64/" + fi + if [ -e "/usr/lib/i386-linux-gnu" ]; then + lib32_dir="/usr/lib/i386-linux-gnu/" + elif [ -e "/usr/lib32" ]; then + lib32_dir="/usr/lib32/" + fi + + # First we find all non-lib files we need, this includes + # - binaries + # - confs + # - egl files + # - icd files + # Excluding here the libs, we will threat them later specifically + NVIDIA_FILES="$(find /host/etc/ /host/usr/ \ + -path "/host/usr/lib/i386-linux-gnu/*" -prune -o \ + -path "/host/usr/lib/x86_64-linux-gnu/*" -prune -o \ + -path "/host/usr/lib32/*" -prune -o \ + -path "/host/usr/lib64/*" -prune -o \ + -iname "*nvidia*" -not -type d -print 2> /dev/null || :)" + for nvidia_file in ${NVIDIA_FILES}; do + dest_file="$(printf "%s" "${nvidia_file}" | sed 's|/host||g')" + ensureTargetDir ${dest_file} + cp -r "${nvidia_file}" "${dest_file}" + done + + # Then we find all directories with nvidia in the name and just mount them + NVIDIA_DIRS="$(find /host/etc /host/usr -iname "*nvidia*" -type d 2> /dev/null || :)" + for nvidia_dir in ${NVIDIA_DIRS}; do + # /usr/lib64 is common in Arch or RPM based distros, while /usr/lib/x86_64-linux-gnu is + # common on Debian derivatives, so we need to adapt between the two nomenclatures. + if printf "%s" "${nvidia_dir}" | grep -Eq "lib32|lib64|x86_64-linux-gnu|i386-linux-gnu"; then + + # Remove origin so we plug our own + dest_dir="$(printf "%s" "${nvidia_dir}" | + sed "s|/host/usr/lib/x86_64-linux-gnu/|${lib64_dir}|g" | + sed "s|/host/usr/lib/i386-linux-gnu/|${lib32_dir}|g" | + sed "s|/host/usr/lib64/|${lib64_dir}|g" | + sed "s|/host/usr/lib32/|${lib32_dir}|g")" + else + dest_dir="$(printf "%s" "${nvidia_dir}" | sed 's|/host||g')" + fi + ensureTargetDir ${dest_file} + cp -r "${nvidia_dir}" "${dest_file}" + done + + # Then we find all the ".so" libraries, there are searched separately + # because we need to extract the relative path to mount them in the + # correct path based on the guest's setup + # + # /usr/lib64 is common in Arch or RPM based distros, while /usr/lib/x86_64-linux-gnu is + # common on Debian derivatives, so we need to adapt between the two nomenclatures. + NVIDIA_LIBS="$(find \ + /host/usr/lib/i386-linux-gnu/ \ + /host/usr/lib/x86_64-linux-gnu/ \ + /host/usr/lib32/ \ + /host/usr/lib64/ \ + -iname "*nvidia*.so*" \ + -o -iname "libcuda*.so*" \ + -o -iname "libnvcuvid*.so*" \ + -o -iname "libnvoptix*.so*" 2> /dev/null || :)" + for nvidia_lib in ${NVIDIA_LIBS}; do + dest_file="$(printf "%s" "${nvidia_lib}" | + sed "s|/host/usr/lib/x86_64-linux-gnu/|${lib64_dir}|g" | + sed "s|/host/usr/lib/i386-linux-gnu/|${lib32_dir}|g" | + sed "s|/host/usr/lib64/|${lib64_dir}|g" | + sed "s|/host/usr/lib32/|${lib32_dir}|g")" + + # If file exists, just continue + # this may happen for directories like /usr/lib/nvidia/xorg/foo.so + # where the directory is already bind mounted (ro) and we don't need + # to mount further files in it. + if [ -e "${dest_file}" ]; then + continue + fi + + type="file" + if [ -L "${nvidia_lib}" ]; then + type="link" + fi + + if [ "${type}" = "link" ]; then + mkdir -p "$(dirname "${dest_file}")" + cp -d "${nvidia_lib}" "${dest_file}" + continue + fi + ensureTargetDir ${dest_file} + cp -r "${nvidia_lib}" "${dest_file}" + + done + + # Refresh ldconfig cache, also detect if there are empty files remaining + # and clean them. + # This could happen when upgrading drivers and changing versions. + empty_libs="$(ldconfig 2>&1 | grep -Eo "File.*is empty" | cut -d' ' -f2)" + if [ -n "${empty_libs}" ]; then + # shellcheck disable=SC2086 + find ${empty_libs} -delete 2> /dev/null || : + find /usr/ /etc/ -empty -iname "*nvidia*" -delete 2> /dev/null || : + fi + + EOFFFFFF #####init