From f8445488794ef0ba7084486bfa9267be2648f160 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 27 Feb 2023 21:35:07 +1100 Subject: [PATCH 01/75] Update syno_hdd_db.sh Changed to avoid issue #2 --- syno_hdd_db.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index f374ae1..b1bb53d 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -71,7 +71,7 @@ done # SATA drives sda, sdb etc for drive in /dev/sd*; do - if [[ $drive =~ /dev/sd[a-z]{1,3}$ ]]; then + if [[ $drive =~ /dev/sd[a-z]{1,2}$ ]]; then tmp=$(hdparm -i "$drive" | grep Model) hdmodel=$(printf %s "$tmp" | cut -d"," -f 1 | cut -d"=" -f 2) fwrev=$(printf %s "$tmp" | cut -d"," -f 2 | cut -d"=" -f 2) @@ -227,15 +227,11 @@ done if [[ ${showedits,,} == "yes" ]]; then lines=$(((db2Edits *12) +4)) if [[ $db1Edits -gt "0" ]]; then - #echo -e "\nChanges to $(basename -- "$db1")" echo -e "\nChanges to ${Cyan}$(basename -- "$db1")${Off}" - #jq . "$db1" # nice colorized json format but displays whole file jq . "$db1" | tail -n "$lines" # show last 20 lines per edit fi if [[ $db2Edits -gt "0" ]]; then - #echo -e "\nChanges to $(basename -- "$db2")" echo -e "\nChanges to ${Cyan}$(basename -- "$db2")${Off}" - #jq . "$db2" | tail -n $((db2Edits *16)) # show last 20 lines per edit jq . "$db2" | tail -n "$lines" # show last 20 lines per edit fi fi From 5a6081cd690488207034d289d59bab054a79ff48 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Wed, 1 Mar 2023 18:30:58 +1100 Subject: [PATCH 02/75] Update syno_hdd_db.sh Added 2nd method of disabling disk compatibility to solve issue #1 and issue #4 for the few people where the original method didn't work. --- syno_hdd_db.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index b1bb53d..69f56ad 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -222,6 +222,12 @@ while [[ $num -lt "${#nvmes[@]}" ]]; do num=$((num +1)) done +# Brute force method just in case +sdc=support_disk_compatibility +setting="$(get_key_value /etc.defaults/synoinfo.conf $sdc)" +if [[ $setting == "yes" ]]; then + sed -i "s/${sdc}=\"yes\"/${sdc}=\"no\"/g" "/etc.defaults/synoinfo.conf" +fi # Show the changes if [[ ${showedits,,} == "yes" ]]; then @@ -236,6 +242,7 @@ if [[ ${showedits,,} == "yes" ]]; then fi fi +echo -e "\nYou may need to ${Cyan}reboot the Synology${Off} to see the changes." exit From 105bcf9ba8e1ff6f23cac171a6f9d90476077413 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 3 Mar 2023 10:58:49 +1100 Subject: [PATCH 03/75] Update syno_hdd_db.sh Added message if newer script version is available. --- syno_hdd_db.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 69f56ad..d019452 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -30,6 +30,26 @@ # Add support for NVMe drives. +scriptver="1.0.7" + +# Check latest release with GitHub API +get_latest_release() { + curl --silent "https://api.github.com/repos/$1/releases/latest" | + grep '"tag_name":' | # Get tag line + sed -E 's/.*"([^"]+)".*/\1/' # Pluck JSON value +} + +tag=$(get_latest_release "007revad/Synology_HDD_db") + +if [[ ${tag:1} > "$scriptver" ]]; then + echo "There is a newer version of this script available." + echo -e "Current version: ${scriptver}\nLatest version: ${tag:1}" + echo "https://github.com/007revad/Synology_HDD_db/releases/latest" + echo "" + sleep 10 +fi + + # Check for -s or -showedits flag if [[ ${1,,} == "-s" ]] || [[ ${1,,} == "-showedits" ]]; then showedits=yes; fi From f598c6cd14a92db310d066b55e1768bed5eddad8 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sun, 5 Mar 2023 18:54:24 +1100 Subject: [PATCH 04/75] Create CHANGES.txt --- CHANGES.txt | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 CHANGES.txt diff --git a/CHANGES.txt b/CHANGES.txt new file mode 100644 index 0000000..4d120b7 --- /dev/null +++ b/CHANGES.txt @@ -0,0 +1,36 @@ +v1.1.8 +- Added support for SAS drives. +- Now gets HDD/SSD/SAS drive model number with smartctl instead of hdparm. +- Now prevents DSM auto updating the drive database. +- Disable "support_disk_compatibility" (that was added in v1.0.6) is now optional. + - Run script with -f or -force to disable "support_disk_compatibility". + - If run without -f or -force "support_disk_compatibility" is re-enabled. + +v1.0.7 +Added message if newer script version is available. + +v1.0.6 +Added 2nd method of disabling disk compatibility to solve issue #1 and #4 for the few people where the original method didn't work. + +v1.0.5 +Changed to avoid issue #2 + +v1.0.4 +Now backs up the database file if there is no backup already. + +v1.0.3 +Changed to avoid avoid error messages from previous change to search for sda and sata# drives in DSM 6 and DSM 7. +- /dev/sata*: No such file or directory +- /dev/sd*: No such file or directory + +v1.0.2 +Improved formatting when listing found drives. + +v1.0.1 +Fixed issue where drives weren't detected if: +- NAS had been updated from DSM 6 to DSM 7 and still used sda, sdb etc. +- Models like the DVA3219 that use sata# even in DSM 6. + +v1.0.0 +Initial release. + From 2b88e2728811d6030347c42b70172c0c495d8236 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sun, 5 Mar 2023 18:54:32 +1100 Subject: [PATCH 05/75] Update syno_hdd_db.sh - Added support for SAS drives. - Now gets HDD/SSD/SAS drive model number with smartctl instead of hdparm. - Now prevents DSM auto updating the drive database. - Disable "support_disk_compatibility" (that was added in v1.0.6) is now optional. - Run script with -f or -force to disable "support_disk_compatibility". - If run without -f or -force "support_disk_compatibility" is re-enabled. --- syno_hdd_db.sh | 116 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 107 insertions(+), 9 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index d019452..17b0257 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -18,19 +18,35 @@ # sudo /volume1/scripts/syno_hdd_db.sh # or # sudo /volume1/scripts/syno_hdd_db.sh -showedits +# or +# sudo /volume1/scripts/syno_hdd_db.sh -force -showedits #-------------------------------------------------------------------------------------------------- # TODO # Detect if expansion unit(s) connected and get model(s) and edit expansion unit db files. # Or add support for specifying user's expansion unit model(s) as arguments. # Or maybe use the shotgun approach and update all expansion unit db files. -# Add support for SAS drives? Are are listed as /dev/sata# or /dev/sas# ? +# +# Add support for M.2 SATA and NVMe drives on a M2D17 PCI card. +# +# Maybe also edit the other disk compatibility DB in synoboot, used during boot time. +# It's also parsed and checked and probably in some cases it could be more critical to patch that one instead. # DONE +# Add support for SAS drives. +# +# Get HDD/SSD/SAS drive model number with smartctl instead of hdparm. +# +# Check if there is a newer script version available. +# # Add support for NVMe drives. +# +# Prevent DSM auto updating the drive database. +# +# Optionally disable "support_disk_compatibility". -scriptver="1.0.7" +scriptver="1.1.8" # Check latest release with GitHub API get_latest_release() { @@ -50,15 +66,35 @@ if [[ ${tag:1} > "$scriptver" ]]; then fi -# Check for -s or -showedits flag -if [[ ${1,,} == "-s" ]] || [[ ${1,,} == "-showedits" ]]; then showedits=yes; fi +# Check for flags with getopts +OPTERR=0 +while getopts "sfn" option; do + # Need to ensure any other long flags do not contain s, n, or f + if [[ ! ${#option} -gt "1" ]]; then + case ${option,,,} in + s) + showedits=yes + echo showedits # debug + ;; + n) + nodbupdate=yes # For future use + ;; + f) + force=yes + ;; + *) + ;; + esac + fi +done + model=$(cat /proc/sys/kernel/syno_hw_version) model=${model,,} # convert to lower case # Check for -j after model - GitHub issue #2 if [[ $model =~ '-j'$ ]]; then - model=${model%??} # remove last to chars + model=${model%??} # remove last two chars fi # Get DSM major version @@ -129,7 +165,13 @@ express=$(cat /proc/devices | grep nvme) if [[ $express ]]; then for path in /sys/class/nvme/*; do nvmemodel=$(cat "$path"/model) - nvmemodel=$(echo "$nvmemodel" | xargs) # trim leading and trailing white space + + shopt -s extglob + nvmemodel=${nvmemodel/#*([[:space:]])} # Remove leading spaces + #echo "$nvmemodel" " Without leading spaces" # debug + nvmemodel=${nvmemodel/%*([[:space:]])} # Remove trailing spaces + #echo "$nvmemodel" " Without trailing spaces" # debug + shopt -u extglob #if [[ $nvmemodel ]]; then echo "NVMe model: ${nvmemodel}"; fi # debug nvmefw=$(cat "$path"/firmware_rev) @@ -242,13 +284,68 @@ while [[ $num -lt "${#nvmes[@]}" ]]; do num=$((num +1)) done -# Brute force method just in case + +# Optionally disable "support_disk_compatibility" sdc=support_disk_compatibility setting="$(get_key_value /etc.defaults/synoinfo.conf $sdc)" -if [[ $setting == "yes" ]]; then - sed -i "s/${sdc}=\"yes\"/${sdc}=\"no\"/g" "/etc.defaults/synoinfo.conf" +if [[ $force == "yes" ]]; then + if [[ $setting == "yes" ]]; then + # Disable support_disk_compatibility + sed -i "s/${sdc}=\"yes\"/${sdc}=\"no\"/g" "/etc.defaults/synoinfo.conf" + setting="$(get_key_value /etc.defaults/synoinfo.conf $sdc)" + if [[ $setting == "no" ]]; then + echo -e "\nDisabled support disk compatibility." + fi + fi +else + if [[ $setting == "no" ]]; then + # Enable support_disk_compatibility + sed -i "s/${sdc}=\"no\"/${sdc}=\"yes\"/g" "/etc.defaults/synoinfo.conf" + setting="$(get_key_value /etc.defaults/synoinfo.conf $sdc)" + if [[ $setting == "yes" ]]; then + echo -e "\nRe-enabled support disk compatibility." + fi + fi fi + +# Edit synoinfo.conf to prevent DB updates +#if [[ $nodbupdate == "yes" ]]; then # For future use + file=/etc.defaults/synoinfo.conf + if [[ -f $file ]]; then + # Backup synoinfo.conf if needed + if [[ ! -f "$file.bak" ]]; then + if cp "$file" "$file.bak"; then + echo "Backed up synoinfo.conf to $(basename -- "${file}").bak" + else + echo -e "\e[41m ERROR:\e[0m Failed to backup $(basename -- "${file}")!" + exit 6 + fi + fi + + url=$(get_key_value "$file" drive_db_test_url) # returns a linefeed if key doesn't exist + if [[ ! $url ]]; then + # Add drive_db_test_url=127.0.0.1 + echo "drive_db_test_url=127.0.0.1" >> "$file" + disabled="yes" + elif [[ $url != "127.0.0.1" ]]; then + # Edit drive_db_test_url= + sed -i "s/drive_db_test_url=$url/drive_db_test_url=127.0.0.1/g" "$file" + disabled="yes" + fi + + url=$(get_key_value "$file" drive_db_test_url) + if [[ $disabled == "yes" ]]; then + if [[ $url == "127.0.0.1" ]]; then + echo "Disabled drive db auto updates." + else + echo -e "\e[41m ERROR:\e[0m Failed to disable drive db auto updates!" + fi + fi + fi +#fi + + # Show the changes if [[ ${showedits,,} == "yes" ]]; then lines=$(((db2Edits *12) +4)) @@ -264,5 +361,6 @@ fi echo -e "\nYou may need to ${Cyan}reboot the Synology${Off} to see the changes." + exit From 971940dbd0cd33574fdf4219693d10ef6b050a21 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sun, 5 Mar 2023 19:13:01 +1100 Subject: [PATCH 06/75] Update README.md --- README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d2e9db5..9b25163 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # Synology HDD db ### Description -Add your HDD, SSD and NVMe drives to your Synology's compatible drive database. +Add your HDD, SSD, SAS and NVMe drives to your Synology's compatible drive database. The script works in DSM 7 and DSM 6. @@ -17,17 +17,29 @@ #### What the script does: * Backs up the database file if there is no backup already. * Checks if each drive is already in the Synology's compatible-drive database. * Adds any missing drives to the Synology's compatible-drive database. +* Prevents DSM auto updating the drive database. +* Optionally disable DSM's "support_disk_compatibility". +* Reminds you that you may need to reboot the Synology after running the script. **Planned updates:** * Detect any connected expansion units and get the model(s) and edit the correct expansion unit db files. * Or add support for users to specify their expansion unit model(s) as arguments. * Or maybe use the shotgun approach and update all expansion unit db files. -* Add support for SAS drives? Are SAS drives listed as /dev/sata# or /dev/sas# ? +* Add support for M.2 SATA and NVMe drives on a Synology PCIe card like the M2D17. ### When to run the script DSM updates wil almost certainly overwrite the drive-compatibility database files so you may need to run the script after every DSM update. You would also have to re-run the script after DSM downloads a newer version of the drive-compatibility database, which can happen between DSM updates. The best option is to run the script every time the Synology boots, and the best way to do that is to setup a scheduled task to run the the script at boot-up. +**Note:** After you first run the script you may need to reboot the Synology to see the effect of the changes. + +### Options when running the script + +There are 2 optional flags you can use when running the script: +* -showedits or -s to show you the changes it made to the Synology's compatible-drive database. +* -force or -f to disable "support_disk_compatibility". This should be needed if any of your drives weren't detected. + * If you run the script without -force or -f it will re-eanble "support_disk_compatibility". + ### Scheduling the script in Synology's Task Scheduler See How to schedule a script in Synology Task Manager @@ -57,3 +69,4 @@ ### Running the script via SSH **Credits** The idea for this script came from a comment made by Empyrealist on the Synology subreddit. +Thanks for the assistance from Alex_of_Chaos on the Synology subreddit. From b775298c397f099a91053c82215fd6f3f6a75c7a Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 6 Mar 2023 10:29:43 +1100 Subject: [PATCH 07/75] Update syno_hdd_db.sh Added SAS drive support --- syno_hdd_db.sh | 168 ++++++++++++++++++++++++++++++------------------- 1 file changed, 103 insertions(+), 65 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 17b0257..3cb5598 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -46,7 +46,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="1.1.8" +scriptver="1.1.9" # Check latest release with GitHub API get_latest_release() { @@ -111,32 +111,96 @@ fi #------------------------------------------------------------------------------ -# Get list of installed HDDs and SATA SSDs - -# SATA drives, sata1, sata2 etc -for drive in /dev/sata*; do - if [[ $drive =~ /dev/sata[1-9][0-9]?[0-9]?$ ]]; then - tmp=$(hdparm -i "$drive" | grep Model) - hdmodel=$(printf %s "$tmp" | cut -d"," -f 1 | cut -d"=" -f 2) - fwrev=$(printf %s "$tmp" | cut -d"," -f 2 | cut -d"=" -f 2) - if [[ $hdmodel ]] && [[ $fwrev ]]; then - hdparm+=("${hdmodel},${fwrev}") - fi +# Get list of installed SATA, SAS and NVMe drives + +getModel() { + hdmodel=$(smartctl -i "$1" | grep -i "Device Model:" | awk '{print $3 $4 $5}') + if [[ ! $hdmodel ]]; then + hdmodel=$(smartctl -i "$1" | grep -i "Product:" | awk '{print $2 $3 $4}') fi -done + #echo "Model: $hdmodel" # debug + + # Brands that return "BRAND " and need "BRAND " removed. + hdmodel=${hdmodel#"WDC "} # Remove "WDC " from start of model name + hdmodel=${hdmodel#"HGST "} # Remove "HGST " from start of model name + hdmodel=${hdmodel#"TOSHIBA "} # Remove "TOSHIBA " from start of model name + + # Old drive brands + hdmodel=${hdmodel#"Hitachi "} # Remove "Hitachi " from start of model name + hdmodel=${hdmodel#"SAMSUNG "} # Remove "SAMSUNG " from start of model name + hdmodel=${hdmodel#"FUJISTU "} # Remove "FUJISTU " from start of model name + hdmodel=${hdmodel#"APPLE HDD "} # Remove "APPLE HDD " from start of model name + + shopt -s extglob + hdmodel=${hdmodel/#*([[:space:]])} # Remove leading spaces + hdmodel=${hdmodel/%*([[:space:]])} # Remove trailing spaces + shopt -u extglob + #echo "Model: $hdmodel" # debug +} -# SATA drives sda, sdb etc -for drive in /dev/sd*; do - if [[ $drive =~ /dev/sd[a-z]{1,2}$ ]]; then - tmp=$(hdparm -i "$drive" | grep Model) - hdmodel=$(printf %s "$tmp" | cut -d"," -f 1 | cut -d"=" -f 2) - fwrev=$(printf %s "$tmp" | cut -d"," -f 2 | cut -d"=" -f 2) - if [[ $hdmodel ]] && [[ $fwrev ]]; then - hdparm+=("${hdmodel},${fwrev}") - fi +getFwVersion() { + tmp=$(hdparm -i "$1" | grep Model) + fwrev=$(printf %s "$tmp" | cut -d"," -f 2 | cut -d"=" -f 2) + #echo "Firmware: $fwrev" # debug +} + +getNVMeModel() { + nvmemodel=$(cat $1/model) + shopt -s extglob + nvmemodel=${nvmemodel/#*([[:space:]])} # Remove leading spaces + nvmemodel=${nvmemodel/%*([[:space:]])} # Remove trailing spaces + shopt -u extglob + #echo "NVMe Model: $nvmemodel" # debug +} + +getNVMeFwVersion() { + nvmefw=$(cat $1/firmware_rev) + nvmefw=$(echo "$nvmefw" | xargs) # trim leading and trailing white space + #echo "NVMe Firmware: $nvmefw" # debug +} + + +for d in `cat /proc/partitions | awk '{print $4}'`; do + if [ ! -e /dev/$d ]; then + continue; fi + #echo $d # debug + case "$d" in + hd*|sd*) + if [[ $d =~ [hs]d[a-z]{1,2}$ ]]; then + echo -e "\n$d" # debug + getModel "/dev/$d" + getFwVersion "/dev/$d" + if [[ $hdmodel ]] && [[ $fwrev ]]; then + hdparm+=("${hdmodel},${fwrev}") + fi + fi + ;; + sas*|sata*) + if [[ $d =~ (sas|sata)[0-9][0-9]?[0-9]?$ ]]; then + echo -e "\n$d" # debug + getModel "/dev/$d" + getFwVersion "/dev/$d" + if [[ $hdmodel ]] && [[ $fwrev ]]; then + hdparm+=("${hdmodel},${fwrev}") + fi + fi + ;; + nvme*) + if [[ $d =~ nvme[0-9][0-9]?n[0-9][0-9]?$ ]]; then + echo -e "\n$d" # debug + n=n$(printf "$d" | cut -d "n" -f 2) + getNVMeModel "/sys/class/nvme/$n" + getNVMeFwVersion "/sys/class/nvme/$n" + if [[ $nvmemodel ]] && [[ $nvmefw ]]; then + nvmelist+=("${nvmemodel},${nvmefw}") + fi + fi + ;; + esac done + # Sort hdparm array into new hdds array to remove duplicates if [[ ${#hdparm[@]} -gt "0" ]]; then while IFS= read -r -d '' x; do @@ -158,50 +222,24 @@ else fi -#------------------------------------------------------------------------------ -# Get list of installed NVMe drives - -express=$(cat /proc/devices | grep nvme) -if [[ $express ]]; then - for path in /sys/class/nvme/*; do - nvmemodel=$(cat "$path"/model) - - shopt -s extglob - nvmemodel=${nvmemodel/#*([[:space:]])} # Remove leading spaces - #echo "$nvmemodel" " Without leading spaces" # debug - nvmemodel=${nvmemodel/%*([[:space:]])} # Remove trailing spaces - #echo "$nvmemodel" " Without trailing spaces" # debug - shopt -u extglob - #if [[ $nvmemodel ]]; then echo "NVMe model: ${nvmemodel}"; fi # debug - - nvmefw=$(cat "$path"/firmware_rev) - nvmefw=$(echo "$nvmefw" | xargs) # trim leading and trailing white space - #if [[ $nvmefw ]]; then echo "NVMe firmware: ${nvmefw}"; fi # debug - - if [[ $nvmemodel ]] && [[ $nvmefw ]]; then - nvmelist+=("${nvmemodel},${nvmefw}") - fi - done - - # Sort nvmelist array into new nvmes array to remove duplicates - if [[ ${#nvmelist[@]} -gt "0" ]]; then - while IFS= read -r -d '' x; do - nvmes+=("$x") - done < <(printf "%s\0" "${nvmelist[@]}" | sort -uz) - fi +# Sort nvmelist array into new nvmes array to remove duplicates +if [[ ${#nvmelist[@]} -gt "0" ]]; then + while IFS= read -r -d '' x; do + nvmes+=("$x") + done < <(printf "%s\0" "${nvmelist[@]}" | sort -uz) +fi - # Check hdds array isn't empty - if [[ ${#nvmes[@]} -eq "0" ]]; then - echo -e "No NVMe drives found\n" - else - echo "NVMe drive models found: ${#nvmes[@]}" - num="0" - while [[ $num -lt "${#nvmes[@]}" ]]; do - echo "${nvmes[num]}" - num=$((num +1)) - done - echo - fi +# Check nvmes array isn't empty +if [[ ${#nvmes[@]} -eq "0" ]]; then + echo -e "No NVMe drives found\n" +else + echo "NVMe drive models found: ${#nvmes[@]}" + num="0" + while [[ $num -lt "${#nvmes[@]}" ]]; do + echo "${nvmes[num]}" + num=$((num +1)) + done + echo fi From 226057e5a7e1d8a2557a6baa419c47d408d1040f Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 6 Mar 2023 10:30:41 +1100 Subject: [PATCH 08/75] Update CHANGES.txt Added SAS drive support --- CHANGES.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 4d120b7..6e5eac0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,8 @@ -v1.1.8 +v1.1.9 - Added support for SAS drives. - Now gets HDD/SSD/SAS drive model number with smartctl instead of hdparm. + +v1.1.8 - Now prevents DSM auto updating the drive database. - Disable "support_disk_compatibility" (that was added in v1.0.6) is now optional. - Run script with -f or -force to disable "support_disk_compatibility". From a461205245a85d8181ba771b2b7a47f21f246804 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 6 Mar 2023 10:34:44 +1100 Subject: [PATCH 09/75] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9b25163..73c5da5 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ #### What the script does: ### When to run the script -DSM updates wil almost certainly overwrite the drive-compatibility database files so you may need to run the script after every DSM update. You would also have to re-run the script after DSM downloads a newer version of the drive-compatibility database, which can happen between DSM updates. The best option is to run the script every time the Synology boots, and the best way to do that is to setup a scheduled task to run the the script at boot-up. +You would need to re-run the script after a DSM update. If you have DSM set to auto update the best option is to run the script every time the Synology boots, and the best way to do that is to setup a scheduled task to run the the script at boot-up. **Note:** After you first run the script you may need to reboot the Synology to see the effect of the changes. @@ -68,5 +68,5 @@ ### Running the script via SSH **Credits** -The idea for this script came from a comment made by Empyrealist on the Synology subreddit. -Thanks for the assistance from Alex_of_Chaos on the Synology subreddit. +- The idea for this script came from a comment made by Empyrealist on the Synology subreddit. +- Thanks for the assistance from Alex_of_Chaos on the Synology subreddit. From 84fc310592c1c23a1d60fe4f60e507d4df9e8be6 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 6 Mar 2023 10:54:46 +1100 Subject: [PATCH 10/75] Update syno_hdd_db.sh --- syno_hdd_db.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 3cb5598..f9c2b8f 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -74,7 +74,7 @@ while getopts "sfn" option; do case ${option,,,} in s) showedits=yes - echo showedits # debug + #echo showedits # debug ;; n) nodbupdate=yes # For future use @@ -168,7 +168,7 @@ for d in `cat /proc/partitions | awk '{print $4}'`; do case "$d" in hd*|sd*) if [[ $d =~ [hs]d[a-z]{1,2}$ ]]; then - echo -e "\n$d" # debug + #echo -e "\n$d" # debug getModel "/dev/$d" getFwVersion "/dev/$d" if [[ $hdmodel ]] && [[ $fwrev ]]; then @@ -178,7 +178,7 @@ for d in `cat /proc/partitions | awk '{print $4}'`; do ;; sas*|sata*) if [[ $d =~ (sas|sata)[0-9][0-9]?[0-9]?$ ]]; then - echo -e "\n$d" # debug + #echo -e "\n$d" # debug getModel "/dev/$d" getFwVersion "/dev/$d" if [[ $hdmodel ]] && [[ $fwrev ]]; then @@ -188,7 +188,7 @@ for d in `cat /proc/partitions | awk '{print $4}'`; do ;; nvme*) if [[ $d =~ nvme[0-9][0-9]?n[0-9][0-9]?$ ]]; then - echo -e "\n$d" # debug + #echo -e "\n$d" # debug n=n$(printf "$d" | cut -d "n" -f 2) getNVMeModel "/sys/class/nvme/$n" getNVMeFwVersion "/sys/class/nvme/$n" From 72c86b337374caf0b7f4feeb26699c1c87d0a464 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Thu, 9 Mar 2023 06:41:12 +1100 Subject: [PATCH 11/75] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 73c5da5..da852bd 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ ### Description #### What the script does: * Gets the Synology NAS model and DSM version (so it knows which db files to edit). -* Gets a list of the HDD, SSD and NVMe drives installed in your Synology NAS. +* Gets a list of the HDD, SSD, SAS and NVMe drives installed in your Synology NAS. * Gets each drive's model number and firmware version. * Backs up the database file if there is no backup already. * Checks if each drive is already in the Synology's compatible-drive database. From ada37160b1aeeb235755bb7c10284654d51c131e Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:04:47 +1100 Subject: [PATCH 12/75] Update syno_hdd_db.sh Fixed DSM6 bug when DSM6 used the old db file format. --- syno_hdd_db.sh | 170 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 125 insertions(+), 45 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index f9c2b8f..680d525 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -31,8 +31,12 @@ # # Maybe also edit the other disk compatibility DB in synoboot, used during boot time. # It's also parsed and checked and probably in some cases it could be more critical to patch that one instead. +# +# Changed SAS drive firmware version detection to use smartctl to support SAS drives that hdparm doesn't work with. # DONE +# Fixed DSM6 bug when DSM6 used the old db file format. +# # Add support for SAS drives. # # Get HDD/SSD/SAS drive model number with smartctl instead of hdparm. @@ -46,7 +50,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="1.1.9" +scriptver="1.1.10" # Check latest release with GitHub API get_latest_release() { @@ -105,7 +109,7 @@ fi # Check script is running as root if [[ $( whoami ) != "root" ]]; then - echo -e "\e[41m ERROR:\e[0m This script must be run as root or sudo!" + echo -e "\e[41m ERROR \e[0m This script must be run as root or sudo!" exit 1 fi @@ -121,6 +125,7 @@ getModel() { #echo "Model: $hdmodel" # debug # Brands that return "BRAND " and need "BRAND " removed. + # Smartmontools database in /var/lib/smartmontools/drivedb.db hdmodel=${hdmodel#"WDC "} # Remove "WDC " from start of model name hdmodel=${hdmodel#"HGST "} # Remove "HGST " from start of model name hdmodel=${hdmodel#"TOSHIBA "} # Remove "TOSHIBA " from start of model name @@ -145,7 +150,7 @@ getFwVersion() { } getNVMeModel() { - nvmemodel=$(cat $1/model) + nvmemodel=$(cat "$1"/model) shopt -s extglob nvmemodel=${nvmemodel/#*([[:space:]])} # Remove leading spaces nvmemodel=${nvmemodel/%*([[:space:]])} # Remove trailing spaces @@ -154,14 +159,14 @@ getNVMeModel() { } getNVMeFwVersion() { - nvmefw=$(cat $1/firmware_rev) + nvmefw=$(cat "$1"/firmware_rev) nvmefw=$(echo "$nvmefw" | xargs) # trim leading and trailing white space #echo "NVMe Firmware: $nvmefw" # debug } -for d in `cat /proc/partitions | awk '{print $4}'`; do - if [ ! -e /dev/$d ]; then +for d in $(cat /proc/partitions | awk '{print $4}'); do + if [ ! -e /dev/"$d" ]; then continue; fi #echo $d # debug @@ -189,7 +194,7 @@ for d in `cat /proc/partitions | awk '{print $4}'`; do nvme*) if [[ $d =~ nvme[0-9][0-9]?n[0-9][0-9]?$ ]]; then #echo -e "\n$d" # debug - n=n$(printf "$d" | cut -d "n" -f 2) + n=n$(printf "%s" "$d" | cut -d "n" -f 2) getNVMeModel "/sys/class/nvme/$n" getNVMeFwVersion "/sys/class/nvme/$n" if [[ $nvmemodel ]] && [[ $nvmefw ]]; then @@ -210,7 +215,7 @@ fi # Check hdds array isn't empty if [[ ${#hdds[@]} -eq "0" ]]; then - echo -e "\e[41m ERROR:\e[0m No drives found!" && exit 2 + echo -e "\e[41m ERROR \e[0m No drives found!" && exit 2 else echo "HDD/SSD models found: ${#hdds[@]}" num="0" @@ -249,8 +254,23 @@ fi db1="/var/lib/disk-compatibility/${model}_host${version}.db" db2="/var/lib/disk-compatibility/${model}_host${version}.db.new" -if [[ ! -f "$db1" ]]; then echo -e "\e[41m ERROR:\e[0m $db1 not found!" && exit 3; fi -if [[ ! -f "$db2" ]]; then echo -e "\e[41m ERROR:\e[0m $db2 not found!" && exit 4; fi +if [[ ! -f "$db1" ]]; then echo -e "\e[41m ERROR \e[0m $db1 not found!" && exit 3; fi +#if [[ ! -f "$db2" ]]; then echo -e "\e[41m ERROR \e[0m $db2 not found!" && exit 4; fi +# new installs don't have a .new file + + +# Detect drive db type +if grep -F '{"disk_compatbility_info":' "$db1" >/dev/null; then + # DSM7 drive db files start with {"disk_compatbility_info": + dbtype=7 +elif grep -F '{"success":1,"list":[' "$db1" >/dev/null; then + # DSM7 drive db files start with {"success":1,"list":[ + dbtype=6 +else + echo -e "\e[41m ERROR \e[0m Unknown database type $(basename -- "${db1}")!" + exit 7 +fi +#echo "dbtype: $dbtype" # debug # Backup database file if needed @@ -258,7 +278,7 @@ if [[ ! -f "$db1.bak" ]]; then if cp "$db1" "$db1.bak"; then echo -e "Backed up database to $(basename -- "${db1}").bak\n" else - echo -e "\e[41m ERROR:\e[0m Failed to backup $(basename -- "${db1}")!" + echo -e "\e[41m ERROR \e[0m Failed to backup $(basename -- "${db1}")!" exit 5 fi fi @@ -267,6 +287,7 @@ fi # Shell Colors Yellow='\e[0;33m' Cyan='\e[0;36m' +Red='\e[0;31m' Off=$'\e[0m' function updatedb() { @@ -281,27 +302,52 @@ function updatedb() { if grep "$hdmodel" "$2" >/dev/null; then echo -e "${Yellow}$hdmodel${Off} already exists in ${Cyan}$(basename -- "$2")${Off}" else - # Don't need to add firmware version? - fwstrng=\"$fwrev\" - fwstrng="$fwstrng":{\"compatibility_interval\":[{\"compatibility\":\"support\",\"not_yet_rolling_status\" - fwstrng="$fwstrng":\"support\",\"fw_dsm_update_status_notify\":false,\"barebone_installable\":true}]}, - - default=\"default\" - default="$default":{\"compatibility_interval\":[{\"compatibility\":\"support\",\"not_yet_rolling_status\" - default="$default":\"support\",\"fw_dsm_update_status_notify\":false,\"barebone_installable\":true}]}}} - - #if sed -i "s/}}}/}},\"$hdmodel\":{$fwstrng$default/g" "$2"; then # Don't need to add firmware version? - if sed -i "s/}}}/}},\"$hdmodel\":{$default/g" "$2"; then - #echo "Added $hdmodel to $(basename -- "$2")" - echo -e "Added ${Yellow}$hdmodel${Off} to ${Cyan}$(basename -- "$2")${Off}" - if [[ $2 == "$db1" ]]; then - db1Edits=$((db1Edits +1)) - elif [[ $2 == "$db2" ]]; then - db2Edits=$((db2Edits +1)) + if [[ $dbtype -gt "6" ]];then + # Don't need to add firmware version? + fwstrng=\"$fwrev\" + fwstrng="$fwstrng":{\"compatibility_interval\":[{\"compatibility\":\"support\",\"not_yet_rolling_status\" + fwstrng="$fwstrng":\"support\",\"fw_dsm_update_status_notify\":false,\"barebone_installable\":true}]}, + + default=\"default\" + default="$default":{\"compatibility_interval\":[{\"compatibility\":\"support\",\"not_yet_rolling_status\" + default="$default":\"support\",\"fw_dsm_update_status_notify\":false,\"barebone_installable\":true}]}}} + + #if sed -i "s/}}}/}},\"$hdmodel\":{$fwstrng$default/" "$2"; then # Don't need to add firmware version? + if sed -i "s/}}}/}},\"$hdmodel\":{$default/" "$2"; then + echo -e "Added ${Yellow}$hdmodel${Off} to ${Cyan}$(basename -- "$2")${Off}" + if [[ $2 == "$db1" ]]; then + db1Edits=$((db1Edits +1)) + elif [[ $2 == "$db2" ]]; then + db2Edits=$((db2Edits +1)) + fi + else + echo -e "\n\e[41m ERROR \e[0m Failed to update v7 $(basename -- "$2")${Off}" + exit 6 fi else - echo -e "\n\e[41m ERROR: Failed to update $(basename -- "$2")${Off}" - exit 6 + # example: + # {"model":"WD60EFRX-68MYMN1","firmware":"82.00A82","rec_intvl":[1]}, + string="{\"model\":\"${hdmodel}\",\"firmware\":\"${fwrev}\",\"rec_intvl\":\[1\]}," + # {"success":1,"list":[ + startstring="{\"success\":1,\"list\":\[" + + #echo "$startstring" # debug + #echo "$string" # debug + #echo # debug + + # example: + # {"success":1,"list":[{"model":"WD60EFRX-68MYMN1","firmware":"82.00A82","rec_intvl":[1]}, + if sed -ir "s/$startstring/$startstring$string/" "$2"; then + echo -e "Added ${Yellow}$hdmodel${Off} to ${Cyan}$(basename -- "$2")${Off}" + if [[ $2 == "$db1" ]]; then + db1Edits=$((db1Edits +1)) + elif [[ $2 == "$db2" ]]; then + db2Edits=$((db2Edits +1)) + fi + else + echo -e "\n\e[41m ERROR \e[0m Failed to update $(basename -- "$2")${Off}" + exit 8 + fi fi fi } @@ -310,7 +356,9 @@ function updatedb() { num="0" while [[ $num -lt "${#hdds[@]}" ]]; do updatedb "${hdds[$num]}" "$db1" - updatedb "${hdds[$num]}" "$db2" + if [[ -f "$db2" ]]; then + updatedb "${hdds[$num]}" "$db2" + fi num=$((num +1)) done @@ -318,7 +366,9 @@ done num="0" while [[ $num -lt "${#nvmes[@]}" ]]; do updatedb "${nvmes[$num]}" "$db1" - updatedb "${nvmes[$num]}" "$db2" + if [[ -f "$db2" ]]; then + updatedb "${nvmes[$num]}" "$db2" + fi num=$((num +1)) done @@ -329,7 +379,7 @@ setting="$(get_key_value /etc.defaults/synoinfo.conf $sdc)" if [[ $force == "yes" ]]; then if [[ $setting == "yes" ]]; then # Disable support_disk_compatibility - sed -i "s/${sdc}=\"yes\"/${sdc}=\"no\"/g" "/etc.defaults/synoinfo.conf" + sed -i "s/${sdc}=\"yes\"/${sdc}=\"no\"/" "/etc.defaults/synoinfo.conf" setting="$(get_key_value /etc.defaults/synoinfo.conf $sdc)" if [[ $setting == "no" ]]; then echo -e "\nDisabled support disk compatibility." @@ -338,7 +388,7 @@ if [[ $force == "yes" ]]; then else if [[ $setting == "no" ]]; then # Enable support_disk_compatibility - sed -i "s/${sdc}=\"no\"/${sdc}=\"yes\"/g" "/etc.defaults/synoinfo.conf" + sed -i "s/${sdc}=\"no\"/${sdc}=\"yes\"/" "/etc.defaults/synoinfo.conf" setting="$(get_key_value /etc.defaults/synoinfo.conf $sdc)" if [[ $setting == "yes" ]]; then echo -e "\nRe-enabled support disk compatibility." @@ -356,7 +406,7 @@ fi if cp "$file" "$file.bak"; then echo "Backed up synoinfo.conf to $(basename -- "${file}").bak" else - echo -e "\e[41m ERROR:\e[0m Failed to backup $(basename -- "${file}")!" + echo -e "\e[41m ERROR \e[0m Failed to backup $(basename -- "${file}")!" exit 6 fi fi @@ -368,7 +418,7 @@ fi disabled="yes" elif [[ $url != "127.0.0.1" ]]; then # Edit drive_db_test_url= - sed -i "s/drive_db_test_url=$url/drive_db_test_url=127.0.0.1/g" "$file" + sed -i "s/drive_db_test_url=$url/drive_db_test_url=127.0.0.1/" "$file" disabled="yes" fi @@ -377,7 +427,7 @@ fi if [[ $url == "127.0.0.1" ]]; then echo "Disabled drive db auto updates." else - echo -e "\e[41m ERROR:\e[0m Failed to disable drive db auto updates!" + echo -e "\e[41m ERROR \e[0m Failed to disable drive db auto updates!" fi fi fi @@ -386,18 +436,48 @@ fi # Show the changes if [[ ${showedits,,} == "yes" ]]; then - lines=$(((db2Edits *12) +4)) - if [[ $db1Edits -gt "0" ]]; then - echo -e "\nChanges to ${Cyan}$(basename -- "$db1")${Off}" - jq . "$db1" | tail -n "$lines" # show last 20 lines per edit + if [[ $dbtype -gt "6" ]];then + # Show last 12 lines per drive + 4 + lines=$(((db1Edits *12) +4)) + if [[ $db1Edits -gt "0" ]]; then + echo -e "\nChanges to ${Cyan}$(basename -- "$db1")${Off}" + jq . "$db1" | tail -n "$lines" + fi + if [[ $db2Edits -gt "0" ]]; then + echo -e "\nChanges to ${Cyan}$(basename -- "$db2")${Off}" + jq . "$db2" | tail -n "$lines" + fi + else + # Show first 8 lines per drive + 2 + lines=$(((db1Edits *8) +2)) + if [[ $db1Edits -gt "0" ]]; then + echo -e "\nChanges to ${Cyan}$(basename -- "$db1")${Off}" + jq . "$db1" | head -n "$lines" + fi + if [[ $db2Edits -gt "0" ]]; then + echo -e "\nChanges to ${Cyan}$(basename -- "$db2")${Off}" + jq . "$db2" | head -n "$lines" + fi fi - if [[ $db2Edits -gt "0" ]]; then - echo -e "\nChanges to ${Cyan}$(basename -- "$db2")${Off}" - jq . "$db2" | tail -n "$lines" # show last 20 lines per edit +fi + + +# Make Synology check disk compatability +/usr/syno/sbin/synostgdisk --check-all-disks-compatibility +status=$? +if [[ $status -eq "0" ]]; then + echo -e "\nDSM successfully checked disk compatibility." +else + # Ignore DSM 6 as it returns 255 for "synostgdisk --check-all-disks-compatibility" + if [[ $dsm -gt "6" ]]; then + echo -e "\nDSM ${Red}failed${Off} to check disk compatibility with exit code $status" + echo -e "\nYou may need to ${Cyan}reboot the Synology${Off} to see the changes." fi fi -echo -e "\nYou may need to ${Cyan}reboot the Synology${Off} to see the changes." +if [[ $dsm -eq "6" ]]; then + echo -e "\nYou may need to ${Cyan}reboot the Synology${Off} to see the changes." +fi exit From 7e45f2711597185ef978487869d1ae2cb332d979 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:05:38 +1100 Subject: [PATCH 13/75] Update CHANGES.txt --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 6e5eac0..a8736b8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +v1.1.10 +- Fixed DSM6 bug when DSM6 used the old db file format. + v1.1.9 - Added support for SAS drives. - Now gets HDD/SSD/SAS drive model number with smartctl instead of hdparm. From d47e3dcafb871294c49700b744a1ccff4649c589 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:06:52 +1100 Subject: [PATCH 14/75] Update CHANGES.txt --- CHANGES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.txt b/CHANGES.txt index a8736b8..b5df198 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ v1.1.10 +- Now makes DSM recheck disk compatability so reboot not needed (DSM 7 only). - Fixed DSM6 bug when DSM6 used the old db file format. v1.1.9 From 2635231f9c2fa1ee25d873bf099e480ee75dd0f8 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:08:15 +1100 Subject: [PATCH 15/75] Update syno_hdd_db.sh - Now makes DSM recheck disk compatability so reboot not needed (DSM 7 only). - Fixed DSM6 bug when DSM6 used the old db file format. --- syno_hdd_db.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 680d525..a6c75c1 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -35,6 +35,8 @@ # Changed SAS drive firmware version detection to use smartctl to support SAS drives that hdparm doesn't work with. # DONE +# Make DSM recheck disk compatability so reboot not needed (DSM 7 only). +# # Fixed DSM6 bug when DSM6 used the old db file format. # # Add support for SAS drives. From bef2e3adf4e835b9ede3a59d197cc10fb97fd3c3 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:09:32 +1100 Subject: [PATCH 16/75] Update CHANGES.txt --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index b5df198..0dc8a1f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,6 @@ v1.1.10 - Now makes DSM recheck disk compatability so reboot not needed (DSM 7 only). -- Fixed DSM6 bug when DSM6 used the old db file format. +- Fixed DSM6 bug when DSM 6 used the old db file format. v1.1.9 - Added support for SAS drives. From d7a060a2f18827cf2b2e91dc7fe64081d7359c3e Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:09:45 +1100 Subject: [PATCH 17/75] Update CHANGES.txt --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 0dc8a1f..12f6d6b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,6 @@ v1.1.10 - Now makes DSM recheck disk compatability so reboot not needed (DSM 7 only). -- Fixed DSM6 bug when DSM 6 used the old db file format. +- Fixed DSM 6 bug when DSM 6 used the old db file format. v1.1.9 - Added support for SAS drives. From 1eac13aeeb517af74b98da128ff24688db3042f4 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:11:26 +1100 Subject: [PATCH 18/75] Update CHANGES.txt --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 12f6d6b..647bf79 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,5 @@ v1.1.10 -- Now makes DSM recheck disk compatability so reboot not needed (DSM 7 only). +- Now makes DSM recheck disk compatibility so reboot not needed (DSM 7 only). - Fixed DSM 6 bug when DSM 6 used the old db file format. v1.1.9 From 661e3878d4cefa5d343213da818cbf0ba27d4ab5 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:15:35 +1100 Subject: [PATCH 19/75] Update syno_hdd_db.sh --- syno_hdd_db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index a6c75c1..1963469 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -32,7 +32,7 @@ # Maybe also edit the other disk compatibility DB in synoboot, used during boot time. # It's also parsed and checked and probably in some cases it could be more critical to patch that one instead. # -# Changed SAS drive firmware version detection to use smartctl to support SAS drives that hdparm doesn't work with. +# Change SAS drive firmware version detection to use smartctl to support SAS drives that hdparm doesn't work with. # DONE # Make DSM recheck disk compatability so reboot not needed (DSM 7 only). From 111e79ff9f3dfbd2e2070ed900f126c783ec3096 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:17:14 +1100 Subject: [PATCH 20/75] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index da852bd..410648c 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ #### What the script does: * Adds any missing drives to the Synology's compatible-drive database. * Prevents DSM auto updating the drive database. * Optionally disable DSM's "support_disk_compatibility". -* Reminds you that you may need to reboot the Synology after running the script. +* Makes DSM recheck disk compatibility so rebooting is not needed (DSM 7 only). +* Reminds you that you may need to reboot the Synology after running the script (DSM 6 only). **Planned updates:** * Detect any connected expansion units and get the model(s) and edit the correct expansion unit db files. From 20cf201d143071b9dd7c85bc452f42ed399abeb3 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:18:30 +1100 Subject: [PATCH 21/75] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 410648c..a02d579 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ #### What the script does: * Reminds you that you may need to reboot the Synology after running the script (DSM 6 only). **Planned updates:** +* Fix SAS drive firmware version detection. * Detect any connected expansion units and get the model(s) and edit the correct expansion unit db files. * Or add support for users to specify their expansion unit model(s) as arguments. * Or maybe use the shotgun approach and update all expansion unit db files. From 925b5e7c1498b30909b3babccbc9c4f4cd160a78 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 16:29:17 +1100 Subject: [PATCH 22/75] Update syno_hdd_db.sh Fixed version check --- syno_hdd_db.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 1963469..3336780 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -63,7 +63,8 @@ get_latest_release() { tag=$(get_latest_release "007revad/Synology_HDD_db") -if [[ ${tag:1} > "$scriptver" ]]; then +if ! printf "%s\n%s\n" "$tag" "$scriptver" | + sort --check --version-sort &> /dev/null ; then echo "There is a newer version of this script available." echo -e "Current version: ${scriptver}\nLatest version: ${tag:1}" echo "https://github.com/007revad/Synology_HDD_db/releases/latest" From 43e092420b3edb02007fd7fa88b0ee5e4dede6af Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:20:52 +1100 Subject: [PATCH 23/75] Update CHANGES.txt --- CHANGES.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 647bf79..e784b34 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,11 @@ +v1.1.11 +- Added support for M.2 SATA drives. +- Can now skip processing M.2 drives by running script with the -m2 flag. +- Changed method of getting drive and firmware version so script is faster and easier to maintain. No longer using smartctl or hdparm. +- Changed SAS drive firmware version detection to support SAS drives that hdparm doesn't work with. +- Removed error message and aborting if *.db.new not found (clean DSM installs don't have a *.db.new). +- Fixed script version check introduced in 1.0.7. + v1.1.10 - Now makes DSM recheck disk compatibility so reboot not needed (DSM 7 only). - Fixed DSM 6 bug when DSM 6 used the old db file format. From 0e2eb482872fb7e5722b00569cac85b681d8538a Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:23:41 +1100 Subject: [PATCH 24/75] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a02d579..976da73 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # Synology HDD db ### Description -Add your HDD, SSD, SAS and NVMe drives to your Synology's compatible drive database. +Add your SATA or SAS HDDs and SSDs plus SATA and NVMe M.2 cache drives to your Synology's compatible drive databases. The script works in DSM 7 and DSM 6. @@ -23,24 +23,24 @@ #### What the script does: * Reminds you that you may need to reboot the Synology after running the script (DSM 6 only). **Planned updates:** -* Fix SAS drive firmware version detection. +* Bypass unsupported M.2 drives for use as volumes in DSM 7.2 (for models that supported M.2 volumes). * Detect any connected expansion units and get the model(s) and edit the correct expansion unit db files. * Or add support for users to specify their expansion unit model(s) as arguments. * Or maybe use the shotgun approach and update all expansion unit db files. -* Add support for M.2 SATA and NVMe drives on a Synology PCIe card like the M2D17. ### When to run the script You would need to re-run the script after a DSM update. If you have DSM set to auto update the best option is to run the script every time the Synology boots, and the best way to do that is to setup a scheduled task to run the the script at boot-up. -**Note:** After you first run the script you may need to reboot the Synology to see the effect of the changes. +**Note:** For DSM 6, after you first run the script you may need to reboot the Synology to see the effect of the changes. ### Options when running the script -There are 2 optional flags you can use when running the script: +There are 3 optional flags you can use when running the script: * -showedits or -s to show you the changes it made to the Synology's compatible-drive database. * -force or -f to disable "support_disk_compatibility". This should be needed if any of your drives weren't detected. * If you run the script without -force or -f it will re-eanble "support_disk_compatibility". +* -m2 or -m to prevent processing M.2 drives. ### Scheduling the script in Synology's Task Scheduler From ef3674b187104aecf48b0b6568263cfd2d47e557 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:31:55 +1100 Subject: [PATCH 25/75] Update syno_hdd_db.sh - Added support for M.2 SATA drives. - Can now skip processing M.2 drives by running script with the -m2 flag. - Changed method of getting drive and firmware version so script is faster and easier to maintain. No longer using smartctl or hdparm. - Changed SAS drive firmware version detection to support SAS drives that hdparm doesn't work with. - Removed error message and aborting if *.db.new not found (clean DSM installs don't have a *.db.new). - Fixed script version check introduced in 1.0.7. --- syno_hdd_db.sh | 214 +++++++++++++++++++++++++------------------------ 1 file changed, 108 insertions(+), 106 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 3336780..c8004ba 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -31,13 +31,22 @@ # # Maybe also edit the other disk compatibility DB in synoboot, used during boot time. # It's also parsed and checked and probably in some cases it could be more critical to patch that one instead. -# -# Change SAS drive firmware version detection to use smartctl to support SAS drives that hdparm doesn't work with. # DONE -# Make DSM recheck disk compatability so reboot not needed (DSM 7 only). +# Added support for M.2 SATA drives. +# +# Can now skip processing M.2 drives by running script with the -m2 flag. +# +# Changed method of getting drive and firmware version so script is faster and easier to maintain. +# - No longer using smartctl or hdparm. +# +# Changed SAS drive firmware version detection to support SAS drives that hdparm doesn't work with. # -# Fixed DSM6 bug when DSM6 used the old db file format. +# Removed error message and aborting if *.db.new not found (clean DSM installs don't have a *.db.new). +# +# Force DSM to check disk compatibility so reboot not needed (DSM 6 may still need a reboot). +# +# Fixed DSM 6 issue when DSM 6 has the old db file format. # # Add support for SAS drives. # @@ -52,7 +61,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="1.1.10" +scriptver="1.1.11" # Check latest release with GitHub API get_latest_release() { @@ -75,19 +84,21 @@ fi # Check for flags with getopts OPTERR=0 -while getopts "sfn" option; do +while getopts "sfnm" option; do # Need to ensure any other long flags do not contain s, n, or f if [[ ! ${#option} -gt "1" ]]; then case ${option,,,} in s) showedits=yes - #echo showedits # debug ;; n) nodbupdate=yes # For future use ;; + m) + m2=no # Don't add M.2 drives to db files + ;; f) - force=yes + force=yes # Disable "support_disk_compatibility" ;; *) ;; @@ -112,96 +123,85 @@ fi # Check script is running as root if [[ $( whoami ) != "root" ]]; then - echo -e "\e[41m ERROR \e[0m This script must be run as root or sudo!" + echo -e "\e[41mERROR\e[0m This script must be run as root or sudo!" exit 1 fi #------------------------------------------------------------------------------ -# Get list of installed SATA, SAS and NVMe drives - -getModel() { - hdmodel=$(smartctl -i "$1" | grep -i "Device Model:" | awk '{print $3 $4 $5}') - if [[ ! $hdmodel ]]; then - hdmodel=$(smartctl -i "$1" | grep -i "Product:" | awk '{print $2 $3 $4}') - fi - #echo "Model: $hdmodel" # debug - - # Brands that return "BRAND " and need "BRAND " removed. - # Smartmontools database in /var/lib/smartmontools/drivedb.db - hdmodel=${hdmodel#"WDC "} # Remove "WDC " from start of model name - hdmodel=${hdmodel#"HGST "} # Remove "HGST " from start of model name - hdmodel=${hdmodel#"TOSHIBA "} # Remove "TOSHIBA " from start of model name - - # Old drive brands - hdmodel=${hdmodel#"Hitachi "} # Remove "Hitachi " from start of model name - hdmodel=${hdmodel#"SAMSUNG "} # Remove "SAMSUNG " from start of model name - hdmodel=${hdmodel#"FUJISTU "} # Remove "FUJISTU " from start of model name - hdmodel=${hdmodel#"APPLE HDD "} # Remove "APPLE HDD " from start of model name - - shopt -s extglob - hdmodel=${hdmodel/#*([[:space:]])} # Remove leading spaces - hdmodel=${hdmodel/%*([[:space:]])} # Remove trailing spaces - shopt -u extglob - #echo "Model: $hdmodel" # debug -} - -getFwVersion() { - tmp=$(hdparm -i "$1" | grep Model) - fwrev=$(printf %s "$tmp" | cut -d"," -f 2 | cut -d"=" -f 2) - #echo "Firmware: $fwrev" # debug -} - -getNVMeModel() { - nvmemodel=$(cat "$1"/model) - shopt -s extglob - nvmemodel=${nvmemodel/#*([[:space:]])} # Remove leading spaces - nvmemodel=${nvmemodel/%*([[:space:]])} # Remove trailing spaces - shopt -u extglob - #echo "NVMe Model: $nvmemodel" # debug -} - -getNVMeFwVersion() { - nvmefw=$(cat "$1"/firmware_rev) - nvmefw=$(echo "$nvmefw" | xargs) # trim leading and trailing white space - #echo "NVMe Firmware: $nvmefw" # debug -} +# Get list of installed SATA, SAS and M.2 NVMe/SATA drives + +#for d in $(ls /sys/block); do +for d in /sys/block/*; do +# if [ ! -e /dev/"$d" ]; then +# echo "Found /dev/$d" # debug +# continue; +# fi + #echo $d # debug + case "$(basename -- "${d}")" in + sd*|hd*) + if [[ $d =~ [hs]d[a-z]$ ]]; then + hdmodel=$(cat "$d/device/model") + hdmodel=$(printf "%s" "$hdmodel" | xargs) # trim leading and trailing white space + #echo "Model: '$hdmodel'" # debug + fwrev=$(cat "$d/device/rev") + fwrev=$(printf "%s" "$fwrev" | xargs) # trim leading and trailing white space + #echo "Firmware: '$fwrev'" # debug -for d in $(cat /proc/partitions | awk '{print $4}'); do - if [ ! -e /dev/"$d" ]; then - continue; - fi - #echo $d # debug - case "$d" in - hd*|sd*) - if [[ $d =~ [hs]d[a-z]{1,2}$ ]]; then - #echo -e "\n$d" # debug - getModel "/dev/$d" - getFwVersion "/dev/$d" if [[ $hdmodel ]] && [[ $fwrev ]]; then - hdparm+=("${hdmodel},${fwrev}") + hdlist+=("${hdmodel},${fwrev}") fi fi ;; - sas*|sata*) + sata*|sas*) if [[ $d =~ (sas|sata)[0-9][0-9]?[0-9]?$ ]]; then - #echo -e "\n$d" # debug - getModel "/dev/$d" - getFwVersion "/dev/$d" + hdmodel=$(cat "$d/device/model") + hdmodel=$(printf "%s" "$hdmodel" | xargs) # trim leading and trailing white space + #echo "Model: '$hdmodel'" # debug + + fwrev=$(cat "$d/device/rev") + fwrev=$(printf "%s" "$fwrev" | xargs) # trim leading and trailing white space + #echo "Firmware: '$fwrev'" # debug + if [[ $hdmodel ]] && [[ $fwrev ]]; then - hdparm+=("${hdmodel},${fwrev}") + hdlist+=("${hdmodel},${fwrev}") fi fi ;; nvme*) if [[ $d =~ nvme[0-9][0-9]?n[0-9][0-9]?$ ]]; then - #echo -e "\n$d" # debug - n=n$(printf "%s" "$d" | cut -d "n" -f 2) - getNVMeModel "/sys/class/nvme/$n" - getNVMeFwVersion "/sys/class/nvme/$n" - if [[ $nvmemodel ]] && [[ $nvmefw ]]; then - nvmelist+=("${nvmemodel},${nvmefw}") + if [[ $m2 != "no" ]]; then + nvmemodel=$(cat "$d/device/model") + nvmemodel=$(printf "%s" "$nvmemodel" | xargs) # trim leading and trailing white space + #echo "NVMe Model: '$nvmemodel'" # debug + + nvmefw=$(cat "$d/device/firmware_rev") + nvmefw=$(printf "%s" "$nvmefw" | xargs) # trim leading and trailing white space + #echo "NVMe Firmware: '$nvmefw'" # debug + + if [[ $nvmemodel ]] && [[ $nvmefw ]]; then + nvmelist+=("${nvmemodel},${nvmefw}") + fi + fi + fi + ;; + nvc*) # M.2 SATA drives (in PCIe card only?) + #if [[ $d =~ nvc[0-9][0-9]?p[0-9][0-9]?$ ]]; then + if [[ $d =~ nvc[0-9][0-9]?$ ]]; then + if [[ $m2 != "no" ]]; then + nvmemodel=$(cat "$d/device/model") + nvmemodel=$(printf "%s" "$nvmemodel" | xargs) # trim leading and trailing white space + #echo "M.2 SATA Model: '$nvmemodel'" # debug + + #nvmefw=$(cat "$d/device/firmware_rev") + nvmefw=$(cat "$d/device/rev") + nvmefw=$(printf "%s" "$nvmefw" | xargs) # trim leading and trailing white space + #echo "M.2 SATA Firmware: '$nvmefw'" # debug + + if [[ $nvmemodel ]] && [[ $nvmefw ]]; then + nvmelist+=("${nvmemodel},${nvmefw}") + fi fi fi ;; @@ -209,16 +209,16 @@ for d in $(cat /proc/partitions | awk '{print $4}'); do done -# Sort hdparm array into new hdds array to remove duplicates -if [[ ${#hdparm[@]} -gt "0" ]]; then +# Sort hdlist array into new hdds array to remove duplicates +if [[ ${#hdlist[@]} -gt "0" ]]; then while IFS= read -r -d '' x; do hdds+=("$x") - done < <(printf "%s\0" "${hdparm[@]}" | sort -uz) + done < <(printf "%s\0" "${hdlist[@]}" | sort -uz) fi # Check hdds array isn't empty if [[ ${#hdds[@]} -eq "0" ]]; then - echo -e "\e[41m ERROR \e[0m No drives found!" && exit 2 + echo -e "\e[41mERROR\e[0m No drives found!" && exit 2 else echo "HDD/SSD models found: ${#hdds[@]}" num="0" @@ -239,9 +239,11 @@ fi # Check nvmes array isn't empty if [[ ${#nvmes[@]} -eq "0" ]]; then - echo -e "No NVMe drives found\n" + if [[ $m2 != "no" ]]; then + echo -e "No M.2 drives found\n" + fi else - echo "NVMe drive models found: ${#nvmes[@]}" + echo "M.2 drive models found: ${#nvmes[@]}" num="0" while [[ $num -lt "${#nvmes[@]}" ]]; do echo "${nvmes[num]}" @@ -257,20 +259,20 @@ fi db1="/var/lib/disk-compatibility/${model}_host${version}.db" db2="/var/lib/disk-compatibility/${model}_host${version}.db.new" -if [[ ! -f "$db1" ]]; then echo -e "\e[41m ERROR \e[0m $db1 not found!" && exit 3; fi -#if [[ ! -f "$db2" ]]; then echo -e "\e[41m ERROR \e[0m $db2 not found!" && exit 4; fi -# new installs don't have a .new file +if [[ ! -f "$db1" ]]; then echo -e "\e[41mERROR\e[0m $db1 not found!" && exit 3; fi +#if [[ ! -f "$db2" ]]; then echo -e "\e[41mERROR\e[0m $db2 not found!" && exit 4; fi +# new installs don't have a .db.new file # Detect drive db type if grep -F '{"disk_compatbility_info":' "$db1" >/dev/null; then - # DSM7 drive db files start with {"disk_compatbility_info": + # DSM 7 drive db files start with {"disk_compatbility_info": dbtype=7 elif grep -F '{"success":1,"list":[' "$db1" >/dev/null; then - # DSM7 drive db files start with {"success":1,"list":[ + # DSM 6 drive db files start with {"success":1,"list":[ dbtype=6 else - echo -e "\e[41m ERROR \e[0m Unknown database type $(basename -- "${db1}")!" + echo -e "\e[41mERROR\e[0m Unknown database type $(basename -- "${db1}")!" exit 7 fi #echo "dbtype: $dbtype" # debug @@ -281,7 +283,7 @@ if [[ ! -f "$db1.bak" ]]; then if cp "$db1" "$db1.bak"; then echo -e "Backed up database to $(basename -- "${db1}").bak\n" else - echo -e "\e[41m ERROR \e[0m Failed to backup $(basename -- "${db1}")!" + echo -e "\e[41mERROR\e[0m Failed to backup $(basename -- "${db1}")!" exit 5 fi fi @@ -294,8 +296,8 @@ Red='\e[0;31m' Off=$'\e[0m' function updatedb() { - hdmodel=$(printf %s "$1" | cut -d"," -f 1) - fwrev=$(printf %s "$1" | cut -d"," -f 2) + hdmodel=$(printf "%s" "$1" | cut -d"," -f 1) + fwrev=$(printf "%s" "$1" | cut -d"," -f 2) #echo arg1 "$1" # debug #echo arg2 "$2" # debug @@ -324,13 +326,15 @@ function updatedb() { db2Edits=$((db2Edits +1)) fi else - echo -e "\n\e[41m ERROR \e[0m Failed to update v7 $(basename -- "$2")${Off}" + echo -e "\n\e[41mERROR\e[0m Failed to update v7 $(basename -- "$2")${Off}" exit 6 fi else # example: # {"model":"WD60EFRX-68MYMN1","firmware":"82.00A82","rec_intvl":[1]}, - string="{\"model\":\"${hdmodel}\",\"firmware\":\"${fwrev}\",\"rec_intvl\":\[1\]}," + # Don't need to add firmware version? + #string="{\"model\":\"${hdmodel}\",\"firmware\":\"${fwrev}\",\"rec_intvl\":\[1\]}," + string="{\"model\":\"${hdmodel}\",\"firmware\":\"\",\"rec_intvl\":\[1\]}," # {"success":1,"list":[ startstring="{\"success\":1,\"list\":\[" @@ -348,7 +352,7 @@ function updatedb() { db2Edits=$((db2Edits +1)) fi else - echo -e "\n\e[41m ERROR \e[0m Failed to update $(basename -- "$2")${Off}" + echo -e "\n\e[41mERROR\e[0m Failed to update $(basename -- "$2")${Off}" exit 8 fi fi @@ -365,7 +369,7 @@ while [[ $num -lt "${#hdds[@]}" ]]; do num=$((num +1)) done -# NVMe drives +# M.2 NVMe/SATA drives num="0" while [[ $num -lt "${#nvmes[@]}" ]]; do updatedb "${nvmes[$num]}" "$db1" @@ -409,7 +413,7 @@ fi if cp "$file" "$file.bak"; then echo "Backed up synoinfo.conf to $(basename -- "${file}").bak" else - echo -e "\e[41m ERROR \e[0m Failed to backup $(basename -- "${file}")!" + echo -e "\e[41mERROR\e[0m Failed to backup $(basename -- "${file}")!" exit 6 fi fi @@ -430,7 +434,7 @@ fi if [[ $url == "127.0.0.1" ]]; then echo "Disabled drive db auto updates." else - echo -e "\e[41m ERROR \e[0m Failed to disable drive db auto updates!" + echo -e "\e[41mERROR\e[0m Failed to disable drive db auto updates!" fi fi fi @@ -445,8 +449,7 @@ if [[ ${showedits,,} == "yes" ]]; then if [[ $db1Edits -gt "0" ]]; then echo -e "\nChanges to ${Cyan}$(basename -- "$db1")${Off}" jq . "$db1" | tail -n "$lines" - fi - if [[ $db2Edits -gt "0" ]]; then + elif [[ $db2Edits -gt "0" ]]; then echo -e "\nChanges to ${Cyan}$(basename -- "$db2")${Off}" jq . "$db2" | tail -n "$lines" fi @@ -456,8 +459,7 @@ if [[ ${showedits,,} == "yes" ]]; then if [[ $db1Edits -gt "0" ]]; then echo -e "\nChanges to ${Cyan}$(basename -- "$db1")${Off}" jq . "$db1" | head -n "$lines" - fi - if [[ $db2Edits -gt "0" ]]; then + elif [[ $db2Edits -gt "0" ]]; then echo -e "\nChanges to ${Cyan}$(basename -- "$db2")${Off}" jq . "$db2" | head -n "$lines" fi @@ -465,7 +467,7 @@ if [[ ${showedits,,} == "yes" ]]; then fi -# Make Synology check disk compatability +# Make Synology check disk compatibility /usr/syno/sbin/synostgdisk --check-all-disks-compatibility status=$? if [[ $status -eq "0" ]]; then From 8407b9818bee08d1f8af207a900a2fa60f05fe46 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 18:30:25 +1100 Subject: [PATCH 26/75] Update syno_hdd_db.sh --- syno_hdd_db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index c8004ba..40fbe6a 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -75,7 +75,7 @@ tag=$(get_latest_release "007revad/Synology_HDD_db") if ! printf "%s\n%s\n" "$tag" "$scriptver" | sort --check --version-sort &> /dev/null ; then echo "There is a newer version of this script available." - echo -e "Current version: ${scriptver}\nLatest version: ${tag:1}" + echo -e "Current version: ${scriptver}\nLatest version: $tag" echo "https://github.com/007revad/Synology_HDD_db/releases/latest" echo "" sleep 10 From 88918e3b81ec5e5df66b6a4f505e93464a6416a6 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 19:58:13 +1100 Subject: [PATCH 27/75] Update CHANGES.txt - Added check that M.2 volume support is enabled --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index e784b34..48d562f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +v1.1.12 +- Added check that M.2 volume support is enabled. + v1.1.11 - Added support for M.2 SATA drives. - Can now skip processing M.2 drives by running script with the -m2 flag. From a35cabad28cd138405b38b59fe2a5d1e3370f5eb Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 19:59:36 +1100 Subject: [PATCH 28/75] Update README.md Checks that M.2 volume support is enabled (on supported models). --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 976da73..36bd422 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ #### What the script does: * Adds any missing drives to the Synology's compatible-drive database. * Prevents DSM auto updating the drive database. * Optionally disable DSM's "support_disk_compatibility". +* Checks that M.2 volume support is enabled (on supported models). * Makes DSM recheck disk compatibility so rebooting is not needed (DSM 7 only). * Reminds you that you may need to reboot the Synology after running the script (DSM 6 only). From e7dc08442b160b2f321d56985acc173f478b8aea Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 20:01:15 +1100 Subject: [PATCH 29/75] Update syno_hdd_db.sh - Added check that M.2 volume support is enabled. --- syno_hdd_db.sh | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 40fbe6a..be81ed3 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -33,6 +33,8 @@ # It's also parsed and checked and probably in some cases it could be more critical to patch that one instead. # DONE +# Added check that M.2 volume support is enabled. +# # Added support for M.2 SATA drives. # # Can now skip processing M.2 drives by running script with the -m2 flag. @@ -61,7 +63,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="1.1.11" +scriptver="1.1.12" # Check latest release with GitHub API get_latest_release() { @@ -74,7 +76,7 @@ tag=$(get_latest_release "007revad/Synology_HDD_db") if ! printf "%s\n%s\n" "$tag" "$scriptver" | sort --check --version-sort &> /dev/null ; then - echo "There is a newer version of this script available." + echo -e "\e[0;36mThere is a newer version of this script available.\e[0m" echo -e "Current version: ${scriptver}\nLatest version: $tag" echo "https://github.com/007revad/Synology_HDD_db/releases/latest" echo "" @@ -131,12 +133,7 @@ fi #------------------------------------------------------------------------------ # Get list of installed SATA, SAS and M.2 NVMe/SATA drives -#for d in $(ls /sys/block); do for d in /sys/block/*; do -# if [ ! -e /dev/"$d" ]; then -# echo "Found /dev/$d" # debug -# continue; -# fi #echo $d # debug case "$(basename -- "${d}")" in sd*|hd*) @@ -404,6 +401,17 @@ else fi +# Check m2 volume support enabled +setting="$(get_key_value /etc.defaults/synoinfo.conf support_m2_pool)" +if [[ $setting == "no" ]]; then + sed -i "s/${sdc}=\"no\"/${sdc}=\"yes\"/" "/etc.defaults/synoinfo.conf" + setting="$(get_key_value /etc.defaults/synoinfo.conf support_m2_pool)" + if [[ $setting == "yes" ]]; then + echo -e "\nEnabled M.2 volume support." + fi +fi + + # Edit synoinfo.conf to prevent DB updates #if [[ $nodbupdate == "yes" ]]; then # For future use file=/etc.defaults/synoinfo.conf From 945ff806f8d655836cb5fe401eabf50eb51f6309 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 20:21:11 +1100 Subject: [PATCH 30/75] Update syno_hdd_db.sh --- syno_hdd_db.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index be81ed3..64e972c 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -63,7 +63,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="1.1.12" +scriptver="v1.1.12" # Check latest release with GitHub API get_latest_release() { @@ -402,10 +402,11 @@ fi # Check m2 volume support enabled -setting="$(get_key_value /etc.defaults/synoinfo.conf support_m2_pool)" +smp=support_m2_pool +setting="$(get_key_value /etc.defaults/synoinfo.conf ${smp})" if [[ $setting == "no" ]]; then - sed -i "s/${sdc}=\"no\"/${sdc}=\"yes\"/" "/etc.defaults/synoinfo.conf" - setting="$(get_key_value /etc.defaults/synoinfo.conf support_m2_pool)" + sed -i "s/${smp}=\"no\"/${smp}=\"yes\"/" "/etc.defaults/synoinfo.conf" + setting="$(get_key_value /etc.defaults/synoinfo.conf ${smp})" if [[ $setting == "yes" ]]; then echo -e "\nEnabled M.2 volume support." fi From b5a274fe3f110321713ad3fc968af9f971f364e0 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 20:41:34 +1100 Subject: [PATCH 31/75] Update syno_hdd_db.sh --- syno_hdd_db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 64e972c..59c8e69 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -63,7 +63,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="v1.1.12" +scriptver="v1.1.13" # Check latest release with GitHub API get_latest_release() { From 4cefdf4d994faa597e09a886fd086c1147ff7664 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 20:43:09 +1100 Subject: [PATCH 32/75] Update syno_hdd_db.sh Minor bug fix --- syno_hdd_db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 59c8e69..ca67a9a 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -63,7 +63,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="v1.1.13" +scriptver="v1.1.14" # Check latest release with GitHub API get_latest_release() { From 93a59b16e9e52d2dda247397ae1f542bbb984884 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 20:44:02 +1100 Subject: [PATCH 33/75] Update CHANGES.txt - Minor bug fix. --- CHANGES.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 48d562f..c2339d3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,9 @@ +v1.1.14 +- Minor bug fix. + +v1.1.13 +- Minor bug fix. + v1.1.12 - Added check that M.2 volume support is enabled. From 23947c761acccc8eb5891f8388d71cdb2c65e846 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 13 Mar 2023 21:07:38 +1100 Subject: [PATCH 34/75] Update CHANGES.txt --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index c2339d3..5c03984 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,7 +2,7 @@ v1.1.14 - Minor bug fix. v1.1.13 -- Minor bug fix. +- Fixed bug in v1.1.12 "check that M.2 volume support is enabled" v1.1.12 - Added check that M.2 volume support is enabled. From a9cb2a14185f6864b454b43a64bd6b0c9a97a75d Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 14 Mar 2023 07:02:21 +1100 Subject: [PATCH 35/75] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 36bd422..edd06c0 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ #### What the script does: * Reminds you that you may need to reboot the Synology after running the script (DSM 6 only). **Planned updates:** -* Bypass unsupported M.2 drives for use as volumes in DSM 7.2 (for models that supported M.2 volumes). +* Allow unsupported M.2 drives for use as volumes in DSM 7.2 (for models that supported M.2 volumes). * Detect any connected expansion units and get the model(s) and edit the correct expansion unit db files. * Or add support for users to specify their expansion unit model(s) as arguments. * Or maybe use the shotgun approach and update all expansion unit db files. From 2876f2234657d1597143f7f7dac03f205f923c8f Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 14 Mar 2023 14:08:08 +1100 Subject: [PATCH 36/75] Add files via upload --- images/how_to_download.png | Bin 0 -> 87899 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/how_to_download.png diff --git a/images/how_to_download.png b/images/how_to_download.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f1510c376efafe8ecf57bac88fcc8cd5d0ddab GIT binary patch literal 87899 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

