From f25b0fd05608f09a31aab55d05d776cf65dc8829 Mon Sep 17 00:00:00 2001 From: Vladislav Yarmak Date: Fri, 27 Sep 2019 19:28:42 +0300 Subject: [PATCH 1/5] linux: refactor patch.sh in order to add new operation modes --- patch.sh | 108 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 44 deletions(-) diff --git a/patch.sh b/patch.sh index 9201064..bf2f886 100755 --- a/patch.sh +++ b/patch.sh @@ -6,11 +6,10 @@ set -euo pipefail ; # <- this semicolon and comment make options apply backup_path="/opt/nvidia/libnvidia-encode-backup" silent_flag='' -rollback_flag='' print_usage() { printf ' SYNOPSIS - patch.sh [OPTION]... + patch.sh [-s] [-r|-h] DESCRIPTION The patch for Nvidia drivers to increase encoder sessions @@ -22,12 +21,15 @@ DESCRIPTION ' } +# shellcheck disable=SC2209 +opmode="patch" + while getopts 'rsh' flag; do case "${flag}" in - r) rollback_flag='true' ;; + r) opmode="${opmode}rollback" ;; s) silent_flag='true' ;; - *) print_usage - exit 1 ;; + h) opmode="${opmode}help" ;; + *) echo "Incorrect option specified in command line" ; exit 2 ;; esac done @@ -105,54 +107,65 @@ declare -A object_list=( ["435.21"]='libnvcuvid.so' ) -NVIDIA_SMI="$(command -v nvidia-smi)" - -if ! driver_version=$("$NVIDIA_SMI" --query-gpu=driver_version --format=csv,noheader,nounits | head -n 1) ; then - echo 'Something went wrong. Check nvidia driver' - exit 1; -fi - -echo "Detected nvidia driver version: $driver_version" - -if [[ ! "${patch_list[$driver_version]+isset}" || ! "${object_list[$driver_version]+isset}" ]]; then - echo "Patch for this ($driver_version) nvidia driver not found." 1>&2 - echo "Available patches for: " 1>&2 - for drv in "${!patch_list[@]}"; do - echo "$drv" 1>&2 - done - exit 1; -fi - -patch="${patch_list[$driver_version]}" -object="${object_list[$driver_version]}" - -declare -a driver_locations=( - '/usr/lib/x86_64-linux-gnu' - '/usr/lib/x86_64-linux-gnu/nvidia/current/' - '/usr/lib64' - "/usr/lib/nvidia-${driver_version%%.*}" -) - -dir_found='' -for driver_dir in "${driver_locations[@]}" ; do - if [[ -e "$driver_dir/$object.$driver_version" ]]; then - dir_found='true' - break +patch_common () { + NVIDIA_SMI="$(command -v nvidia-smi || true)" + if [[ ! "$NVIDIA_SMI" ]] ; then + echo 'nvidia-smi utility not found. Probably driver is not installed.' + exit 1 fi -done -[[ "$dir_found" ]] || { echo "ERROR: cannot detect driver directory"; exit 1; } + if ! driver_version=$("$NVIDIA_SMI" --query-gpu=driver_version --format=csv,noheader,nounits | head -n 1) ; then + echo 'Something went wrong. Check nvidia driver' + exit 1 + fi -if [[ $rollback_flag ]]; then + echo "Detected nvidia driver version: $driver_version" + + if [[ ! "${patch_list[$driver_version]+isset}" || ! "${object_list[$driver_version]+isset}" ]]; then + echo "Patch for this ($driver_version) nvidia driver not found." 1>&2 + echo "Available patches for: " 1>&2 + for drv in "${!patch_list[@]}"; do + echo "$drv" 1>&2 + done + exit 1 + fi + + patch="${patch_list[$driver_version]}" + object="${object_list[$driver_version]}" + + declare -a driver_locations=( + '/usr/lib/x86_64-linux-gnu' + '/usr/lib/x86_64-linux-gnu/nvidia/current/' + '/usr/lib64' + "/usr/lib/nvidia-${driver_version%%.*}" + ) + + dir_found='' + for driver_dir in "${driver_locations[@]}" ; do + if [[ -e "$driver_dir/$object.$driver_version" ]]; then + dir_found='true' + break + fi + done + + [[ "$dir_found" ]] || { echo "ERROR: cannot detect driver directory"; exit 1; } + +} + +rollback () { + patch_common if [[ -f "$backup_path/$object.$driver_version" ]]; then cp -p "$backup_path/$object.$driver_version" \ "$driver_dir/$object.$driver_version" echo "Restore from backup $object.$driver_version" else echo "Backup not found. Try to patch first." - exit 1; + exit 1 fi -else +} + +patch () { + patch_common if [[ ! -f "$backup_path/$object.$driver_version" ]]; then echo "Attention! Backup not found. Copy current $object to backup." mkdir -p "$backup_path" @@ -165,4 +178,11 @@ else sha1sum "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" ldconfig echo "Patched!" -fi +} + +case "${opmode}" in + patch) patch ;; + patchrollback) rollback ;; + patchhelp) print_usage ; exit 2 ;; + *) echo "Incorrect combination of flags"; exit 2 ;; +esac From 1029bfb2a1253ed0e7df9fdcf532a303dbe8227e Mon Sep 17 00:00:00 2001 From: Vladislav Yarmak Date: Fri, 27 Sep 2019 20:00:31 +0300 Subject: [PATCH 2/5] linux: patch.sh: new opmode - query for specific version support --- patch.sh | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/patch.sh b/patch.sh index bf2f886..5494261 100755 --- a/patch.sh +++ b/patch.sh @@ -9,14 +9,16 @@ silent_flag='' print_usage() { printf ' SYNOPSIS - patch.sh [-s] [-r|-h] + patch.sh [-s] [-r|-h|-c VERSION] DESCRIPTION - The patch for Nvidia drivers to increase encoder sessions + The patch for Nvidia drivers to remove NVENC session limit - -s Silent mode (No output) - -r Rollback to original (Restore lib from backup) - -h Print this help message + -s Silent mode (No output) + -r Rollback to original (Restore lib from backup) + -h Print this help message + -c VERSION Check if version VERSION supported by this patch. + Returns true exit code (0) if version is supported. ' } @@ -24,11 +26,12 @@ DESCRIPTION # shellcheck disable=SC2209 opmode="patch" -while getopts 'rsh' flag; do +while getopts 'rshc:' flag; do case "${flag}" in r) opmode="${opmode}rollback" ;; s) silent_flag='true' ;; h) opmode="${opmode}help" ;; + c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;; *) echo "Incorrect option specified in command line" ; exit 2 ;; esac done @@ -107,6 +110,11 @@ declare -A object_list=( ["435.21"]='libnvcuvid.so' ) +check_version_supported () { + local ver="$1" + [[ "${patch_list[$ver]+isset}" && "${object_list[$ver]+isset}" ]] +} + patch_common () { NVIDIA_SMI="$(command -v nvidia-smi || true)" if [[ ! "$NVIDIA_SMI" ]] ; then @@ -121,7 +129,7 @@ patch_common () { echo "Detected nvidia driver version: $driver_version" - if [[ ! "${patch_list[$driver_version]+isset}" || ! "${object_list[$driver_version]+isset}" ]]; then + if ! check_version_supported "$driver_version" ; then echo "Patch for this ($driver_version) nvidia driver not found." 1>&2 echo "Available patches for: " 1>&2 for drv in "${!patch_list[@]}"; do @@ -180,9 +188,20 @@ patch () { echo "Patched!" } +query_version_support () { + if check_version_supported "$checked_version" ; then + echo "SUPPORTED" + exit 0 + else + echo "NOT SUPPORTED" + exit 1 + fi +} + case "${opmode}" in patch) patch ;; patchrollback) rollback ;; patchhelp) print_usage ; exit 2 ;; + patchcheckversion) query_version_support ;; *) echo "Incorrect combination of flags"; exit 2 ;; esac From a82e6112c9967e58da6a2cf67ebe1f78c8983f07 Mon Sep 17 00:00:00 2001 From: Vladislav Yarmak Date: Fri, 27 Sep 2019 22:27:37 +0300 Subject: [PATCH 3/5] linux: patch.sh: new opmode - list supported versions --- patch.sh | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/patch.sh b/patch.sh index 5494261..f3b4962 100755 --- a/patch.sh +++ b/patch.sh @@ -9,7 +9,7 @@ silent_flag='' print_usage() { printf ' SYNOPSIS - patch.sh [-s] [-r|-h|-c VERSION] + patch.sh [-s] [-r|-h|-c VERSION|-l] DESCRIPTION The patch for Nvidia drivers to remove NVENC session limit @@ -19,6 +19,7 @@ DESCRIPTION -h Print this help message -c VERSION Check if version VERSION supported by this patch. Returns true exit code (0) if version is supported. + -l List supported driver versions ' } @@ -26,12 +27,13 @@ DESCRIPTION # shellcheck disable=SC2209 opmode="patch" -while getopts 'rshc:' flag; do +while getopts 'rshc:l' flag; do case "${flag}" in r) opmode="${opmode}rollback" ;; s) silent_flag='true' ;; h) opmode="${opmode}help" ;; c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;; + l) opmode="${opmode}listversions" ;; *) echo "Incorrect option specified in command line" ; exit 2 ;; esac done @@ -115,6 +117,13 @@ check_version_supported () { [[ "${patch_list[$ver]+isset}" && "${object_list[$ver]+isset}" ]] } +get_supported_versions () { + for drv in "${!patch_list[@]}"; do + [[ "${object_list[$drv]+isset}" ]] && echo "$drv" + done | sort -t. -n + return 0 +} + patch_common () { NVIDIA_SMI="$(command -v nvidia-smi || true)" if [[ ! "$NVIDIA_SMI" ]] ; then @@ -130,11 +139,9 @@ patch_common () { echo "Detected nvidia driver version: $driver_version" if ! check_version_supported "$driver_version" ; then - echo "Patch for this ($driver_version) nvidia driver not found." 1>&2 - echo "Available patches for: " 1>&2 - for drv in "${!patch_list[@]}"; do - echo "$drv" 1>&2 - done + echo "Patch for this ($driver_version) nvidia driver not found." + echo "Patch is available for versions: " + get_supported_versions exit 1 fi @@ -198,10 +205,16 @@ query_version_support () { fi } +list_supported_versions () { + get_supported_versions +} + case "${opmode}" in patch) patch ;; patchrollback) rollback ;; patchhelp) print_usage ; exit 2 ;; patchcheckversion) query_version_support ;; - *) echo "Incorrect combination of flags"; exit 2 ;; + patchlistversions) list_supported_versions ;; + *) echo "Incorrect combination of flags. Use option -h to get help." + exit 2 ;; esac From 5c2471afb1dac65eb3e1b3c5d035ef6954c7840e Mon Sep 17 00:00:00 2001 From: Vladislav Yarmak Date: Fri, 27 Sep 2019 23:57:55 +0300 Subject: [PATCH 4/5] linux: make patch invocation idempotent --- patch.sh | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/patch.sh b/patch.sh index f3b4962..d89d07f 100755 --- a/patch.sh +++ b/patch.sh @@ -28,14 +28,14 @@ DESCRIPTION opmode="patch" while getopts 'rshc:l' flag; do - case "${flag}" in - r) opmode="${opmode}rollback" ;; - s) silent_flag='true' ;; - h) opmode="${opmode}help" ;; - c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;; - l) opmode="${opmode}listversions" ;; - *) echo "Incorrect option specified in command line" ; exit 2 ;; - esac + case "${flag}" in + r) opmode="${opmode}rollback" ;; + s) silent_flag='true' ;; + h) opmode="${opmode}help" ;; + c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;; + l) opmode="${opmode}listversions" ;; + *) echo "Incorrect option specified in command line" ; exit 2 ;; + esac done if [[ $silent_flag ]]; then @@ -181,8 +181,15 @@ rollback () { patch () { patch_common - if [[ ! -f "$backup_path/$object.$driver_version" ]]; then - echo "Attention! Backup not found. Copy current $object to backup." + if [[ -f "$backup_path/$object.$driver_version" ]]; then + bkp_hash="$(sha1sum "$backup_path/$object.$driver_version" | 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." + return 0 + fi + else + 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" From 2ca3692831613e837df8a9fa6f9bfcce49bbf844 Mon Sep 17 00:00:00 2001 From: Vladislav Yarmak Date: Sat, 28 Sep 2019 00:08:35 +0300 Subject: [PATCH 5/5] linux: patch.sh: reflect CLI changes in docs --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0331020..2469633 100644 --- a/README.md +++ b/README.md @@ -49,14 +49,17 @@ Requirements: # bash ./patch.sh -h SYNOPSIS - patch.sh [OPTION]... + patch.sh [-s] [-r|-h|-c VERSION|-l] DESCRIPTION - The patch for Nvidia drivers to increase encoder sessions + The patch for Nvidia drivers to remove NVENC session limit - -s Silent mode (No output) - -r Rollback to original (Restore lib from backup) - -h Print this help message + -s Silent mode (No output) + -r Rollback to original (Restore lib from backup) + -h Print this help message + -c VERSION Check if version VERSION supported by this patch. + Returns true exit code (0) if version is supported. + -l List supported driver versions ```