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