From e2f7ad79cc7cd75d36ced950db5fb84e00af96b1 Mon Sep 17 00:00:00 2001 From: guihkx Date: Tue, 28 Sep 2021 16:46:43 -0300 Subject: [PATCH] linux: support patching the Flatpak NVIDIA driver This adds support for patching the Flatpak version of NVIDIA driver by passing the `-f` flag to either patch.sh or patch-fbc.sh. Just like when patching the host driver, patching the Flatpak driver also creates a backup file automatically (with the .flatpak suffix) --- patch-fbc.sh | 49 ++++++++++++++++++++++++++++++++++++++----------- patch.sh | 48 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/patch-fbc.sh b/patch-fbc.sh index baf070f..1e376f9 100755 --- a/patch-fbc.sh +++ b/patch-fbc.sh @@ -7,10 +7,12 @@ set -euo pipefail ; # <- this semicolon and comment make options apply backup_path="/opt/nvidia/libnvidia-fbc-backup" silent_flag='' manual_driver_version='' +flatpak_flag='' +backup_suffix='' print_usage() { printf ' SYNOPSIS - patch-fbc.sh [-s] [-r|-h|-c VERSION|-l] + patch-fbc.sh [-s] [-r|-h|-c VERSION|-l|-f] DESCRIPTION The patch for Nvidia drivers to allow FBC on consumer devices @@ -23,14 +25,14 @@ DESCRIPTION -l List supported driver versions -d VERSION Use VERSION driver version when looking for libraries instead of using nvidia-smi to detect it. - + -f Enable support for Flatpak NVIDIA drivers. ' } # shellcheck disable=SC2209 opmode="patch" -while getopts 'rshc:ld:' flag; do +while getopts 'rshc:ld:f' flag; do case "${flag}" in r) opmode="${opmode}rollback" ;; s) silent_flag='true' ;; @@ -38,6 +40,7 @@ while getopts 'rshc:ld:' flag; do c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;; l) opmode="${opmode}listversions" ;; d) manual_driver_version="$OPTARG" ;; + f) flatpak_flag='true' ;; *) echo "Incorrect option specified in command line" ; exit 2 ;; esac done @@ -46,6 +49,11 @@ if [[ $silent_flag ]]; then exec 1> /dev/null fi +if [[ $flatpak_flag ]]; then + backup_suffix='.flatpak' + echo "WARNING: Flatpak flag enabled (-f), modifying ONLY the Flatpak driver." +fi + declare -A patch_list=( ["435.27.08"]='s/\x85\xc0\x89\xc3\x0f\x85\x68\xfa\xff\xff/\x31\xc0\x89\xc3\x0f\x85\x68\xfa\xff\xff/' ["440.26"]='s/\x85\xc0\x89\xc3\x0f\x85\xa9\xfa\xff\xff/\x31\xc0\x89\xc3\x0f\x85\xa9\xfa\xff\xff/' @@ -203,6 +211,14 @@ check_version_supported () { [[ "${patch_list[$ver]+isset}" && "${object_list[$ver]+isset}" ]] } +get_flatpak_driver_path () { + # Flatpak's package versioning replaces '.' by '-' + version="$(echo "$1" | tr '.' '-')" + if path=$(flatpak info --show-location "org.freedesktop.Platform.GL.nvidia-${version}" 2>/dev/null); then + echo "$path/files/lib" + fi +} + get_supported_versions () { for drv in "${!patch_list[@]}"; do [[ "${object_list[$drv]+isset}" ]] && echo "$drv" @@ -246,6 +262,17 @@ patch_common () { patch="${patch_list[$driver_version]}" object="${object_list[$driver_version]}" + if [[ $flatpak_flag ]]; then + driver_dir=$(get_flatpak_driver_path "$driver_version") + if [ -z "$driver_dir" ]; then + echo "ERROR: Flatpak package for driver $driver_version does not appear to be installed." + echo "Try rebooting your computer and/or running 'flatpak update'." + exit 1 + fi + # return early because the code below is out of scope for the Flatpak driver + return 0 + fi + declare -a driver_locations=( '/usr/lib/x86_64-linux-gnu' '/usr/lib/x86_64-linux-gnu/nvidia/current/' @@ -267,10 +294,10 @@ patch_common () { rollback () { patch_common - if [[ -f "$backup_path/$object.$driver_version" ]]; then - cp -p "$backup_path/$object.$driver_version" \ + if [[ -f "$backup_path/$object.$driver_version$backup_suffix" ]]; then + cp -p "$backup_path/$object.$driver_version$backup_suffix" \ "$driver_dir/$object.$driver_version" - echo "Restore from backup $object.$driver_version" + echo "Restore from backup $object.$driver_version$backup_suffix" else echo "Backup not found. Try to patch first." exit 1 @@ -279,8 +306,8 @@ rollback () { patch () { patch_common - if [[ -f "$backup_path/$object.$driver_version" ]]; then - bkp_hash="$(sha1sum "$backup_path/$object.$driver_version" | cut -f1 -d\ )" + if [[ -f "$backup_path/$object.$driver_version$backup_suffix" ]]; then + bkp_hash="$(sha1sum "$backup_path/$object.$driver_version$backup_suffix" | cut -f1 -d\ )" drv_hash="$(sha1sum "$driver_dir/$object.$driver_version" | cut -f1 -d\ )" if [[ "$bkp_hash" != "$drv_hash" ]] ; then echo "Backup exists and driver file differ from backup. Skipping patch." @@ -290,10 +317,10 @@ patch () { echo "Attention! Backup not found. Copying current $object to backup." mkdir -p "$backup_path" cp -p "$driver_dir/$object.$driver_version" \ - "$backup_path/$object.$driver_version" + "$backup_path/$object.$driver_version$backup_suffix" fi - sha1sum "$backup_path/$object.$driver_version" - sed "$patch" "$backup_path/$object.$driver_version" > \ + sha1sum "$backup_path/$object.$driver_version$backup_suffix" + sed "$patch" "$backup_path/$object.$driver_version$backup_suffix" > \ "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" sha1sum "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" ldconfig diff --git a/patch.sh b/patch.sh index f4e258c..3e8bada 100755 --- a/patch.sh +++ b/patch.sh @@ -7,10 +7,12 @@ set -euo pipefail ; # <- this semicolon and comment make options apply backup_path="/opt/nvidia/libnvidia-encode-backup" silent_flag='' manual_driver_version='' +flatpak_flag='' +backup_suffix='' print_usage() { printf ' SYNOPSIS - patch.sh [-s] [-r|-h|-c VERSION|-l] + patch.sh [-s] [-r|-h|-c VERSION|-l|-f] DESCRIPTION The patch for Nvidia drivers to remove NVENC session limit @@ -23,13 +25,14 @@ DESCRIPTION -l List supported driver versions -d VERSION Use VERSION driver version when looking for libraries instead of using nvidia-smi to detect it. + -f Enable support for Flatpak NVIDIA drivers. ' } # shellcheck disable=SC2209 opmode="patch" -while getopts 'rshc:ld:' flag; do +while getopts 'rshc:ld:f' flag; do case "${flag}" in r) opmode="${opmode}rollback" ;; s) silent_flag='true' ;; @@ -37,6 +40,7 @@ while getopts 'rshc:ld:' flag; do c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;; l) opmode="${opmode}listversions" ;; d) manual_driver_version="$OPTARG" ;; + f) flatpak_flag='true' ;; *) echo "Incorrect option specified in command line" ; exit 2 ;; esac done @@ -45,6 +49,11 @@ if [[ $silent_flag ]]; then exec 1> /dev/null fi +if [[ $flatpak_flag ]]; then + backup_suffix='.flatpak' + echo "WARNING: Flatpak flag enabled (-f), modifying ONLY the Flatpak driver." +fi + declare -A patch_list=( ["375.39"]='s/\x85\xC0\x89\xC5\x75\x18/\x29\xC0\x89\xC5\x90\x90/g' ["390.77"]='s/\x85\xC0\x89\xC5\x75\x18/\x29\xC0\x89\xC5\x90\x90/g' @@ -276,6 +285,14 @@ check_version_supported () { [[ "${patch_list[$ver]+isset}" && "${object_list[$ver]+isset}" ]] } +get_flatpak_driver_path () { + # Flatpak's package versioning replaces '.' by '-' + version="$(echo "$1" | tr '.' '-')" + if path=$(flatpak info --show-location "org.freedesktop.Platform.GL.nvidia-${version}" 2>/dev/null); then + echo "$path/files/lib" + fi +} + get_supported_versions () { for drv in "${!patch_list[@]}"; do [[ "${object_list[$drv]+isset}" ]] && echo "$drv" @@ -319,6 +336,17 @@ patch_common () { patch="${patch_list[$driver_version]}" object="${object_list[$driver_version]}" + if [[ $flatpak_flag ]]; then + driver_dir=$(get_flatpak_driver_path "$driver_version") + if [ -z "$driver_dir" ]; then + echo "ERROR: Flatpak package for driver $driver_version does not appear to be installed." + echo "Try rebooting your computer and/or running 'flatpak update'." + exit 1 + fi + # return early because the code below is out of scope for the Flatpak driver + return 0 + fi + declare -a driver_locations=( '/usr/lib/x86_64-linux-gnu' '/usr/lib/x86_64-linux-gnu/nvidia/current/' @@ -340,10 +368,10 @@ patch_common () { rollback () { patch_common - if [[ -f "$backup_path/$object.$driver_version" ]]; then - cp -p "$backup_path/$object.$driver_version" \ + if [[ -f "$backup_path/$object.$driver_version$backup_suffix" ]]; then + cp -p "$backup_path/$object.$driver_version$backup_suffix" \ "$driver_dir/$object.$driver_version" - echo "Restore from backup $object.$driver_version" + echo "Restore from backup $object.$driver_version$backup_suffix" else echo "Backup not found. Try to patch first." exit 1 @@ -352,8 +380,8 @@ rollback () { patch () { patch_common - if [[ -f "$backup_path/$object.$driver_version" ]]; then - bkp_hash="$(sha1sum "$backup_path/$object.$driver_version" | cut -f1 -d\ )" + if [[ -f "$backup_path/$object.$driver_version$backup_suffix" ]]; then + bkp_hash="$(sha1sum "$backup_path/$object.$driver_version$backup_suffix" | cut -f1 -d\ )" drv_hash="$(sha1sum "$driver_dir/$object.$driver_version" | cut -f1 -d\ )" if [[ "$bkp_hash" != "$drv_hash" ]] ; then echo "Backup exists and driver file differ from backup. Skipping patch." @@ -363,10 +391,10 @@ patch () { echo "Attention! Backup not found. Copying current $object to backup." mkdir -p "$backup_path" cp -p "$driver_dir/$object.$driver_version" \ - "$backup_path/$object.$driver_version" + "$backup_path/$object.$driver_version$backup_suffix" fi - sha1sum "$backup_path/$object.$driver_version" - sed "$patch" "$backup_path/$object.$driver_version" > \ + sha1sum "$backup_path/$object.$driver_version$backup_suffix" + sed "$patch" "$backup_path/$object.$driver_version$backup_suffix" > \ "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" sha1sum "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" ldconfig