#|-eL 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 U3wPK$Ya=V$(cZ Date: Tue, 14 Mar 2023 14:18:24 +1100 Subject: [PATCH 37/75] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index edd06c0..dc3afa0 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,10 @@ #### What the script does: * Or add support for users to specify their expansion unit model(s) as arguments. * Or maybe use the shotgun approach and update all expansion unit db files. +### Download the script + +See How to download the script + ### When to run the script You would need to re-run the script after a DSM update. If you have DSM set to auto update the best option is to run the script every time the Synology boots, and the best way to do that is to setup a scheduled task to run the the script at boot-up. From 598b7e1e2a2b661981e692a1aef44ca503725d84 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 14 Mar 2023 14:20:43 +1100 Subject: [PATCH 38/75] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc3afa0..e9a7b3f 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ #### What the script does: ### Download the script -See How to download the script +See How to download the script ### When to run the script From d1988b339571f305c956e19fd04e5ad3f0a6a92c Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 14 Mar 2023 14:27:09 +1100 Subject: [PATCH 39/75] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e9a7b3f..a078a80 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ #### What the script does: ### Download the script -See How to download the script +See How to download the script for the easiest way to download the script. ### When to run the script From a62d0413c1463c5319d9ccf7b20527550c04578f Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 14 Mar 2023 21:24:27 +1100 Subject: [PATCH 40/75] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a078a80..3de6623 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # Synology HDD db ### Description -Add your SATA or SAS HDDs and SSDs plus SATA and NVMe M.2 cache drives to your Synology's compatible drive databases. +Add your SATA or SAS HDDs and SSDs plus SATA and NVMe M.2 drives to your Synology's compatible drive databases. The script works in DSM 7 and DSM 6. From 768ac6e81f7a32dd3bd086bb42616ebdf687da10 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Thu, 16 Mar 2023 06:55:40 +1100 Subject: [PATCH 41/75] Update syno_hdd_db.sh Made drive_db_test_url code more robust --- syno_hdd_db.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index ca67a9a..61d0052 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -430,11 +430,11 @@ fi url=$(get_key_value "$file" drive_db_test_url) # returns a linefeed if key doesn't exist if [[ ! $url ]]; then # Add drive_db_test_url=127.0.0.1 - echo "drive_db_test_url=127.0.0.1" >> "$file" + echo 'drive_db_test_url="127.0.0.1"' >> "$file" disabled="yes" elif [[ $url != "127.0.0.1" ]]; then # Edit drive_db_test_url= - sed -i "s/drive_db_test_url=$url/drive_db_test_url=127.0.0.1/" "$file" + sed -i "s/drive_db_test_url=.*/drive_db_test_url=\"127.0.0.1\"/" "$file" disabled="yes" fi From 0728fae53c1306b074fb91b003820ecd2c3e4c9e Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 17 Mar 2023 19:24:46 +1100 Subject: [PATCH 42/75] Update CHANGES.txt Updated to v1.1.15 --- CHANGES.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 5c03984..20b5d3d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,12 @@ +v1.1.15 +- Added support for M.2 drives on a PCI card (M2Dxx and E10G18-T1 and future models). +- Improved flags/options checking and added usage help. +- Can now download the latest script version for you (if you have user home service enabled in DSM). +- Now adds 'support_m2_pool="yes"' line for models that don't have support_m2_pool in synoinfo.conf + - To (hopefully) prevent losing your SSH created M2 volume when running this script on models that DSM 7.2 Beta does not list as supported for creating M2 volumes. +- Changed Synology model detection to be more reliable (for models that came in different variations). +- Changed checking drive_db_test_url setting to be more durable. + v1.1.14 - Minor bug fix. From e5ca4bb449befdd3cc842e3f4193314614de8817 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 17 Mar 2023 19:25:59 +1100 Subject: [PATCH 43/75] Update syno_hdd_db.sh v1.1.15 - Added support for M.2 drives on a PCI card (M2Dxx and E10G18-T1 and future models). - Improved flags/options checking and added usage help. - Can now download the latest script version for you (if you have user home service enabled in DSM). - Now adds 'support_m2_pool="yes"' line for models that don't have support_m2_pool in synoinfo.conf - To (hopefully) prevent losing your SSH created M2 volume when running this script on models that DSM 7.2 Beta does not list as supported for creating M2 volumes. - Changed Synology model detection to be more reliable (for models that came in different variations). - Changed checking drive_db_test_url setting to be more durable. --- syno_hdd_db.sh | 547 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 384 insertions(+), 163 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 61d0052..a17b6b2 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -23,17 +23,32 @@ #-------------------------------------------------------------------------------------------------- # TODO +# Bypass M.2 volume lock for unsupported M.2 drives. +# # Detect if expansion unit(s) connected and get model(s) and edit expansion unit db files. # Or add support for specifying user's expansion unit model(s) as arguments. # Or maybe use the shotgun approach and update all expansion unit db files. # -# Add support for M.2 SATA and NVMe drives on a M2D17 PCI card. -# -# Maybe also edit the other disk compatibility DB in synoboot, used during boot time. +# Maybe also edit the other disk compatibility db in synoboot, used during boot time. # It's also parsed and checked and probably in some cases it could be more critical to patch that one instead. # DONE -# Added check that M.2 volume support is enabled. +# Added support for M.2 drives on a PCI card (M2Dxx and E10G18-T1 and future models). +# +# Improved flags/options checking and added usage help. +# +# Can now download the latest script version for you (if you have user home service enabled in DSM). +# +# Now adds 'support_m2_pool="yes"' line for models that don't have support_m2_pool in synoinfo.conf +# to (hopefully) prevent losing your SSH created M2 volume when running this script on models +# that DSM 7.2 Beta does not list as supported for creating M2 volumes. +# +# Changed Synology model detection to be more reliable (for models that came in different variations). +# +# Changed checking drive_db_test_url setting to be more durable. +# +# +# Added check that M.2 volume support is enabled (on supported models). # # Added support for M.2 SATA drives. # @@ -63,58 +78,100 @@ # Optionally disable "support_disk_compatibility". -scriptver="v1.1.14" +scriptver="v1.1.15" +script=Synology_HDD_db +repo="007revad/Synology_HDD_db" -# Check latest release with GitHub API -get_latest_release() { - curl --silent "https://api.github.com/repos/$1/releases/latest" | - grep '"tag_name":' | # Get tag line - sed -E 's/.*"([^"]+)".*/\1/' # Pluck JSON value + +# Shell Colors +#Black='\e[0;30m' +Red='\e[0;31m' +#Green='\e[0;32m' +Yellow='\e[0;33m' +#Blue='\e[0;34m' +#Purple='\e[0;35m' +Cyan='\e[0;36m' +#White='\e[0;37m' +Error='\e[41m' +Off='\e[0m' + + +usage(){ + cat < /dev/null ; then - echo -e "\e[0;36mThere is a newer version of this script available.\e[0m" - echo -e "Current version: ${scriptver}\nLatest version: $tag" - echo "https://github.com/007revad/Synology_HDD_db/releases/latest" - echo "" - sleep 10 -fi +scriptversion(){ + cat < /dev/null ; then + echo -e "${Cyan}There is a newer version of this script available.${Off}" + echo -e "Current version: ${scriptver}\nLatest version: $tag" + if [[ ! -d $HOME ]]; then + # Can't download to home + echo "https://github.com/$repo/releases/latest" + sleep 10 + elif [[ -f $HOME/$script-$shorttag.tar.gz ]]; then + # Latest version tar.gz in home but they're using older version + echo "https://github.com/$repo/releases/latest" + sleep 10 + else + echo -e "${Cyan}Do you want to download $tag now?${Off} {y/n]" + read -r -t 30 reply + if [[ ${reply,,} == "y" ]]; then + if ! curl -LJO "https://github.com/$repo/archive/refs/tags/$tag.tar.gz"; then + echo -e "${Error}ERROR ${Off} Failed to download $script-$shorttag.tar.gz!" + else + if [[ -f $HOME/$script-$shorttag.tar.gz ]]; then + if ! tar -xf "$HOME/$script-$shorttag.tar.gz"; then + echo -e "${Error}ERROR ${Off} Failed to extract $script-$shorttag.tar.gz!" + else + if ! rm "$HOME/$script-$shorttag.tar.gz"; then + echo -e "${Error}ERROR ${Off} Failed to delete downloaded $script-$shorttag.tar.gz!" + else + echo -e "\n$tag and changes.txt are in ${Cyan}$shorthome/$script-$shorttag${Off}" + echo -e "${Cyan}Do you want to stop this script so you can run the new one?${Off} {y/n]" + read -r -t 30 reply + if [[ ${reply,,} == "y" ]]; then exit; fi + fi + fi + else + echo -e "${Error}ERROR ${Off} $shorthome/$script-$shorttag.tar.gz not found!" + #ls $HOME/ | grep "$script" # debug + fi + fi + fi + fi fi #------------------------------------------------------------------------------ # Get list of installed SATA, SAS and M.2 NVMe/SATA drives +getdriveinfo() { + # Get drive model and firmware version + hdmodel=$(cat "$1/device/model") + hdmodel=$(printf "%s" "$hdmodel" | xargs) # trim leading and trailing white space + + fwrev=$(cat "$1/device/rev") + fwrev=$(printf "%s" "$fwrev" | xargs) # trim leading and trailing white space + + if [[ $hdmodel ]] && [[ $fwrev ]]; then + hdlist+=("${hdmodel},${fwrev}") + fi +} + +getm2info() { + nvmemodel=$(cat "$1/device/model") + nvmemodel=$(printf "%s" "$nvmemodel" | xargs) # trim leading and trailing white space + if [[ $2 == "nvme" ]]; then + nvmefw=$(cat "$1/device/firmware_rev") + elif [[ $2 == "nvc" ]]; then + nvmefw=$(cat "$1/device/rev") + fi + nvmefw=$(printf "%s" "$nvmefw" | xargs) # trim leading and trailing white space + + if [[ $nvmemodel ]] && [[ $nvmefw ]]; then + nvmelist+=("${nvmemodel},${nvmefw}") + fi +} + +getcardmodel() { + # Get M.2 card model + cardmodel=$(synodisk --m2-card-model-get "$1") + if [[ $cardmodel =~ M2D[0-9][0-9] ]]; then + # M2 adaptor card + m2carddblist+=("${model}_${cardmodel,,}${version}.db") # M.2 card's db file + m2cardlist+=("$cardmodel") # M.2 card + elif [[ $cardmodel =~ E[0-9][0-9]+M.+ ]]; then + # Ethernet + M2 adaptor card + m2carddblist+=("${model}_${cardmodel,,}${version}.db") # M.2 card's db file + m2cardlist+=("$cardmodel") # M.2 card + fi +} + + for d in /sys/block/*; do - #echo $d # debug case "$(basename -- "${d}")" in sd*|hd*) - if [[ $d =~ [hs]d[a-z]$ ]]; then - hdmodel=$(cat "$d/device/model") - hdmodel=$(printf "%s" "$hdmodel" | xargs) # trim leading and trailing white space - #echo "Model: '$hdmodel'" # debug - - fwrev=$(cat "$d/device/rev") - fwrev=$(printf "%s" "$fwrev" | xargs) # trim leading and trailing white space - #echo "Firmware: '$fwrev'" # debug - - if [[ $hdmodel ]] && [[ $fwrev ]]; then - hdlist+=("${hdmodel},${fwrev}") - fi + if [[ $d =~ [hs]d[a-z][a-z]?$ ]]; then + # Get drive model and firmware version + getdriveinfo "$d" fi ;; sata*|sas*) if [[ $d =~ (sas|sata)[0-9][0-9]?[0-9]?$ ]]; then - hdmodel=$(cat "$d/device/model") - hdmodel=$(printf "%s" "$hdmodel" | xargs) # trim leading and trailing white space - #echo "Model: '$hdmodel'" # debug - - fwrev=$(cat "$d/device/rev") - fwrev=$(printf "%s" "$fwrev" | xargs) # trim leading and trailing white space - #echo "Firmware: '$fwrev'" # debug - - if [[ $hdmodel ]] && [[ $fwrev ]]; then - hdlist+=("${hdmodel},${fwrev}") - fi + # Get drive model and firmware version + getdriveinfo "$d" fi ;; nvme*) if [[ $d =~ nvme[0-9][0-9]?n[0-9][0-9]?$ ]]; then if [[ $m2 != "no" ]]; then - nvmemodel=$(cat "$d/device/model") - nvmemodel=$(printf "%s" "$nvmemodel" | xargs) # trim leading and trailing white space - #echo "NVMe Model: '$nvmemodel'" # debug - - nvmefw=$(cat "$d/device/firmware_rev") - nvmefw=$(printf "%s" "$nvmefw" | xargs) # trim leading and trailing white space - #echo "NVMe Firmware: '$nvmefw'" # debug - - if [[ $nvmemodel ]] && [[ $nvmefw ]]; then - nvmelist+=("${nvmemodel},${nvmefw}") - fi + getm2info "$d" "nvme" + # Get M.2 card model if in M.2 card + getcardmodel "/dev/$d" fi fi ;; @@ -187,18 +332,9 @@ for d in /sys/block/*; do #if [[ $d =~ nvc[0-9][0-9]?p[0-9][0-9]?$ ]]; then if [[ $d =~ nvc[0-9][0-9]?$ ]]; then if [[ $m2 != "no" ]]; then - nvmemodel=$(cat "$d/device/model") - nvmemodel=$(printf "%s" "$nvmemodel" | xargs) # trim leading and trailing white space - #echo "M.2 SATA Model: '$nvmemodel'" # debug - - #nvmefw=$(cat "$d/device/firmware_rev") - nvmefw=$(cat "$d/device/rev") - nvmefw=$(printf "%s" "$nvmefw" | xargs) # trim leading and trailing white space - #echo "M.2 SATA Firmware: '$nvmefw'" # debug - - if [[ $nvmemodel ]] && [[ $nvmefw ]]; then - nvmelist+=("${nvmemodel},${nvmefw}") - fi + getm2info "$d" "nvc" + # Get M.2 card model if in M.2 card + getcardmodel "/dev/$d" fi fi ;; @@ -206,16 +342,25 @@ for d in /sys/block/*; do done +sortarray(){ + # Sort $1 array into new $2 array to remove duplicates + local -n inarray=$1 + outarray=() + if [[ ${#inarray[@]} -gt "0" ]]; then + while IFS= read -r -d '' x; do + outarray+=("$x") + done < <(printf "%s\0" "${inarray[@]}" | sort -uz) + fi +} + + # Sort hdlist array into new hdds array to remove duplicates -if [[ ${#hdlist[@]} -gt "0" ]]; then - while IFS= read -r -d '' x; do - hdds+=("$x") - done < <(printf "%s\0" "${hdlist[@]}" | sort -uz) -fi +sortarray "hdlist" +hdds=${outarray[*]} # Check hdds array isn't empty if [[ ${#hdds[@]} -eq "0" ]]; then - echo -e "\e[41mERROR\e[0m No drives found!" && exit 2 + echo -e "${Error}ERROR${Off} No drives found!" && exit 2 else echo "HDD/SSD models found: ${#hdds[@]}" num="0" @@ -228,11 +373,8 @@ fi # Sort nvmelist array into new nvmes array to remove duplicates -if [[ ${#nvmelist[@]} -gt "0" ]]; then - while IFS= read -r -d '' x; do - nvmes+=("$x") - done < <(printf "%s\0" "${nvmelist[@]}" | sort -uz) -fi +sortarray "nvmelist" +nvmes=${outarray[*]} # Check nvmes array isn't empty if [[ ${#nvmes[@]} -eq "0" ]]; then @@ -250,14 +392,40 @@ else fi +# M.2 card db files +# Sort m2carddblist array into new m2carddbs array to remove duplicates +sortarray "m2carddblist" +m2carddbs=${outarray[*]} + +# M.2 cards +# Sort m2cardlist array into new m2cards array to remove duplicates +sortarray "m2cardlist" +m2cards=${outarray[*]} + +# Check m2cards array isn't empty +if [[ ${#m2cards[@]} -gt "0" ]]; then + echo "M.2 card models found: ${#m2cards[@]}" + num="0" + while [[ $num -lt "${#m2cards[@]}" ]]; do + echo "${m2cards[num]}" + num=$((num +1)) + done + echo +fi + + #------------------------------------------------------------------------------ -# Check database and add our drives if needed +# Check databases and add our drives if needed db1="/var/lib/disk-compatibility/${model}_host${version}.db" db2="/var/lib/disk-compatibility/${model}_host${version}.db.new" +dbpath="/var/lib/disk-compatibility/" -if [[ ! -f "$db1" ]]; then echo -e "\e[41mERROR\e[0m $db1 not found!" && exit 3; fi -#if [[ ! -f "$db2" ]]; then echo -e "\e[41mERROR\e[0m $db2 not found!" && exit 4; fi +synoinfo="/etc.defaults/synoinfo.conf" + + +if [[ ! -f "$db1" ]]; then echo -e "${Error}ERROR 3${Off} $db1 not found!" && exit 3; fi +#if [[ ! -f "$db2" ]]; then echo -e "${Error}ERROR 4${Off} $db2 not found!" && exit 4; fi # new installs don't have a .db.new file @@ -269,30 +437,36 @@ elif grep -F '{"success":1,"list":[' "$db1" >/dev/null; then # DSM 6 drive db files start with {"success":1,"list":[ dbtype=6 else - echo -e "\e[41mERROR\e[0m Unknown database type $(basename -- "${db1}")!" + echo -e "${Error}ERROR${Off} Unknown database type $(basename -- "${db1}")!" exit 7 fi #echo "dbtype: $dbtype" # debug -# Backup database file if needed -if [[ ! -f "$db1.bak" ]]; then - if cp "$db1" "$db1.bak"; then - echo -e "Backed up database to $(basename -- "${db1}").bak\n" - else - echo -e "\e[41mERROR\e[0m Failed to backup $(basename -- "${db1}")!" - exit 5 +backupdb() { + # Backup database file if needed + if [[ ! -f "$1.bak" ]]; then + if cp "$1" "$1.bak"; then + echo -e "\nBacked up $(basename -- "${1}") database.\n" + else + echo -e "${Error}ERROR 5${Off} Failed to backup $(basename -- "${1}")!" + return 1 + fi fi -fi +} -# Shell Colors -Yellow='\e[0;33m' -Cyan='\e[0;36m' -Red='\e[0;31m' -Off=$'\e[0m' +# Backup host database file if needed +backupdb "$db1" || exit 5 + +# Backup synoinfo.conf if needed +backupdb "$synoinfo" || exit 9 + + +#------------------------------------------------------------------------------ +# Edit db files -function updatedb() { +updatedb() { hdmodel=$(printf "%s" "$1" | cut -d"," -f 1) fwrev=$(printf "%s" "$1" | cut -d"," -f 2) @@ -317,13 +491,16 @@ function updatedb() { #if sed -i "s/}}}/}},\"$hdmodel\":{$fwstrng$default/" "$2"; then # Don't need to add firmware version? if sed -i "s/}}}/}},\"$hdmodel\":{$default/" "$2"; then echo -e "Added ${Yellow}$hdmodel${Off} to ${Cyan}$(basename -- "$2")${Off}" + + # Count drives added to host db files if [[ $2 == "$db1" ]]; then db1Edits=$((db1Edits +1)) elif [[ $2 == "$db2" ]]; then db2Edits=$((db2Edits +1)) fi + else - echo -e "\n\e[41mERROR\e[0m Failed to update v7 $(basename -- "$2")${Off}" + echo -e "\n${Error}ERROR 6${Off} Failed to update v7 $(basename -- "$2")${Off}" exit 6 fi else @@ -343,13 +520,16 @@ function updatedb() { # {"success":1,"list":[{"model":"WD60EFRX-68MYMN1","firmware":"82.00A82","rec_intvl":[1]}, if sed -ir "s/$startstring/$startstring$string/" "$2"; then echo -e "Added ${Yellow}$hdmodel${Off} to ${Cyan}$(basename -- "$2")${Off}" + + # Count drives added to host db files if [[ $2 == "$db1" ]]; then db1Edits=$((db1Edits +1)) elif [[ $2 == "$db2" ]]; then db2Edits=$((db2Edits +1)) fi + else - echo -e "\n\e[41mERROR\e[0m Failed to update $(basename -- "$2")${Off}" + echo -e "\n${Error}ERROR 8${Off} Failed to update $(basename -- "$2")${Off}" exit 8 fi fi @@ -373,18 +553,36 @@ while [[ $num -lt "${#nvmes[@]}" ]]; do if [[ -f "$db2" ]]; then updatedb "${nvmes[$num]}" "$db2" fi + + #------------------------------------------------ + # M.2 adaptor cards + num2="0" + while [[ $num2 -lt "${#m2carddbs[@]}" ]]; do + if [[ -f "${dbpath}${m2carddbs[$num2]}" ]];then + backupdb "${dbpath}${m2carddbs[$num2]}" &&\ + updatedb "${nvmes[$num]}" "${dbpath}${m2carddbs[$num2]}" + else + echo -e "${Error}ERROR 10${Off} ${m2carddbs[$num2]} not found!" + fi + num2=$((num2 +1)) + done + #------------------------------------------------ + num=$((num +1)) done +#------------------------------------------------------------------------------ +# Edit /etc.defaults/synoinfo.conf + # Optionally disable "support_disk_compatibility" sdc=support_disk_compatibility -setting="$(get_key_value /etc.defaults/synoinfo.conf $sdc)" +setting="$(get_key_value $synoinfo $sdc)" if [[ $force == "yes" ]]; then if [[ $setting == "yes" ]]; then # Disable support_disk_compatibility - sed -i "s/${sdc}=\"yes\"/${sdc}=\"no\"/" "/etc.defaults/synoinfo.conf" - setting="$(get_key_value /etc.defaults/synoinfo.conf $sdc)" + sed -i "s/${sdc}=\"yes\"/${sdc}=\"no\"/" "$synoinfo" + setting="$(get_key_value "$synoinfo" $sdc)" if [[ $setting == "no" ]]; then echo -e "\nDisabled support disk compatibility." fi @@ -392,8 +590,8 @@ if [[ $force == "yes" ]]; then else if [[ $setting == "no" ]]; then # Enable support_disk_compatibility - sed -i "s/${sdc}=\"no\"/${sdc}=\"yes\"/" "/etc.defaults/synoinfo.conf" - setting="$(get_key_value /etc.defaults/synoinfo.conf $sdc)" + sed -i "s/${sdc}=\"no\"/${sdc}=\"yes\"/" "$synoinfo" + setting="$(get_key_value "$synoinfo" $sdc)" if [[ $setting == "yes" ]]; then echo -e "\nRe-enabled support disk compatibility." fi @@ -403,53 +601,76 @@ fi # Check m2 volume support enabled smp=support_m2_pool -setting="$(get_key_value /etc.defaults/synoinfo.conf ${smp})" -if [[ $setting == "no" ]]; then - sed -i "s/${smp}=\"no\"/${smp}=\"yes\"/" "/etc.defaults/synoinfo.conf" - setting="$(get_key_value /etc.defaults/synoinfo.conf ${smp})" +setting="$(get_key_value $synoinfo ${smp})" +enabled="" +if [[ ! $setting ]]; then + # Add support_m2_pool"yes" + echo 'support_m2_pool="yes"' >> "$synoinfo" + enabled="yes" +elif [[ $setting == "no" ]]; then + # Change support_m2_pool"no" to "yes" + sed -i "s/${smp}=\"no\"/${smp}=\"yes\"/" "$synoinfo" + enabled="yes" +elif [[ $setting == "yes" ]]; then + echo -e "\nM.2 volume support already enabled." +fi + +# Check if we enabled m2 volume support +setting="$(get_key_value $synoinfo ${smp})" +if [[ $enabled == "yes" ]]; then if [[ $setting == "yes" ]]; then echo -e "\nEnabled M.2 volume support." + else + echo -e "${Error}ERROR${Off} Failed to enable m2 volume support!" fi fi -# Edit synoinfo.conf to prevent DB updates -#if [[ $nodbupdate == "yes" ]]; then # For future use - file=/etc.defaults/synoinfo.conf - if [[ -f $file ]]; then - # Backup synoinfo.conf if needed - if [[ ! -f "$file.bak" ]]; then - if cp "$file" "$file.bak"; then - echo "Backed up synoinfo.conf to $(basename -- "${file}").bak" - else - echo -e "\e[41mERROR\e[0m Failed to backup $(basename -- "${file}")!" - exit 6 - fi - fi +# Edit synoinfo.conf to prevent drive db updates +dtu=drive_db_test_url +url="$(get_key_value $synoinfo ${dtu})" +disabled="" +if [[ $nodbupdate == "yes" ]]; then + if [[ ! $url ]]; then + # Add drive_db_test_url="127.0.0.1" + echo 'drive_db_test_url="127.0.0.1"' >> "$synoinfo" + disabled="yes" + elif [[ $url != "127.0.0.1" ]]; then + # Edit drive_db_test_url= + sed -i "s/drive_db_test_url=.*/drive_db_test_url=\"127.0.0.1\"/" "$synoinfo" >/dev/null + disabled="yes" + fi - url=$(get_key_value "$file" drive_db_test_url) # returns a linefeed if key doesn't exist - if [[ ! $url ]]; then - # Add drive_db_test_url=127.0.0.1 - echo 'drive_db_test_url="127.0.0.1"' >> "$file" - disabled="yes" - elif [[ $url != "127.0.0.1" ]]; then - # Edit drive_db_test_url= - sed -i "s/drive_db_test_url=.*/drive_db_test_url=\"127.0.0.1\"/" "$file" - disabled="yes" + # Check if we disabled drive db auto updates + url="$(get_key_value $synoinfo drive_db_test_url)" + if [[ $disabled == "yes" ]]; then + if [[ $url == "127.0.0.1" ]]; then + echo -e "\nDisabled drive db auto updates." + else + echo -e "${Error}ERROR${Off} Failed to disable drive db auto updates!" fi - - url=$(get_key_value "$file" drive_db_test_url) - if [[ $disabled == "yes" ]]; then - if [[ $url == "127.0.0.1" ]]; then - echo "Disabled drive db auto updates." - else - echo -e "\e[41mERROR\e[0m Failed to disable drive db auto updates!" - fi + fi +else + # Re-enable drive db updates + if [[ $url == "127.0.0.1" ]]; then + # Edit drive_db_test_url= + sed -z "s/drive_db_test_url=\"127\.0\.0\.1\"\n//" "$synoinfo" >/dev/null + #sed -i "s/drive_db_test_url=\"127\.0\.0\.1\"//" "$synoinfo" # works but leaves line feed + + # Check if we re-enabled drive db auto updates + url="$(get_key_value $synoinfo drive_db_test_url)" + if [[ $url != "127.0.0.1" ]]; then + echo -e "\nRe-enabled drive db auto updates." fi + else + echo -e "\nDrive db auto updates already enabled." fi -#fi +fi +#------------------------------------------------------------------------------ +# Finished + # Show the changes if [[ ${showedits,,} == "yes" ]]; then if [[ $dbtype -gt "6" ]];then From 0cca7b862098190062ee0dc028de849fcdd25ebd Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 17 Mar 2023 22:25:51 +1100 Subject: [PATCH 44/75] Update syno_hdd_db.sh - Fixed bug where removable drives were being detected and added to drive database. --- syno_hdd_db.sh | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index a17b6b2..95686a1 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -47,6 +47,8 @@ # # Changed checking drive_db_test_url setting to be more durable. # +# Fixed bug where removable drives were being detected and added to drive database. +# # # Added check that M.2 volume support is enabled (on supported models). # @@ -263,15 +265,19 @@ fi # Get list of installed SATA, SAS and M.2 NVMe/SATA drives getdriveinfo() { - # Get drive model and firmware version - hdmodel=$(cat "$1/device/model") - hdmodel=$(printf "%s" "$hdmodel" | xargs) # trim leading and trailing white space - - fwrev=$(cat "$1/device/rev") - fwrev=$(printf "%s" "$fwrev" | xargs) # trim leading and trailing white space - - if [[ $hdmodel ]] && [[ $fwrev ]]; then - hdlist+=("${hdmodel},${fwrev}") + # Skip removable drives (USB drives) + removable=$(cat "$1/removable") + if [[ $removable == "0" ]]; then + # Get drive model and firmware version + hdmodel=$(cat "$1/device/model") + hdmodel=$(printf "%s" "$hdmodel" | xargs) # trim leading and trailing white space + + fwrev=$(cat "$1/device/rev") + fwrev=$(printf "%s" "$fwrev" | xargs) # trim leading and trailing white space + + if [[ $hdmodel ]] && [[ $fwrev ]]; then + hdlist+=("${hdmodel},${fwrev}") + fi fi } From 1543e2723d868a0c5817d4ae050ba586a37760b8 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Fri, 17 Mar 2023 22:26:34 +1100 Subject: [PATCH 45/75] Update CHANGES.txt - Fixed bug where removable drives were being detected and added to drive database. --- CHANGES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.txt b/CHANGES.txt index 20b5d3d..db525a1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -6,6 +6,7 @@ v1.1.15 - To (hopefully) prevent losing your SSH created M2 volume when running this script on models that DSM 7.2 Beta does not list as supported for creating M2 volumes. - Changed Synology model detection to be more reliable (for models that came in different variations). - Changed checking drive_db_test_url setting to be more durable. +- Fixed bug where removable drives were being detected and added to drive database. v1.1.14 - Minor bug fix. From 7c37061e4d412df865df538a30eb70bef9b233ef Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sat, 18 Mar 2023 11:07:08 +1100 Subject: [PATCH 46/75] Update syno_hdd_db.sh --- syno_hdd_db.sh | 63 ++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 95686a1..c523e09 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -84,6 +84,7 @@ scriptver="v1.1.15" script=Synology_HDD_db repo="007revad/Synology_HDD_db" +#echo -e "bash version: $(bash --version | head -1 | cut -d' ' -f4)\n" # debug # Shell Colors #Black='\e[0;30m' @@ -297,16 +298,18 @@ getm2info() { } getcardmodel() { - # Get M.2 card model - cardmodel=$(synodisk --m2-card-model-get "$1") - if [[ $cardmodel =~ M2D[0-9][0-9] ]]; then - # M2 adaptor card - m2carddblist+=("${model}_${cardmodel,,}${version}.db") # M.2 card's db file - m2cardlist+=("$cardmodel") # M.2 card - elif [[ $cardmodel =~ E[0-9][0-9]+M.+ ]]; then - # Ethernet + M2 adaptor card - m2carddblist+=("${model}_${cardmodel,,}${version}.db") # M.2 card's db file - m2cardlist+=("$cardmodel") # M.2 card + # Get M.2 card model (if M.2 drives found) + if [[ ${#nvmelist[@]} -gt "0" ]]; then + cardmodel=$(synodisk --m2-card-model-get "$1") + if [[ $cardmodel =~ M2D[0-9][0-9] ]]; then + # M2 adaptor card + m2carddblist+=("${model}_${cardmodel,,}${version}.db") # M.2 card's db file + m2cardlist+=("$cardmodel") # M.2 card + elif [[ $cardmodel =~ E[0-9][0-9]+M.+ ]]; then + # Ethernet + M2 adaptor card + m2carddblist+=("${model}_${cardmodel,,}${version}.db") # M.2 card's db file + m2cardlist+=("$cardmodel") # M.2 card + fi fi } @@ -348,21 +351,12 @@ for d in /sys/block/*; do done -sortarray(){ - # Sort $1 array into new $2 array to remove duplicates - local -n inarray=$1 - outarray=() - if [[ ${#inarray[@]} -gt "0" ]]; then - while IFS= read -r -d '' x; do - outarray+=("$x") - done < <(printf "%s\0" "${inarray[@]}" | sort -uz) - fi -} - - # Sort hdlist array into new hdds array to remove duplicates -sortarray "hdlist" -hdds=${outarray[*]} +if [[ ${#hdlist[@]} -gt "0" ]]; then + while IFS= read -r -d '' x; do + hdds+=("$x") + done < <(printf "%s\0" "${hdlist[@]}" | sort -uz) +fi # Check hdds array isn't empty if [[ ${#hdds[@]} -eq "0" ]]; then @@ -379,8 +373,11 @@ fi # Sort nvmelist array into new nvmes array to remove duplicates -sortarray "nvmelist" -nvmes=${outarray[*]} +if [[ ${#nvmelist[@]} -gt "0" ]]; then + while IFS= read -r -d '' x; do + nvmes+=("$x") + done < <(printf "%s\0" "${nvmelist[@]}" | sort -uz) +fi # Check nvmes array isn't empty if [[ ${#nvmes[@]} -eq "0" ]]; then @@ -400,13 +397,19 @@ fi # M.2 card db files # Sort m2carddblist array into new m2carddbs array to remove duplicates -sortarray "m2carddblist" -m2carddbs=${outarray[*]} +if [[ ${#m2carddblist[@]} -gt "0" ]]; then + while IFS= read -r -d '' x; do + m2carddbs+=("$x") + done < <(printf "%s\0" "${m2carddblist[@]}" | sort -uz) +fi # M.2 cards # Sort m2cardlist array into new m2cards array to remove duplicates -sortarray "m2cardlist" -m2cards=${outarray[*]} +if [[ ${#m2cardlist[@]} -gt "0" ]]; then + while IFS= read -r -d '' x; do + m2cards+=("$x") + done < <(printf "%s\0" "${m2cardlist[@]}" | sort -uz) +fi # Check m2cards array isn't empty if [[ ${#m2cards[@]} -gt "0" ]]; then From 24d971a12be8d234c9c0216a1a6bd2eea3741e6e Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sat, 18 Mar 2023 11:14:35 +1100 Subject: [PATCH 47/75] Update CHANGES.txt --- CHANGES.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index db525a1..d6e94e9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,12 +1,12 @@ v1.1.15 - Added support for M.2 drives on a PCI card (M2Dxx and E10G18-T1 and future models). -- Improved flags/options checking and added usage help. -- Can now download the latest script version for you (if you have user home service enabled in DSM). +- Improved flags/options checking and added usage help (-h or --help) and version info (-v or --version). +- Can now download the latest script version for you (if you have 'user home service' enabled in DSM). - Now adds 'support_m2_pool="yes"' line for models that don't have support_m2_pool in synoinfo.conf - To (hopefully) prevent losing your SSH created M2 volume when running this script on models that DSM 7.2 Beta does not list as supported for creating M2 volumes. -- Changed Synology model detection to be more reliable (for models that came in different variations). +- Changed Synology NAS model detection to be more reliable (for models that came in different variations and report extra text after model). - Changed checking drive_db_test_url setting to be more durable. -- Fixed bug where removable drives were being detected and added to drive database. +- Fixed bug where removable drives were being added to the drive database. v1.1.14 - Minor bug fix. From 3e0ed022b8e6b25ce596fec0d2eb7f78bf2997e4 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sat, 18 Mar 2023 11:43:06 +1100 Subject: [PATCH 48/75] Update CHANGES.txt --- CHANGES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.txt b/CHANGES.txt index d6e94e9..0858283 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,6 +7,7 @@ v1.1.15 - Changed Synology NAS model detection to be more reliable (for models that came in different variations and report extra text after model). - Changed checking drive_db_test_url setting to be more durable. - Fixed bug where removable drives were being added to the drive database. +- Fixed bug where "M.2 volume support already enabled" message appeared when NAS had no M.2 drives. v1.1.14 - Minor bug fix. From 85479bc766d6eda67da4d01336a7a063260cf260 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sat, 18 Mar 2023 11:45:37 +1100 Subject: [PATCH 49/75] Update syno_hdd_db.sh Fixed bug where "M.2 volume support already enabled" message appeared when NAS had no M.2 drives. --- syno_hdd_db.sh | 72 ++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index c523e09..f18e97f 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -49,6 +49,8 @@ # # Fixed bug where removable drives were being detected and added to drive database. # +# Fixed bug where "M.2 volume support already enabled" message appeared when NAS had no M.2 drives. +# # # Added check that M.2 volume support is enabled (on supported models). # @@ -380,18 +382,19 @@ if [[ ${#nvmelist[@]} -gt "0" ]]; then fi # Check nvmes array isn't empty -if [[ ${#nvmes[@]} -eq "0" ]]; then - if [[ $m2 != "no" ]]; then +if [[ $m2 != "no" ]]; then + if [[ ${#nvmes[@]} -eq "0" ]]; then echo -e "No M.2 drives found\n" + else + m2exists="yes" + echo "M.2 drive models found: ${#nvmes[@]}" + num="0" + while [[ $num -lt "${#nvmes[@]}" ]]; do + echo "${nvmes[num]}" + num=$((num +1)) + done + echo fi -else - echo "M.2 drive models found: ${#nvmes[@]}" - num="0" - while [[ $num -lt "${#nvmes[@]}" ]]; do - echo "${nvmes[num]}" - num=$((num +1)) - done - echo fi @@ -608,29 +611,34 @@ else fi -# Check m2 volume support enabled -smp=support_m2_pool -setting="$(get_key_value $synoinfo ${smp})" -enabled="" -if [[ ! $setting ]]; then - # Add support_m2_pool"yes" - echo 'support_m2_pool="yes"' >> "$synoinfo" - enabled="yes" -elif [[ $setting == "no" ]]; then - # Change support_m2_pool"no" to "yes" - sed -i "s/${smp}=\"no\"/${smp}=\"yes\"/" "$synoinfo" - enabled="yes" -elif [[ $setting == "yes" ]]; then - echo -e "\nM.2 volume support already enabled." -fi +# Enable m2 volume support +if [[ $m2 != "no" ]]; then + if [[ $m2exists == "yes" ]]; then + # Check if m2 volume support is enabled + smp=support_m2_pool + setting="$(get_key_value $synoinfo ${smp})" + enabled="" + if [[ ! $setting ]]; then + # Add support_m2_pool"yes" + echo 'support_m2_pool="yes"' >> "$synoinfo" + enabled="yes" + elif [[ $setting == "no" ]]; then + # Change support_m2_pool"no" to "yes" + sed -i "s/${smp}=\"no\"/${smp}=\"yes\"/" "$synoinfo" + enabled="yes" + elif [[ $setting == "yes" ]]; then + echo -e "\nM.2 volume support already enabled." + fi -# Check if we enabled m2 volume support -setting="$(get_key_value $synoinfo ${smp})" -if [[ $enabled == "yes" ]]; then - if [[ $setting == "yes" ]]; then - echo -e "\nEnabled M.2 volume support." - else - echo -e "${Error}ERROR${Off} Failed to enable m2 volume support!" + # Check if we enabled m2 volume support + setting="$(get_key_value $synoinfo ${smp})" + if [[ $enabled == "yes" ]]; then + if [[ $setting == "yes" ]]; then + echo -e "\nEnabled M.2 volume support." + else + echo -e "${Error}ERROR${Off} Failed to enable m2 volume support!" + fi + fi fi fi From 6a2ae6c3c2b0a1290b97cb584f7548966c9d9547 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sat, 18 Mar 2023 21:28:02 +1100 Subject: [PATCH 50/75] Update CHANGES.txt --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 0858283..1decd2d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,7 +4,7 @@ v1.1.15 - Can now download the latest script version for you (if you have 'user home service' enabled in DSM). - Now adds 'support_m2_pool="yes"' line for models that don't have support_m2_pool in synoinfo.conf - To (hopefully) prevent losing your SSH created M2 volume when running this script on models that DSM 7.2 Beta does not list as supported for creating M2 volumes. -- Changed Synology NAS model detection to be more reliable (for models that came in different variations and report extra text after model). +- Changed Synology NAS model detection to be more reliable (for models that came in different variations and report extra text after model). issue # and issue #10 - Changed checking drive_db_test_url setting to be more durable. - Fixed bug where removable drives were being added to the drive database. - Fixed bug where "M.2 volume support already enabled" message appeared when NAS had no M.2 drives. From 64811801e179098fbaa7b04ff0650a693ae0751c Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sat, 18 Mar 2023 21:28:20 +1100 Subject: [PATCH 51/75] Update CHANGES.txt --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 1decd2d..989c6f7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,7 +4,7 @@ v1.1.15 - Can now download the latest script version for you (if you have 'user home service' enabled in DSM). - Now adds 'support_m2_pool="yes"' line for models that don't have support_m2_pool in synoinfo.conf - To (hopefully) prevent losing your SSH created M2 volume when running this script on models that DSM 7.2 Beta does not list as supported for creating M2 volumes. -- Changed Synology NAS model detection to be more reliable (for models that came in different variations and report extra text after model). issue # and issue #10 +- Changed Synology NAS model detection to be more reliable (for models that came in different variations and report extra text after model). issue #2 and issue #10 - Changed checking drive_db_test_url setting to be more durable. - Fixed bug where removable drives were being added to the drive database. - Fixed bug where "M.2 volume support already enabled" message appeared when NAS had no M.2 drives. From 3a01ba75babc811abd5b25f10204570515a18cc9 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sun, 19 Mar 2023 06:42:37 +1100 Subject: [PATCH 52/75] Update CHANGES.txt --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 989c6f7..5b30bd4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,5 @@ v1.1.15 -- Added support for M.2 drives on a PCI card (M2Dxx and E10G18-T1 and future models). +- Added support for M.2 drives on a PCI card (M2Dxx and E10M20-T1 and future models). - Improved flags/options checking and added usage help (-h or --help) and version info (-v or --version). - Can now download the latest script version for you (if you have 'user home service' enabled in DSM). - Now adds 'support_m2_pool="yes"' line for models that don't have support_m2_pool in synoinfo.conf From 0cb23f8279f5b8b109c6f3a7e4b92a752898e11d Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sun, 19 Mar 2023 06:43:54 +1100 Subject: [PATCH 53/75] Update syno_hdd_db.sh --- syno_hdd_db.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index f18e97f..fbec9d7 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -3,7 +3,7 @@ #-------------------------------------------------------------------------------------------------- # Github: https://github.com/007revad/Synology_HDD_db # Script verified at https://www.shellcheck.net/ -# Tested on DSM 7.1.1 and DSM 6.2.4 +# Tested on DSM 7.2 beta, 7.1.1 and DSM 6.2.4 # # Easiest solution: # Edit /etc.defaults/synoinfo.conf and change support_disk_compatibility="yes" to "no" and reboot. @@ -33,7 +33,7 @@ # It's also parsed and checked and probably in some cases it could be more critical to patch that one instead. # DONE -# Added support for M.2 drives on a PCI card (M2Dxx and E10G18-T1 and future models). +# Added support for M.2 drives on a PCI card (M2Dxx and E10M20-T1 and future models). # # Improved flags/options checking and added usage help. # From f2df7109e164f6a76df3737aa6c281d02553d0bc Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Sun, 19 Mar 2023 18:44:32 +1100 Subject: [PATCH 54/75] Update syno_hdd_db.sh Changed model detection method, again. --- syno_hdd_db.sh | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index fbec9d7..baff3e8 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -185,23 +185,9 @@ if [[ $dsm -gt "6" ]]; then version="_v$dsm" fi -# Get Synology model -model=$(cat /proc/sys/kernel/syno_hw_version) # not always the actual model number - -modeltype=$(printf "%s" "$model" | sed 's/[0-9].*//') # DS, RS etc - -unique=$(get_key_value /etc/synoinfo.conf unique | cut -d'_' -f3) # 920+ etc - -# Remove extra text from end, like DS213pv10-j and DS1817+-j -#[[ $model =~ ([0-9]{3,}) ]] && modelnum=${BASH_REMATCH[1]} -[[ $model =~ ([0-9]{3,}(RP\+|RPxs|RP|\+II|xsII|xs\+|xs|\+|j|slim|play|se|air|D)?) ]] &&\ - modelnum=${BASH_REMATCH[1]} - -if [[ $modelnum != "$unique" ]]; then - model="$modeltype$unique" -fi - -model=${model,,} # convert to lower case +# Get Synology model from host db file +model=$(ls -lh /var/lib/disk-compatibility | grep -E ".*host(_v7)?\.db$" |\ + rev | cut -d" " -f1 | rev | cut -d"_" -f1) #------------------------------------------------------------------------------ From 5447ec6fff6057d35f25e23297d047dee9336cbc Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 20 Mar 2023 00:31:48 +1100 Subject: [PATCH 55/75] Update CHANGES.txt --- CHANGES.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 5b30bd4..2c1e8ab 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,9 +1,11 @@ -v1.1.15 -- Added support for M.2 drives on a PCI card (M2Dxx and E10M20-T1 and future models). +v1.2.15 +- Now finds your expansion units' model numbers and adds your drives to their db files. +- Now adds your M.2 drives to your M.2 PCI card's db files (supports M2Dxx and E10M20-T1 and future models with similar model names). - Improved flags/options checking and added usage help (-h or --help) and version info (-v or --version). - Can now download the latest script version for you (if you have 'user home service' enabled in DSM). - Now adds 'support_m2_pool="yes"' line for models that don't have support_m2_pool in synoinfo.conf - To (hopefully) prevent losing your SSH created M2 volume when running this script on models that DSM 7.2 Beta does not list as supported for creating M2 volumes. +- Added removal of " 00Y" from end of Samsung/Lenovo SSDs to fix issue #13. - Changed Synology NAS model detection to be more reliable (for models that came in different variations and report extra text after model). issue #2 and issue #10 - Changed checking drive_db_test_url setting to be more durable. - Fixed bug where removable drives were being added to the drive database. From bdfe8e88f9cf48a476721479a18e7ccaf7920541 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 20 Mar 2023 00:37:34 +1100 Subject: [PATCH 56/75] Update syno_hdd_db.sh - Now finds your expansion units' model numbers and adds your drives to their db files. - Now adds your M.2 drives to your M.2 PCI cards db files (M2Dxx and E10M20-T1 and future models) --- syno_hdd_db.sh | 153 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 44 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index baff3e8..1692d97 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -25,15 +25,13 @@ # TODO # Bypass M.2 volume lock for unsupported M.2 drives. # -# Detect if expansion unit(s) connected and get model(s) and edit expansion unit db files. -# Or add support for specifying user's expansion unit model(s) as arguments. -# Or maybe use the shotgun approach and update all expansion unit db files. -# # Maybe also edit the other disk compatibility db in synoboot, used during boot time. # It's also parsed and checked and probably in some cases it could be more critical to patch that one instead. # DONE -# Added support for M.2 drives on a PCI card (M2Dxx and E10M20-T1 and future models). +# Now finds your expansion units' model numbers and adds your drives to their db files. +# +# Now adds your M.2 drives to your M.2 PCI cards db files (M2Dxx and E10M20-T1 and future models). # # Improved flags/options checking and added usage help. # @@ -47,6 +45,8 @@ # # Changed checking drive_db_test_url setting to be more durable. # +# Added removal of " 00Y" from end of Samsung/Lenovo SSDs to fix issue #13. +# # Fixed bug where removable drives were being detected and added to drive database. # # Fixed bug where "M.2 volume support already enabled" message appeared when NAS had no M.2 drives. @@ -82,7 +82,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="v1.1.15" +scriptver="v1.2.15" script=Synology_HDD_db repo="007revad/Synology_HDD_db" @@ -123,18 +123,17 @@ exit 0 scriptversion(){ cat </dev/null; then - # DSM 7 drive db files start with {"disk_compatbility_info": - dbtype=7 -elif grep -F '{"success":1,"list":[' "$db1" >/dev/null; then - # DSM 6 drive db files start with {"success":1,"list":[ - dbtype=6 -else - echo -e "${Error}ERROR${Off} Unknown database type $(basename -- "${db1}")!" - exit 7 -fi -#echo "dbtype: $dbtype" # debug +getdbtype(){ + # Detect drive db type + if grep -F '{"disk_compatbility_info":' "$1" >/dev/null; then + # DSM 7 drive db files start with {"disk_compatbility_info": + dbtype=7 + elif grep -F '{"success":1,"list":[' "$1" >/dev/null; then + # DSM 6 drive db files start with {"success":1,"list":[ + dbtype=6 + else + echo -e "${Error}ERROR${Off} Unknown database type $(basename -- "${1}")!" >&2 + dbtype=1 + fi + #echo "db type: $dbtype" >&2 # debug +} backupdb() { # Backup database file if needed if [[ ! -f "$1.bak" ]]; then if cp "$1" "$1.bak"; then - echo -e "\nBacked up $(basename -- "${1}") database.\n" + echo -e "Backed up $(basename -- "${1}")" >&2 else - echo -e "${Error}ERROR 5${Off} Failed to backup $(basename -- "${1}")!" + echo -e "${Error}ERROR 5${Off} Failed to backup $(basename -- "${1}")!" >&2 return 1 fi fi @@ -457,9 +501,6 @@ backupdb() { # Backup host database file if needed backupdb "$db1" || exit 5 -# Backup synoinfo.conf if needed -backupdb "$synoinfo" || exit 9 - #------------------------------------------------------------------------------ # Edit db files @@ -468,14 +509,17 @@ updatedb() { hdmodel=$(printf "%s" "$1" | cut -d"," -f 1) fwrev=$(printf "%s" "$1" | cut -d"," -f 2) - #echo arg1 "$1" # debug - #echo arg2 "$2" # debug - #echo hdmodel "$hdmodel" # debug - #echo fwrev "$fwrev" # debug + #echo arg1 "$1" >&2 # debug + #echo arg2 "$2" >&2 # debug + #echo hdmodel "$hdmodel" >&2 # debug + #echo fwrev "$fwrev" >&2 # debug if grep "$hdmodel" "$2" >/dev/null; then - echo -e "${Yellow}$hdmodel${Off} already exists in ${Cyan}$(basename -- "$2")${Off}" + echo -e "${Yellow}$hdmodel${Off} already exists in ${Cyan}$(basename -- "$2")${Off}" >&2 else + # Check if db file is new or old style + getdbtype "$2" + if [[ $dbtype -gt "6" ]];then # Don't need to add firmware version? fwstrng=\"$fwrev\" @@ -501,7 +545,7 @@ updatedb() { echo -e "\n${Error}ERROR 6${Off} Failed to update v7 $(basename -- "$2")${Off}" exit 6 fi - else + elif [[ $dbtype -eq "6" ]];then # example: # {"model":"WD60EFRX-68MYMN1","firmware":"82.00A82","rec_intvl":[1]}, # Don't need to add firmware version? @@ -510,9 +554,9 @@ updatedb() { # {"success":1,"list":[ startstring="{\"success\":1,\"list\":\[" - #echo "$startstring" # debug - #echo "$string" # debug - #echo # debug + #echo "$startstring" >&2 # debug + #echo "$string" >&2 # debug + #echo >&2 # debug # example: # {"success":1,"list":[{"model":"WD60EFRX-68MYMN1","firmware":"82.00A82","rec_intvl":[1]}, @@ -527,7 +571,7 @@ updatedb() { fi else - echo -e "\n${Error}ERROR 8${Off} Failed to update $(basename -- "$2")${Off}" + echo -e "\n${Error}ERROR 8${Off} Failed to update $(basename -- "$2")${Off}" >&2 exit 8 fi fi @@ -541,6 +585,22 @@ while [[ $num -lt "${#hdds[@]}" ]]; do if [[ -f "$db2" ]]; then updatedb "${hdds[$num]}" "$db2" fi + + #------------------------------------------------ + # Expansion Units + num2="0" + while [[ $num2 -lt "${#eunits[@]}" ]]; do + eudb="${dbpath}${eunits[$num2],,}${version}.db" + if [[ -f "$eudb" ]];then + backupdb "$eudb" &&\ + updatedb "${hdds[$num]}" "$eudb" + else + echo -e "${Error}ERROR 11${Off} $eudb not found!" + fi + num2=$((num2 +1)) + done + #------------------------------------------------ + num=$((num +1)) done @@ -573,6 +633,10 @@ done #------------------------------------------------------------------------------ # Edit /etc.defaults/synoinfo.conf +# Backup synoinfo.conf if needed +echo "" +backupdb "$synoinfo" || exit 9 + # Optionally disable "support_disk_compatibility" sdc=support_disk_compatibility setting="$(get_key_value $synoinfo $sdc)" @@ -676,6 +740,7 @@ fi # Show the changes if [[ ${showedits,,} == "yes" ]]; then + getdbtype "$db1" if [[ $dbtype -gt "6" ]];then # Show last 12 lines per drive + 4 lines=$(((db1Edits *12) +4)) @@ -686,7 +751,7 @@ if [[ ${showedits,,} == "yes" ]]; then echo -e "\nChanges to ${Cyan}$(basename -- "$db2")${Off}" jq . "$db2" | tail -n "$lines" fi - else + elif [[ $dbtype -eq "6" ]];then # Show first 8 lines per drive + 2 lines=$(((db1Edits *8) +2)) if [[ $db1Edits -gt "0" ]]; then From 1d5f70295d3fc075bd8571ec2ba07ff365c95ef4 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 20 Mar 2023 01:12:37 +1100 Subject: [PATCH 57/75] Update syno_hdd_db.sh Changed model detection to also be DSM 6 compatible. --- syno_hdd_db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 1692d97..113fef8 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -187,7 +187,7 @@ fi # Get Synology model model=$(find /var/lib/disk-compatibility -regextype egrep -regex ".*host(_v7)?\.db$" |\ - rev | cut -d"/" -f1 | rev | cut -d"_" -f1) + cut -d"/" -f5 | cut -d"_" -f1 | uniq) #------------------------------------------------------------------------------ From e0749b5443b6b0061e1c259e505d2bc65767adc7 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 20 Mar 2023 01:46:47 +1100 Subject: [PATCH 58/75] Update syno_hdd_db.sh --- syno_hdd_db.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 113fef8..fefdeb7 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -186,8 +186,20 @@ if [[ $dsm -gt "6" ]]; then fi # Get Synology model -model=$(find /var/lib/disk-compatibility -regextype egrep -regex ".*host(_v7)?\.db$" |\ - cut -d"/" -f5 | cut -d"_" -f1 | uniq) + +# This doesn't work for drives migrated from different model +#model=$(find /var/lib/disk-compatibility -regextype egrep -regex ".*host(_v7)?\.db$" |\ +# cut -d"/" -f5 | cut -d"_" -f1 | uniq) + +model=$(cat /proc/sys/kernel/syno_hw_version) +model=${model,,} # convert to lower case + +# Check for dodgy characters after model number +if [[ $model =~ 'pv10-j'$ ]]; then # GitHub issue #10 + model=${model%??????}+ # replace last 6 chars with + +elif [[ $model =~ '-j'$ ]]; then # GitHub issue #2 + model=${model%??} # remove last 2 chars +fi #------------------------------------------------------------------------------ From 500119e1e34cb485dba1c7314a37ffec63f08973 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 20 Mar 2023 07:27:48 +1100 Subject: [PATCH 59/75] Update README.md --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3de6623..72ca773 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # Synology HDD db ### Description -Add your SATA or SAS HDDs and SSDs plus SATA and NVMe M.2 drives to your Synology's compatible drive databases. +Add your SATA or SAS HDDs and SSDs plus SATA and NVMe M.2 drives to your Synology's compatible drive databases, including your M.2 card and Expansion Unit databases. The script works in DSM 7 and DSM 6. @@ -14,7 +14,7 @@ #### What the script does: * Gets the Synology NAS model and DSM version (so it knows which db files to edit). * Gets a list of the HDD, SSD, SAS and NVMe drives installed in your Synology NAS. * Gets each drive's model number and firmware version. -* Backs up the database file if there is no backup already. +* Backs up the database files if there is no backup already. * Checks if each drive is already in the Synology's compatible-drive database. * Adds any missing drives to the Synology's compatible-drive database. * Prevents DSM auto updating the drive database. @@ -25,9 +25,6 @@ #### What the script does: **Planned updates:** * Allow unsupported M.2 drives for use as volumes in DSM 7.2 (for models that supported M.2 volumes). -* Detect any connected expansion units and get the model(s) and edit the correct expansion unit db files. - * Or add support for users to specify their expansion unit model(s) as arguments. - * Or maybe use the shotgun approach and update all expansion unit db files. ### Download the script From e494a2325c897afd429941e9b715326e91d47ed5 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 20 Mar 2023 07:58:46 +1100 Subject: [PATCH 60/75] Update CHANGES.txt --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 2c1e8ab..8036e7b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +v1.2.16 +- Changed to show the script version and DSM version on each run to make it easier to debug any user's issues. + v1.2.15 - Now finds your expansion units' model numbers and adds your drives to their db files. - Now adds your M.2 drives to your M.2 PCI card's db files (supports M2Dxx and E10M20-T1 and future models with similar model names). From 5b065e5f7812c192ecf6bbc6315d03dc12a74d54 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 20 Mar 2023 08:00:16 +1100 Subject: [PATCH 61/75] Update syno_hdd_db.sh Show script version, Synology model and DSM version --- syno_hdd_db.sh | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index fefdeb7..a69b304 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -82,7 +82,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="v1.2.15" +scriptver="v1.2.16" script=Synology_HDD_db repo="007revad/Synology_HDD_db" @@ -192,7 +192,22 @@ fi # cut -d"/" -f5 | cut -d"_" -f1 | uniq) model=$(cat /proc/sys/kernel/syno_hw_version) -model=${model,,} # convert to lower case + + +# Show script version +echo "$script $scriptver" +#echo "github.com/$repo" + +# Show NAS info +productversion=$(get_key_value /etc.defaults/VERSION productversion) +buildphase=$(get_key_value /etc.defaults/VERSION buildphase) +if [[ $buildphase == GM ]]; then buildphase=""; fi +echo "$model DSM $productversion $buildphase" +echo "" + + +# Convert model to lower case +model=${model,,} # Check for dodgy characters after model number if [[ $model =~ 'pv10-j'$ ]]; then # GitHub issue #10 From b90b663bed6e87ed04a78011511883b8b428ec14 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 20 Mar 2023 08:01:03 +1100 Subject: [PATCH 62/75] Update CHANGES.txt --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 8036e7b..9363b15 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,5 @@ v1.2.16 -- Changed to show the script version and DSM version on each run to make it easier to debug any user's issues. +- Changed to show the script version, Synology model and DSM version on each run to make it easier to debug any user's issues. v1.2.15 - Now finds your expansion units' model numbers and adds your drives to their db files. From 9b5df19e999795d261987072695112837223ec75 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 20 Mar 2023 08:29:46 +1100 Subject: [PATCH 63/75] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 72ca773..1f70dc4 100644 --- a/README.md +++ b/README.md @@ -74,3 +74,4 @@ ### Running the script via SSH - The idea for this script came from a comment made by Empyrealist on the Synology subreddit. - Thanks for the assistance from Alex_of_Chaos on the Synology subreddit. +- Thanks to dwabraxus and aferende for help detecting connected expansion units. From ff68a283641bc68a9bee874ee3703481c1e0746e Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Mon, 20 Mar 2023 17:13:14 +1100 Subject: [PATCH 64/75] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1f70dc4..e41c79d 100644 --- a/README.md +++ b/README.md @@ -75,3 +75,4 @@ ### Running the script via SSH - The idea for this script came from a comment made by Empyrealist on the Synology subreddit. - Thanks for the assistance from Alex_of_Chaos on the Synology subreddit. - Thanks to dwabraxus and aferende for help detecting connected expansion units. +- Thanks to bartoque on the Synology subreddit for the tip on making the script download the latest release from github. From 9ca604f70f31bfe081bcf7fdd3fb2527bda50408 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 21 Mar 2023 04:11:24 +1100 Subject: [PATCH 65/75] Update syno_hdd_db.sh Added disable support memory compatibility option --ram or -r --- syno_hdd_db.sh | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index a69b304..a1ca942 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -82,7 +82,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="v1.2.16" +scriptver="v1.2.17" script=Synology_HDD_db repo="007revad/Synology_HDD_db" @@ -150,8 +150,7 @@ if options="$(getopt -o abcdefghijklmnopqrstuvwxyz0123456789 -a \ force=yes ;; -r|--ram) # Include memory compatibility - # shellcheck disable=SC2034 - ram=yes # for future use + ram=yes ;; -h|--help) # Show usage options usage @@ -688,6 +687,30 @@ else fi +# Optionally disable "support_memory_compatibility" +smc=support_memory_compatibility +setting="$(get_key_value $synoinfo $smc)" +if [[ $ram == "yes" ]]; then + if [[ $setting == "yes" ]]; then + # Disable support_memory_compatibility + sed -i "s/${smc}=\"yes\"/${smc}=\"no\"/" "$synoinfo" + setting="$(get_key_value "$synoinfo" $smc)" + if [[ $setting == "no" ]]; then + echo -e "\nDisabled support memory compatibility." + fi + fi +else + if [[ $setting == "no" ]]; then + # Enable support_memory_compatibility + sed -i "s/${smc}=\"no\"/${smc}=\"yes\"/" "$synoinfo" + setting="$(get_key_value "$synoinfo" $smc)" + if [[ $setting == "yes" ]]; then + echo -e "\nRe-enabled support memory compatibility." + fi + fi +fi + + # Enable m2 volume support if [[ $m2 != "no" ]]; then if [[ $m2exists == "yes" ]]; then From 5585f174967ce3fd8d0ae19f266a8dc9849cbc5f Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 21 Mar 2023 04:12:26 +1100 Subject: [PATCH 66/75] Update CHANGES.txt Added disable support memory compatibility option --ram or -r --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 9363b15..4245934 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +v1.2.17 +- Added disable support memory compatibility option --ram or -r + v1.2.16 - Changed to show the script version, Synology model and DSM version on each run to make it easier to debug any user's issues. From 8ea79288cb47da9930134efe442ba331cb8d4600 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 21 Mar 2023 04:18:13 +1100 Subject: [PATCH 67/75] Update README.md Added disable support memory compatibility option --ram or -r --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e41c79d..7d51b7c 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ #### What the script does: * Adds any missing drives to the Synology's compatible-drive database. * Prevents DSM auto updating the drive database. * Optionally disable DSM's "support_disk_compatibility". +* Optionally disable DSM's "support_memory_compatibility". * Checks that M.2 volume support is enabled (on supported models). * Makes DSM recheck disk compatibility so rebooting is not needed (DSM 7 only). * Reminds you that you may need to reboot the Synology after running the script (DSM 6 only). @@ -38,11 +39,13 @@ ### When to run the script ### Options when running the script -There are 3 optional flags you can use when running the script: -* -showedits or -s to show you the changes it made to the Synology's compatible-drive database. -* -force or -f to disable "support_disk_compatibility". This should be needed if any of your drives weren't detected. - * If you run the script without -force or -f it will re-eanble "support_disk_compatibility". -* -m2 or -m to prevent processing M.2 drives. +There are 4 optional flags you can use when running the script: +* --showedits or -s to show you the changes it made to the Synology's compatible-drive database. +* --force or -f to disable "support_disk_compatibility". This should only be needed if any of your drives weren't detected. + * If you run the script without --force or -f it will re-eanble "support_disk_compatibility". +* --ram or -r to disable "support_memory_compatibility". + * If you run the script without --ram or -r it will re-eanble "support_memory_compatibility". +* --m2 or -m to prevent processing M.2 drives. ### Scheduling the script in Synology's Task Scheduler From 653dec819bc951345ffcd85cd200f354dc22d141 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 21 Mar 2023 06:04:24 +1100 Subject: [PATCH 68/75] Update README.md Added new version check info. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7d51b7c..89c76a5 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ #### What the script does: * Checks that M.2 volume support is enabled (on supported models). * Makes DSM recheck disk compatibility so rebooting is not needed (DSM 7 only). * Reminds you that you may need to reboot the Synology after running the script (DSM 6 only). +* Checks if there is a newer version of this script and offers to download it for you. + * The new version available messages time out so they don't prevent the script running if it is scheduled to run unattended. **Planned updates:** * Allow unsupported M.2 drives for use as volumes in DSM 7.2 (for models that supported M.2 volumes). From 638365e45734c34e4a213539c7bda60594ddaff1 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 21 Mar 2023 12:41:26 +1100 Subject: [PATCH 69/75] Update CHANGES.txt Minor shell output formatting fix. --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 4245934..d3d9f99 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +v2.2.18 +- Minor shell output formatting fix. + v1.2.17 - Added disable support memory compatibility option --ram or -r From 7113ce13d8109637ed137ec0680a343eaa32ad91 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 21 Mar 2023 12:42:09 +1100 Subject: [PATCH 70/75] Update syno_hdd_db.sh Minor shell output formatting fix. --- syno_hdd_db.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index a1ca942..2c6aa12 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -29,6 +29,8 @@ # It's also parsed and checked and probably in some cases it could be more critical to patch that one instead. # DONE +# Added option to disable incompatible memory notifications. +# # Now finds your expansion units' model numbers and adds your drives to their db files. # # Now adds your M.2 drives to your M.2 PCI cards db files (M2Dxx and E10M20-T1 and future models). @@ -82,7 +84,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="v1.2.17" +scriptver="v1.2.18" script=Synology_HDD_db repo="007revad/Synology_HDD_db" @@ -149,7 +151,7 @@ if options="$(getopt -o abcdefghijklmnopqrstuvwxyz0123456789 -a \ -f|--force) # Disable "support_disk_compatibility" force=yes ;; - -r|--ram) # Include memory compatibility + -r|--ram) # Disable "support_memory_compatibility" ram=yes ;; -h|--help) # Show usage options @@ -514,6 +516,9 @@ getdbtype(){ backupdb() { # Backup database file if needed if [[ ! -f "$1.bak" ]]; then + if [[ $(basename "$1") == "synoinfo.conf" ]]; then + echo "" >&2 + fi if cp "$1" "$1.bak"; then echo -e "Backed up $(basename -- "${1}")" >&2 else @@ -660,7 +665,6 @@ done # Edit /etc.defaults/synoinfo.conf # Backup synoinfo.conf if needed -echo "" backupdb "$synoinfo" || exit 9 # Optionally disable "support_disk_compatibility" @@ -736,7 +740,7 @@ if [[ $m2 != "no" ]]; then if [[ $setting == "yes" ]]; then echo -e "\nEnabled M.2 volume support." else - echo -e "${Error}ERROR${Off} Failed to enable m2 volume support!" + echo -e "\n${Error}ERROR${Off} Failed to enable m2 volume support!" fi fi fi @@ -764,7 +768,7 @@ if [[ $nodbupdate == "yes" ]]; then if [[ $url == "127.0.0.1" ]]; then echo -e "\nDisabled drive db auto updates." else - echo -e "${Error}ERROR${Off} Failed to disable drive db auto updates!" + echo -e "\n${Error}ERROR${Off} Failed to disable drive db auto updates!" fi fi else From 08ec5e577cf860559af71570394e476d2a989f36 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 21 Mar 2023 15:48:49 +1100 Subject: [PATCH 71/75] Add files via upload Updated image to match v1.2.17 --- images/syno_hdd_db1.png | Bin 0 -> 21548 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/syno_hdd_db1.png diff --git a/images/syno_hdd_db1.png b/images/syno_hdd_db1.png new file mode 100644 index 0000000000000000000000000000000000000000..ec0884c44d24b3ca1ff53f49f797917dfc8280df GIT binary patch literal 21548 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

yn^8f|!1n=>lP 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 literal 0 HcmV?d00001 From a8a213b82638f0a23499ee312c3bb77caf63dbd8 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 21 Mar 2023 15:49:46 +1100 Subject: [PATCH 72/75] Update README.md Updated image to match v1.2.17 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 89c76a5..9b4c2a9 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ ### Running the script via SSH **Note:** Replace /path-to-script/ with the actual path to the script on your Synology. -

+

If you run the script with the -showedits flag it will show you the changes it made to the Synology's compatible-drive database. Obviously this is only useful if you run the script in a shell. From 0b0e32bd71b9985e254fa610f55c65ee464329d5 Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 21 Mar 2023 15:53:31 +1100 Subject: [PATCH 73/75] Add files via upload Added help image to match v1.2.17 --- images/syno_hdd_db_help.png | Bin 0 -> 11300 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/syno_hdd_db_help.png diff --git a/images/syno_hdd_db_help.png b/images/syno_hdd_db_help.png new file mode 100644 index 0000000000000000000000000000000000000000..4d2fdeadb12ff11da5d48db0d07d0a548e39bc4f GIT binary patch literal 11300 zcmbt)cUY5Iw{ILr84F@ZY0367Kry_f{~&aHEz9h=Q)d>Ct1=!13vgHQA}w6& zaf9V{PPKlXd4Ea0N_QYSyZ-qv`OVI@;#d8pO-}5+Z|@&hP@ZUc_Th)`Hy^d6s`*3( z8}(W)W!U&0P$EbF z6PW`D=YIb6kBN>4Y+fr#O+;``?458)&psrN|HD(ozVWL}D0iDC0*+Yk)1jXEAzVR! zV#Fi(U*M9nnSgNo0BV?^B@)7n#HkD-0b`{J!yi_Y3q=rO1xHN5q5=4nz?8OrK9V+~J>(*2v8;+gk zP5}K%P9Tu4J8cto)V&oJG_$;k;cY>Acqk9^Xdg*Nu|JTE5CBN#G>tDPMWBpX7E2Xq z&MYrEH`k1bCi7?_F@hiSaYWC^r^L-^xE<%b{0R_9@oeuPLcL)0>Px(Q36Q>LkyY)v z(sg29A>>cf7F08z%^^lm3=@BVAyd4r1pcgm@09&y=ue@x6t&{MA(98ZsEk*$rAEsk zzO9_;CL|!>>x{KNnm;tSguhd&cN>0R(0a@iJ{}?%fNrj1qJM$wZfp_x?Fj($rl1_R)CqNAbFfm0kR8XW{=dd$>JEk^Bo;g3rgq1G1AoAHl3xh zD8A>3t{U8!HTVnmo3s;G6m;)^=p)T&w77U?%m=$u5flVkvK{CGA1k@_s+zvC+=2(d zFW$e^N;CT+Nx*QZXx1nqPz1YUFUF=rn@CmqqIKD1D?j*5HZhdtD&UH7wbp=F z%OT+|SLWk|TDty7A|Hr-NZe{AL4LbO^9XRZ_qG2FzFD#zTu7ufxXu^+&$MYBZ868IuLTA{cnk*1H1xWGuj`e=l8xRhHnAeFyUzpszW8uDH z|8?TrC{?gIzUnUg>GSc%P}*z=k&`uIK%i-0-|hHT?63d(N~r;=CjzkH(HJF0dYJ9O z^-?&7@aH8ZNgdvFWz>CF%2+T{pJi4Z!se_z=4?j{wqcKUiGjLrkr_xHqXF8$AJYIs zw3@cqLmD{#(v%qHs7zy+y4IpK7FEUjfivT!;u@J*8b4hi{Po-rfE~2HGESkEPB&68 zORU!Z;oe0t1f(uFl-WCVCLOMaVlIf|?Hm2{!g)?DEV+Ix+ZlO*?Zu{@F{VXWXu-n} zjJQicVJkj6LdJT9HOLWTLd=Ftpbp)4a2PT_ry4^h#GUfmlqm&>Ls{l}jb_x+aDjd1 z>gc=cYg_Hzc#@81$%=^)re?$JgRScWfvv~5eD9H9n{`v5@s~m{;M;>}E53jti- z)_fO~x+(dsc19`@O+3Eb88GJvlu%(TNE4CKhrLeuOf@*^-kgJ!UY62J>bhcm&6 zOXU~kl3A~x=)x`fRG*kamO6eUso*fY7L_Nos$lBi>r~TpfJf`+rBy^do19TG`~p_f zoiO767HzebHO*gGd5M{sb^3(LyxTNj=G>w1B%}G#-2CHOb*T>{mek&xBV#bTx>GXI zO%BLhJW>2SPB~guWGVtHyTaU_QMc&(@ysL3+n_$NcgCq`^p1X5(yZvPmFratnW=5} zLV;Vr{Op`l)k)XGC)7TEf^f~lyt=^o;N%NDidQf4$ZfUl&rjr43$`RWNU}kr^7Uq*3_Oj_Ho=j%7w!UFg$f0_%i_fzl*$ym)_qQU{NZvn?XYHY&uqyW2 zi;(Rb3O^jl2s0xLcVtlvD#QP5(O_Lx49B2tPNfn2O9bCkBK`6LZTFF>_lU&pZtBN~ z4SvibZn*>Sh|G-XuooKqNP{&ln*I$Mx)G*(3%$m5WHf0I*fYEFj{Hrg`ui{g;j5Nok!juxtWF>2^7u&e% zhvkuv&aw!3#Yt09XR`S^v^}o%4(hZcUGUT9>;=l`3VYWdr%2RWjW^pb*yaLlM+!Br zbGub!Tz>Z5X?43GC6+gs1AM?(^S*MnOHXg=%#Tmtr@7Pg5HgFd5rRVpZw}IN#Bkm* zoMQQmyiVcm87dk(H+`Is*nQLotAkBabnHo$Bd%x&4rW zhi>aA#Scw1@ke>yL}MfM#~-nBOU2L7R0YiEZ@ao*OKVZSkqqW&sYK8VP4(XetC<>s(tNS-$oxK#h0bGE)0QFRn(RvZtBigsnG^g zfxrJi*UJ;8^T^RaZoxkferYKrcupy1 zFVTKE-j`r(IqVpwm%)!fY4y?<^>ZR6=~z^dV;2Xo=)oFmEWU@_&X1ywGdRt8l1240 zVJ*FF!3`*6x8&P)^6feUoHem}zFY}YlPNDb-Yrb-+YeXp>NnWO%3zz41vg887mvmH z2j$)Y9`!8xQmJPQ-YR5dy(3u?lpFuZ>d7}9-FboVnVj(WSd|2^vABUt9wq_ z=t7OkiaKzU;cRo4zQ%2foR4Tp60Qvz7?}@RS#GeH5?J}U`qfzZx4lZ;9xaAA6RjnR ztG%>^V#gSaOX_ft{Nu&w3J-B{Zr@^vza%P^wvhfgzo4!jJxtd{!9rtSNx%e84S z3*6R0m-YU!@oAT{K8D^Mo3LYGM=ANwQm#`$I=zhDe-Gp=cASs=5n6@mZk5A^MjwCM z3$w+1a(*(8TM8?5?}oR2J-T3M+27slPZr|T+S}_~v-K{AhD49A2baDd`C@r8l=mm> zKT!Ymy}hlbXHR(R+Jvw{seAt`y!j{YNf=}3Q0P}5lnw@0i|HzU0c+ShBu&LMW9+_T zbjGaTDM_ioTa8fhmU7V5a)(W3SA(?Sa$y4D>Fc7Z5&2gM`&A~ZN0O6cW0P7^d^5<^ zqun32bnpENI$OCC^2yS1cuIsL@!=&y=P`f6_xP5+3GZA5j_1(E(KPBXzTedEckzcg zCp3?9w`M|zlWz=7K?es=wQWi(ww;U#gOuVj7qi|TT0O;*FmR1OCWMR+a)1|RaHA2( zmwFisZK#Yv0mqLGc{9E-sj9u-WR&XFoF~jGC$^;|QMKg9->I$6tK2p7?Orptj?^4zWo^}hmLK;e zI)G>Q@paSbQGC5^tse>Jb{|{*k{j;Ok@-&Z96GTeiSBR0e-lqB9$kD$Zp~V7ECH-? zjc>9Up~}x`GEwkkQR9l@CA2HDsL#iiI@n1gMpANiZ?NFrEJ z@CEkdv2YD>I2 zT4%X%(@O&*Bcmd8^!eA9@_{{Mw>3Y#A(oV+xdPkQb^0`JwHEH5GnE@E?QlQW3FBu- z^t`HgjdMK}0VlTO!6A-_g&wsU-^qI_c86b~`yJO#D2D24E=4DguXwc=kbAJZ|NLVQ zyL5Kmjm2==RmnaqxnONv3a1>e--rl1|Hc0fWyZlJ4DBU>b#(lT4w*~@2QT!#l1b=g zE>zo)abCg$vEs9Hu6!x9<+MLrmG<_Kx%(zwVXZM?THJOYy59kLL1_kOFB!(LaI6`e z=l3pRFjI-0D(qu!9ZK*&%ef@E`PYw+XI^IH7S2gpd>cbb^VPOWo+v_FKO0AvVW7Cg@#K%ICFiz3&$Gf_l!|D zky~2UH!sYKfQpjYn+;7v6M!wlU{1XCz=-z5p#;S0rZ(+Il0H*&8QawVlhvUT9pmbO zxGDp!(Fo@>(`I&yOnG6)f9h%5SYGIeso%Io{-RkjhpSYlwzc^dS>=jJ72HTPT-<@K z+{ZV{cuM~UA4j`);G?F`H$Tl(C3DUN)8>ALnzp1mdOGKoD;1PN>VEA+!{qtHd zhs)K~SXXx1ZPRldW-fTO; z_@y^`)Hi*XR(b=-HgKJ*)#4j^<5JQ;Pky7>mtpT@NL=!zC|*hkw7sDVq}~atK>9|= zScPJE!M|AH|?h`G5KQHAD+KE=lo!~Uz)tmxQxLiGpnmtk~`%LYjjy-a}f;nr6IWp z#bQF>%>=hrk;P-F?3`!qOiXf2hkJrS#eE{);dRW*yTChv!r+0~}<`D1&$#Km)0Oka zszcwsO_AAK+Bdze-C*1Mp4@pXcAufr7l!Bf##@|-Fi>Wg9b+QKgmGkH5}6|N=*HUwIKBK4@qfoB&{UG<&;)W{2uK7O%c> z$z>K@9iPgU6AJw2ysH&&>x8wmOdvQkv7vkjfa$!wMBHIL)_z9aCP@j|6FZk7>Xs=6 z?u`J;Qp5ZS=y2EJu&O$LKmRK>6Fp)*P4t9o)>qs`#i+N8exm#lBT#1E`tBTIL`g`j z(>(13hCWZKJ9TKp;|>1_JL*gTfBi;v-<38`ri^r{%f_!l9lc54)cKnll{x9N$=3LZ zGzexVjP5v5LO)NV=@>py75{{*mpx-j#LBD}u0##r+y|F@wi~0;-*-t{?vE$FzN`Hr zp@ra}J0UwNc&NQHL`839ef$%)6k^J(>|6v4k@kw(sG-RUz4`C|=!zMOM^n z@=U*Z{KHo^d$xt-(qqFSPhN%}UpH}U#ps^X{IcyVmaUg)zUbh48 zW^{wr0P{4ch*0(Wi*FM{*a`0ozbKp5@(zMP_q0~ALOT1uqku*JGdC>J!h5n%-EaJ< z#DuTkaCjJlaGvoDN#<8DJN;dzo= zwMcaP&0lg9m+;x;StQRk092z>3@;nen8M*+2KRd+R#!vbd#^1X7V&OUhH(`XT}$V2 zpX^*NnMuUBZ@t*KP#N@TN=fj}{noYe$fDI-fBr5cYoib$rAu_t&DD?9b?zJD3CsXd zW{DyCodI;L^__V=%*zKe##OG^J@SI%yhcSuA;NF_b+gM(##mHj>6_0t0 zU8uA=RX>aFG?#SZn<|@H)eF{PjW9 z1}RDva*d48Iy7yzlQa(7mN`b>c97mEd$ABqlEEGq%;t=TW~prii`IV5WK7Ihn7=^a z-w=Wb;h3vYrc7i4z5(Al?Zly334-%nS$=okAoNGuwcl*8@5caPKSE6Q_+56<2;=L% z#a+vGxGQl|a6Y#dX;zYcsJ}6A_>xq;;XkF}0I(WT)LF<$wh}(IxiHjUVF?fxtjEYy z>_C^cLIy6WyjlCYT*ei?>7zG@5D0t%Eg!1twgzZQmrk9^Dy?oAdMcS>xndygXKWyL zqOJMqGc*hU`8?#_<{i58IA(Ayw(6&YR$<){!WrI4GWiqQ>=p42u}$-mutLt4V|#C` zl?`oKbdhFM%CLyZCB~?wXCQ_%W(G#BL+zULu+Qa)n1A0)VxR_7SwUNgy+&XWmgY)<-D863iAZ;+kz^A=a zn562vN9PpEUb5(hG?hNAB<|Qk{}ZE(T;M%|Ic)aABn#IJx3w)i28`=M5KNghS3=y_ zGv%E$ld4%M=S7Ky%M8wsccJ!21UGz)g>#pcb}zT1vqZ-bDVl*ym!PKlOB>dl^HayhA_F z`yqY3Gn%+G9+xb+0;;f_iCO5*zY2D=#K z_@>6!XB0#RW9fVCde>QHuW#ty)w$I>BT#a+-wIDNZmdP=;;w$Fsau==Rls147(>Q3KL(G8x%bbJ z?RSsBu|wMxQF?I$)O99$?$yWrgcfy&9_vc5Q?TvPgfT8Sy?KVQLqw(s*|ApZL06ka zrq}xI8b(viMZD;PZz$OjsUjs}qv7+wdBfnho2?sO3apzO`r>5hGiV@Myda?JJEom-ZL4nMP&kUzS$Z$6%Dl(wk>() zl47J4Vz%flCzA$AcF%r3EfQLPc(H5Ned`FGDY*9ZNso#FlXs=6VT9RD(5;~jV^umV zFod}TpH3obFAU;chmiJr_mY|K)*&?!GwXii~D}BOrS-RiBO9% zd*g^D1JsurrFO(U#6{2))9H{#kCWt{yFw|FM)jmypD&W~fELki)kn|MQ_&MO$ZLP? zU1C1qQ!pC zt0Bn}Aw^c)ojb4V0oy=YjeV>ne6`rtgE`~_3me4IM{566^;okw!gEZ{&T{-qhL!O`ptp`>!8SOP@*C^@ljT;xLW(0>j={d zWwu^7q_+m$Z{?H?9x6+F@s<1hO0t2gM4=Y^^u$yP*d_vPvgnzeE#;JayoGzfPj#(~ zNTnCc`P4ByvyPe_8D1l1XI<7aOg*}vLV7a|Mhy>k)Fp;~_!Kj^{oITy@P1XXqyaAU z`AVAQIKyQqXhS6WQD6S;yL_L@E;+UtjJ0U4-bc!eMDxH9|M2_uXkeP(i(? zzHF9-gMN3j+wUn^iUx>JD7hY=&56!XgHmuEA+thIRgL=;2YhNGhHf;QlO}%W<BDpzV%_Dgr;BFr3zyQ2`$dt=rx{U@(5$}SLky0TEoGCUxn7p z<`UZ?q6mS+zbmYP2CE`dm!43Xvo{sdXs(z~$?t3JnYw23XT;8(y$HE9Dq{Z7V{n|&8O z_l>RIi5c&*{@#KJtsriH7c=i>pd1G?vHy1VeQfV`Q30apBsY5(s7KA7Xtyqi_GqS_ z20i{gjBS2W$jv5;gKFRaFBVn)T%&-?;Df!7}?n8@p3ouphnH(^M^gY2cyK%Wg#MW3_Uuq7 zV6XfgF(A79FfJ)CbT5jw)71DcJtXf}Lr(J)TYVtup1SOjZ#WN>HGabuthnmFRs!B`p zPRbUwMKJuX-3{b?%O5t{bbRdKcXD3G=NMRyZ?vg(oaYg+rQxBLW+U{ZNgIaFTT3nM zb>H9Gf#hZ88{w@q+w^Ch4`=liQV%aITr_|8& zaLWRq`9^u`Qt;igmIj+Tu&}*Ack}_a9aezP#Dz_VHV%Dar2Cv1rFT}h>r)M~DP}|V zzDB&!?bl|im@V=*_1#E*#3SgOPZE1G|~+tjEN(fjPNCU6~tt)9=+7auC$&?mJIW#SII zq8iS_%X+R{A!~T+6UbJyBjc*dudJUAF+Popct9hLB8CUqy@hvIg*<8L8tZo{!1h~J zE`cC_aN|chlXYbg`UwJAuHS$bN+1^x6%@#^m7;`iD~7uhIlTdkNJIBVG+7`D3aa>m zrl;>h+F7K1y8b^!n;L1n8kEbXT(~}esXqKPZ$`*|h6aoZTSJc~;s<=w-Cm+O zU-`|9_x;w390iVuPQoD0VjU5G?X4+FH~FvzQsAfqc8kJQUXxA|tI7iEN{Ls{Bk79r z>m~Ldq4itHv+U*=cxo`x6)XDgokYf*z^?gXlLZUoNgrYJyZE>J9E*YF(3XV$%WI@x ziB39#TQIO&u^r^ZH`PqUVrmAiYwo})qDOM4Lojh=4=2}?0mCA+axFm$8R~rd9_La< z`6!!jFTqm|G%4U@OovjpQZyEXW-iQK`7#gL*JIayr#L&az2|YS;MHADsts^PByVsK z@la8DDP)QdkXc3qV(KkocMpQeDb;WPOoH606Zo>Wbi%8@uWo^U~?5gyDBTawrNEtt)*0Z!nK+^-DJl+JcW>fZ zRYR#+ovjK|5Y!~7%Ien!sl6!J#uyXyPUIufspkdmFyd|erKP73NTey!fg9R@)Ct6m zqZ>zvdgW(@sXoC@>?C^5Tw46wjyMJ3W7{}mesax@IOiqQ_+>YUC0!wrf=z#lusiNj z0yM|!dkWf@-PYQdyh_!z_Mcb|*{~l?uys;h^PyPS7uY*=#@HZ`+fkuuW$}R; zNONaliYH%}M0JgYj`csBM^$KqHwBGIOabVc5o*<)sLuNX?CTRN_~`^&mw#-eOzNJ- z*ioV0idpJg&{8g#@-sFWpV&OWBN*P#Xs&K>JoejT;3aA&Dj(c~BPe=>g z|D4aEvDYF6%%dFDs9pH+ouLc4|5HHPA9b4dVKLH}58Q2iwzcO^XCY|8b}tB{-;B1f zP<0A1!iaUd!aBi0)E7^>tk-WJg3e|^@4*QD{vOgwEY;NYl6WRqv?J^F&8iH%SiK}4 zxP~67QUNKd#tk4WeWSlGF=Sb0!&$ga@iA%zjNnQ}VO&>h!hO+@W=wb_!m?d(?z>WO zVCZE8IMA9abh;1jaL_}mj9I}N!)xa~#oAAn3DOA0!BFVxoZl(8JLjNwtAKMB>`j74 z$^si>Mz+4o`Q@|!w>LDrk+z;Xv00eb2F1rF*H$7j>?nXFMW7c4S6@2-GB%9b)LHGn z<58-)T{a|ub&=*`KT?8w`9oIplGr66izdkK!et26a3SwLyHrE6q+c+RhL8g<%^5tK z>F~ Date: Tue, 21 Mar 2023 15:54:38 +1100 Subject: [PATCH 74/75] Update README.md Added help image to match v1.2.17 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9b4c2a9..c11cad3 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ ### Options when running the script * If you run the script without --ram or -r it will re-eanble "support_memory_compatibility". * --m2 or -m to prevent processing M.2 drives. +

+ ### Scheduling the script in Synology's Task Scheduler See How to schedule a script in Synology Task Manager From ba936382cc247f029f50891d941b0cd660fca5fd Mon Sep 17 00:00:00 2001 From: 007revad <39733752+007revad@users.noreply.github.com> Date: Tue, 21 Mar 2023 15:58:55 +1100 Subject: [PATCH 75/75] Update README.md Updated optional flag text to match v1.2.17 --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c11cad3..bd4c6aa 100644 --- a/README.md +++ b/README.md @@ -41,13 +41,14 @@ ### When to run the script ### Options when running the script -There are 4 optional flags you can use when running the script: +There are optional flags you can use when running the script: * --showedits or -s to show you the changes it made to the Synology's compatible-drive database. +* --noupdate or -n to prevent DSM updating the compatible drive databases. +* --m2 or -m to prevent processing M.2 drives. * --force or -f to disable "support_disk_compatibility". This should only be needed if any of your drives weren't detected. * If you run the script without --force or -f it will re-eanble "support_disk_compatibility". * --ram or -r to disable "support_memory_compatibility". * If you run the script without --ram or -r it will re-eanble "support_memory_compatibility". -* --m2 or -m to prevent processing M.2 drives.