diff --git a/CHANGES.txt b/CHANGES.txt index fed379a..7b6780d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,13 @@ +v3.1.61 +- Added enabling E10M20-T1, M2D20 and M2D18 for DS1821+, DS1621+ and DS1520+. +- Added enabling M2D18 for RS822RP+, RS822+, RS1221RP+ and RS1221+ for older DSM versions. +- Fixed enabling E10M20-T1, M2D20 and M2D18 cards in models that don't officially support them. +- Fixed bugs where the calculated amount of installed memory could be incorrect: + - If last memory socket was empty an invalid unit of bytes could be used. Issue #106 + - When dmidecode returned MB for one ram module and GB for another ram module. Issue #107 +- Fixed bug displaying the max memory setting if total installed memory was less than the max memory. Issue #107 +- Fixed bug where sata1 drive firmware version was wrong if there was a sata10 drive. + v3.0.56 - Minor bug fix for checking amount of installed memory. diff --git a/README.md b/README.md index b685a8a..0ecc648 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,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, including your M.2 card and Expansion Unit 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 Synology M.2 PCIe card and Expansion Unit databases. The script works in DSM 7, including DSM 7.2, and DSM 6. diff --git a/my-other-scripts.md b/my-other-scripts.md index 1da561a..de8440a 100644 --- a/my-other-scripts.md +++ b/my-other-scripts.md @@ -10,11 +10,14 @@ ## All my Synology Scripts - **Synology_M2_volume** - Easily create an M.2 volume on Synology NAS. +- **Synology_enable_M2_card** + - Enable Synology M.2 PCIe cards in Synology NAS that don't officially support them. + - **Synology_enable_Deduplication** - Enable deduplication with non-Synology SSDs and unsupported NAS models. - **Synology_RAID-F1_SHR_switch** - - Easily switch between SHR and RAID F1. + - Easily switch between SHR and RAID Group. - **Synology_Config_Backup** - Backup and export your Synology DSM configuration. diff --git a/syno_hdd_db.sh b/syno_hdd_db.sh index 2a4b545..0fc5edc 100644 --- a/syno_hdd_db.sh +++ b/syno_hdd_db.sh @@ -26,10 +26,24 @@ # It's also parsed and checked and probably in some cases it could be more critical to patch that one instead. # # Solve issue of --restore option restoring files that were backed up with older DSM version. +# Change how synoinfo.conf is backed up and restored to prevent issue #73 # DONE -# Minor bug fix for checking amount of installed memory. +# Added enabling E10M20-T1, M2D20 and M2D18 for DS1821+, DS1621+ and DS1520+. +# Added enabling M2D18 for RS822RP+, RS822+, RS1221RP+ and RS1221+ with older DSM version. +# +# Fixed enabling E10M20-T1, M2D20 and M2D18 cards in models that don't officially support them. +# +# Fixed bugs where the calculated amount of installed memory could be incorrect: +# - If last memory socket was empty an invalid unit of bytes could be used. Issue #106 +# - When dmidecode returned MB for one ram module and GB for another ram module. Issue #107 +# +# Fixed bug displaying the max memory setting if total installed memory was less than the max memory. Issue #107 # +# Fixed bug where sata1 drive firmware version was wrong if there was a sata10 drive. +# +# +# Minor bug fix for checking amount of installed memory. # # Now enables any installed Synology M.2 PCIe cards for models that don't officially support them. # @@ -69,7 +83,6 @@ # https://www.youtube.com/watch?v=cLGi8sPLkLY # https://community.synology.com/enu/forum/1/post/159537 # -# # Added --restore info to --help # # Updated restore option to download the latest db files from Synology @@ -188,7 +201,7 @@ # Optionally disable "support_disk_compatibility". -scriptver="v3.0.56" +scriptver="v3.1.61" script=Synology_HDD_db repo="007revad/Synology_HDD_db" @@ -441,7 +454,7 @@ scriptpath=$( cd -P "$( dirname "$source" )" >/dev/null 2>&1 && pwd ) if ! printf "%s\n%s\n" "$tag" "$scriptver" | - sort --check --version-sort &> /dev/null ; then + sort --check --version-sort >/dev/null ; then echo -e "\n${Cyan}There is a newer version of this script available.${Off}" echo -e "Current version: ${scriptver}\nLatest version: $tag" if [[ -f $scriptpath/$script-$shorttag.tar.gz ]]; then @@ -469,28 +482,28 @@ if ! printf "%s\n%s\n" "$tag" "$scriptver" | url="https://github.com/$repo/archive/refs/tags/$tag.tar.gz" if ! curl -LJO -m 30 --connect-timeout 5 "$url"; then - echo -e "${Error}ERROR ${Off} Failed to download"\ + echo -e "${Error}ERROR${Off} Failed to download"\ "$script-$shorttag.tar.gz!" syslog_set warn "$script $tag failed to download" else if [[ -f /tmp/$script-$shorttag.tar.gz ]]; then # Extract tar file to /tmp/ if ! tar -xf "/tmp/$script-$shorttag.tar.gz" -C "/tmp"; then - echo -e "${Error}ERROR ${Off} Failed to"\ + echo -e "${Error}ERROR${Off} Failed to"\ "extract $script-$shorttag.tar.gz!" syslog_set warn "$script failed to extract $script-$shorttag.tar.gz!" else # Copy new script sh files to script location if ! cp -p "/tmp/$script-$shorttag/"*.sh "$scriptpath"; then copyerr=1 - echo -e "${Error}ERROR ${Off} Failed to copy"\ + echo -e "${Error}ERROR${Off} Failed to copy"\ "$script-$shorttag .sh file(s) to:\n $scriptpath" syslog_set warn "$script failed to copy $tag to script location" else # Set permissions on script sh files if ! chmod 744 "$scriptpath/"*.sh ; then permerr=1 - echo -e "${Error}ERROR ${Off} Failed to set permissions on:" + echo -e "${Error}ERROR${Off} Failed to set permissions on:" echo "$scriptpath *.sh file(s)" syslog_set warn "$script failed to set permissions on $tag" fi @@ -499,27 +512,27 @@ if ! printf "%s\n%s\n" "$tag" "$scriptver" | # Copy new CHANGES.txt file to script location if ! cp -p "/tmp/$script-$shorttag/CHANGES.txt" "$scriptpath"; then if [[ $autoupdate != "yes" ]]; then copyerr=1; fi - echo -e "${Error}ERROR ${Off} Failed to copy"\ + echo -e "${Error}ERROR${Off} Failed to copy"\ "$script-$shorttag/CHANGES.txt to:\n $scriptpath" else # Set permissions on CHANGES.txt if ! chmod 744 "$scriptpath/CHANGES.txt"; then if [[ $autoupdate != "yes" ]]; then permerr=1; fi - echo -e "${Error}ERROR ${Off} Failed to set permissions on:" + echo -e "${Error}ERROR${Off} Failed to set permissions on:" echo "$scriptpath/CHANGES.txt" fi fi # Delete downloaded .tar.gz file if ! rm "/tmp/$script-$shorttag.tar.gz"; then - echo -e "${Error}ERROR ${Off} Failed to delete"\ + echo -e "${Error}ERROR${Off} Failed to delete"\ "downloaded /tmp/$script-$shorttag.tar.gz!" syslog_set warn "$script update failed to delete tmp files" fi # Delete extracted tmp files if ! rm -r "/tmp/$script-$shorttag"; then - echo -e "${Error}ERROR ${Off} Failed to delete"\ + echo -e "${Error}ERROR${Off} Failed to delete"\ "downloaded /tmp/$script-$shorttag!" syslog_set warn "$script update failed to delete tmp files" fi @@ -537,14 +550,15 @@ if ! printf "%s\n%s\n" "$tag" "$scriptver" | fi fi else - echo -e "${Error}ERROR ${Off}"\ + echo -e "${Error}ERROR${Off}"\ "/tmp/$script-$shorttag.tar.gz not found!" #ls /tmp | grep "$script" # debug syslog_set warn "/tmp/$script-$shorttag.tar.gz not found" fi fi + cd "$scriptpath" || echo -e "${Error}ERROR${Off} Failed to cd to script location!" else - echo -e "${Error}ERROR ${Off} Failed to cd to /tmp!" + echo -e "${Error}ERROR${Off} Failed to cd to /tmp!" syslog_set warn "$script update failed to cd to /tmp" fi fi @@ -557,16 +571,18 @@ fi dbpath=/var/lib/disk-compatibility/ synoinfo="/etc.defaults/synoinfo.conf" +adapter_cards="/usr/syno/etc.defaults/adapter_cards.conf" +modeldtb="/etc.defaults/model.dtb" if [[ $restore == "yes" ]]; then dbbakfiles=($(find $dbpath -maxdepth 1 \( -name "*.db.new.bak" -o -name "*.db.bak" \))) echo - if [[ ${#dbbakfiles[@]} -gt "0" ]] || [[ -f ${synoinfo}.bak ]]; then + if [[ ${#dbbakfiles[@]} -gt "0" ]] || [[ -f ${synoinfo}.bak ]] ||\ + [[ -f ${modeldtb}.bak ]] || [[ -f ${adapter_cards}.bak ]] ; then # Restore synoinfo.conf from backup if [[ -f ${synoinfo}.bak ]]; then - #if mv "${synoinfo}.bak" "${synoinfo}"; then if cp -p "${synoinfo}.bak" "${synoinfo}"; then echo -e "Restored $(basename -- "$synoinfo")\n" else @@ -575,10 +591,29 @@ if [[ $restore == "yes" ]]; then fi fi + # Restore adapter_cards.conf from backup + if [[ -f ${adapter_cards}.bak ]]; then + if cp -p "${adapter_cards}.bak" "${adapter_cards}"; then + echo -e "Restored $(basename -- "$adapter_cards")\n" + else + restoreerr=1 + echo -e "${Error}ERROR${Off} Failed to restore adapter_cards.conf!\n" + fi + fi + + # Restore modeldtb from backup + if [[ -f ${modeldtb}.bak ]]; then + if cp -p "${modeldtb}.bak" "${modeldtb}"; then + echo -e "Restored $(basename -- "$modeldtb")\n" + else + restoreerr=1 + echo -e "${Error}ERROR${Off} Failed to restore model.dtb!\n" + fi + fi + # Restore .db files from backups for f in "${!dbbakfiles[@]}"; do replaceme="${dbbakfiles[f]%.bak}" # Remove .bak - #if mv "${dbbakfiles[f]}" "$replaceme"; then if cp -p "${dbbakfiles[f]}" "$replaceme"; then echo "Restored $(basename -- "$replaceme")" else @@ -659,9 +694,9 @@ getdriveinfo(){ #fwrev=$(printf "%s" "$fwrev" | xargs) # trim leading and trailing white space device="/dev/$(basename -- "$1")" - #fwrev=$(syno_hdd_util --ssd_detect | grep "$device" | awk '{print $2}') # GitHub issue #86, 87 + #fwrev=$(syno_hdd_util --ssd_detect | grep "$device " | awk '{print $2}') # GitHub issue #86, 87 # Account for SSD drives with spaces in their model name/number - fwrev=$(syno_hdd_util --ssd_detect | grep "$device" | awk '{print $(NF-3)}') # GitHub issue #86, 87 + fwrev=$(syno_hdd_util --ssd_detect | grep "$device " | awk '{print $(NF-3)}') # GitHub issue #86, 87 if [[ $hdmodel ]] && [[ $fwrev ]]; then hdlist+=("${hdmodel},${fwrev}") @@ -941,14 +976,12 @@ backupdb(){ for i in "${!db1list[@]}"; do backupdb "${db1list[i]}" ||{ ding - echo -e "${Error}ERROR 5${Off} Failed to backup $(basename -- "${db1list[i]}")!" exit 5 } done for i in "${!db2list[@]}"; do backupdb "${db2list[i]}" ||{ ding - echo -e "${Error}ERROR 5${Off} Failed to backup $(basename -- "${db2list[i]}")!" exit 5 # maybe don't exit for .db.new file } done @@ -1121,10 +1154,18 @@ done #------------------------------------------------------------------------------ # Enable unsupported Synology M2 PCIe cards +# DS1821+, DS1621+ and DS1520+ also need edited device tree blob file +# /etc.defaults/model.dtb +# RS822RP+, RS822+, RS1221RP+ and RS1221+ with DSM older than 7.2 need +# device tree blob file from DSM 7.2 to support M2D18 + enable_card(){ - if [[ -f $1 ]] && [[ -n $2 ]]; then + # $1 is the file + # $2 is the section + # $3 is the card model and mode + if [[ -f $1 ]] && [[ -n $2 ]] && [[ -n $3 ]]; then # Check if section exists - if ! grep '^\['"$2"'\]$' "$1"; then + if ! grep '^\['"$2"'\]$' "$1" >/dev/null; then echo -e "Section [$2] not found in $(basename -- "$1")!" >&2 return fi @@ -1132,38 +1173,121 @@ enable_card(){ val=$(get_section_key_value "$1" "$2" "$modelname") if [[ $val != "yes" ]]; then if set_section_key_value "$1" "$2" "$modelname" yes; then - echo -e "Enabled $1 for $modelname" >&2 + echo -e "Enabled ${Yellow}$3${Off} for ${Cyan}$modelname${Off}" >&2 + else + echo -e "${Error}ERROR 9${Off} Failed to enable $3 for ${modelname}!" >&2 + fi + else + echo -e "${Yellow}$3${Off} already enabled for ${Cyan}$modelname${Off}" >&2 + fi + fi +} + +check_modeldtb(){ + # $1 is E10M20-T1 or M2D20 or M2D18 or M2D17 + if [[ -f /etc.defaults/model.dtb ]]; then + if ! grep --text "$1" /etc.defaults/model.dtb >/dev/null; then + if [[ $modelname == "DS1821+" ]] || [[ $modelname == "DS1621+" ]] ||\ + [[ $modelname == "DS1520+" ]] || [[ $modelname == "RS822rp+" ]] ||\ + [[ $modelname == "RS822+" ]] || [[ $modelname == "RS1221rp+" ]] ||\ + [[ $modelname == "RS1221+" ]]; + then + echo "" >&2 + if [[ -f ./dtb/${modelname}_model.dtb ]]; then + # Edited device tree blob exists in dtb folder with script + blob="./dtb/${modelname}_model.dtb" + elif [[ -f ./${modelname}_model.dtb ]]; then + # Edited device tree blob exists with script + blob="./${modelname}_model.dtb" + else + # Download edited device tree blob model.dtb from github + if cd /var/services/tmp; then + echo -e "Downloading ${modelname}_model.dtb" >&2 + repo=https://github.com/007revad/Synology_HDD_db + url=${repo}/raw/main/dtb/${modelname}_model.dtb + curl -LJO -m 30 --connect-timeout 5 "$url" + echo "" >&2 + cd "$scriptpath" || echo -e "${Error}ERROR${Off} Failed to cd to script location!" + else + echo -e "${Error}ERROR${Off} /var/services/tmp does not exist!" >&2 + fi + + # Check we actually downloaded the file + if [[ -f /var/services/tmp/${modelname}_model.dtb ]]; then + blob="/var/services/tmp/${modelname}_model.dtb" + else + echo -e "${Error}ERROR${Off} Failed to download ${modelname}_model.dtb!" >&2 + fi + fi + if [[ -f $blob ]]; then + # Backup model.dtb + if ! backupdb "/etc.defaults/model.dtb"; then + echo -e "${Error}ERROR${Off} Failed to backup /etc.defaults/model.dtb!" >&2 + else + # Move and rename downloaded model.dtb + if mv "$blob" "/etc.defaults/model.dtb"; then + echo -e "Enabled ${Yellow}$1${Off} in ${Cyan}model.dtb${Off}" >&2 + else + echo -e "${Error}ERROR${Off} Failed to add support for ${1}" >&2 + fi + + # Fix permissions if needed + octal=$(stat -c "%a %n" "/etc.defaults/model.dtb" | cut -d" " -f1) + if [[ ! $octal -eq 644 ]]; then + chmod 644 "/etc.defaults/model.dtb" + fi + fi + else + #echo -e "${Error}ERROR${Off} Missing file ${modelname}_model.dtb" >&2 + echo -e "${Error}ERROR${Off} Missing file $blob" >&2 + fi else - echo -e "${Error}ERROR 5${Off} Failed to enable $1 for ${modelname}!" >&2 + echo -e "\n${Cyan}Contact 007revad to get an edited model.dtb file for your model.${Off}" >&2 fi else - echo -e "$1 already enabled for $modelname" >&2 + echo -e "${Yellow}$1${Off} already enabled in ${Cyan}model.dtb${Off}" >&2 fi fi } -for c in "${!m2cards[@]}"; do - echo "" +for c in "${m2cards[@]}"; do + #echo "" m2cardconf="/usr/syno/etc.defaults/adapter_cards.conf" case "$c" in E10M20-T1) - enable_card "$m2cardconf" E10M20-T1_sup_nvme - enable_card "$m2cardconf" E10M20-T1_sup_sata + backupdb "$m2cardconf" + echo "" + enable_card "$m2cardconf" E10M20-T1_sup_nic "E10M20-T1 NIC" + enable_card "$m2cardconf" E10M20-T1_sup_nvme "E10M20-T1 NVMe" + enable_card "$m2cardconf" E10M20-T1_sup_sata "E10M20-T1 SATA" + check_modeldtb "$c" ;; M2D20) - enable_card "$m2cardconf" M2D20_sup_nvme + backupdb "$m2cardconf" + echo "" + enable_card "$m2cardconf" M2D20_sup_nvme "M2D20 NVMe" + check_modeldtb "$c" ;; M2D18) - enable_card "$m2cardconf" M2D18_sup_nvme - enable_card "$m2cardconf" M2D18_sup_sata + backupdb "$m2cardconf" + echo "" + enable_card "$m2cardconf" M2D18_sup_nvme "M2D18 NVMe" + enable_card "$m2cardconf" M2D18_sup_sata "M2D18 SATA" + check_modeldtb "$c" ;; M2D17) - enable_card "$m2cardconf" M2D17_sup_sata + backupdb "$m2cardconf" + echo "" + enable_card "$m2cardconf" M2D17_sup_sata "M2D17 SATA" + ;; + *) + echo "Unknown M2 card type: $c" ;; esac done + #------------------------------------------------------------------------------ # Edit /etc.defaults/synoinfo.conf @@ -1232,23 +1356,25 @@ fi if [[ $dsm -gt "6" ]]; then # DSM 6 as has no /proc/meminfo if [[ $ram == "yes" ]]; then # Get total amount of installed memory - IFS=$'\n' read -r -d '' -a array < <(dmidecode -t memory | grep "[Ss]ize") # GitHub issue #86, 87 + #IFS=$'\n' read -r -d '' -a array < <(dmidecode -t memory | grep "[Ss]ize") # GitHub issue #86, 87 + IFS=$'\n' read -r -d '' -a array < <(dmidecode -t memory |\ + grep -E "[Ss]ize: [0-9]+ [MG]{1}[B]{1}$") # GitHub issue #86, 87, 106 if [[ ${#array[@]} -gt "0" ]]; then num="0" while [[ $num -lt "${#array[@]}" ]]; do check=$(printf %s "${array[num]}" | awk '{print $1}') if [[ ${check,,} == "size:" ]]; then - #ramsize=$(printf %s "${array[num]}" | cut -d" " -f2) ramsize=$(printf %s "${array[num]}" | awk '{print $2}') # GitHub issue #86, 87 bytes=$(printf %s "${array[num]}" | awk '{print $3}') # GitHub issue #86, 87 if [[ $ramsize =~ ^[0-9]+$ ]]; then # Check $ramsize is numeric # GitHub issue #86, 87 + if [[ $bytes == "GB" ]]; then # DSM 7.2 dmidecode returned GB + ramsize=$((ramsize * 1024)) # Convert to MB # GitHub issue #107 + fi if [[ $ramtotal ]]; then ramtotal=$((ramtotal +ramsize)) else ramtotal="$ramsize" fi - #else - # echo -e "\n${Error}ERROR${Off} Memory size is not numeric: '$ramsize'" fi fi num=$((num +1)) @@ -1256,28 +1382,41 @@ if [[ $dsm -gt "6" ]]; then # DSM 6 as has no /proc/meminfo fi # Set mem_max_mb to the amount of installed memory setting="$(get_key_value $synoinfo mem_max_mb)" + settingbak="$(get_key_value ${synoinfo}.bak mem_max_mb)" # GitHub issue #107 if [[ $ramtotal =~ ^[0-9]+$ ]]; then # Check $ramtotal is numeric - if [[ $bytes == "GB" ]]; then # DSM 7.2 dmidecode returns GB - ramtotal=$((ramtotal * 1024)) # Convert to MB - fi - if [[ $ramtotal -gt $setting ]]; then + if [[ $ramtotal -gt "$setting" ]]; then synosetkeyvalue "$synoinfo" mem_max_mb "$ramtotal" # Check we changed mem_max_mb setting="$(get_key_value $synoinfo mem_max_mb)" - if [[ $setting == "$ramtotal" ]]; then + if [[ $ramtotal == "$setting" ]]; then #echo -e "\nSet max memory to $ramtotal MB." ramgb=$((ramtotal / 1024)) echo -e "\nSet max memory to $ramtotal GB." else echo -e "\n${Error}ERROR${Off} Failed to change max memory!" fi - elif [[ $setting == "$ramtotal" ]]; then + + elif [[ $setting -gt "$ramtotal" ]] && [[ $setting -gt "$settingbak" ]]; # GitHub issue #107 + then + # Fix setting is greater than both ramtotal and default in syninfo.conf.bak + synosetkeyvalue "$synoinfo" mem_max_mb "$settingbak" + # Check we restored mem_max_mb + setting="$(get_key_value $synoinfo mem_max_mb)" + if [[ $settingbak == "$setting" ]]; then + #echo -e "\nSet max memory to $ramtotal MB." + ramgb=$((ramtotal / 1024)) + echo -e "\nRestored max memory to $ramtotal GB." + else + echo -e "\n${Error}ERROR${Off} Failed to restore max memory!" + fi + + elif [[ $ramtotal == "$setting" ]]; then #echo -e "\nMax memory already set to $ramtotal MB." ramgb=$((ramtotal / 1024)) echo -e "\nMax memory already set to $ramgb GB." - else [[ $setting -lt "$ramtotal" ]] - #echo -e "\nMax memory is set to $ramtotal MB." - ramgb=$((ramtotal / 1024)) + else [[ $ramtotal -lt "$setting" ]] + #echo -e "\nMax memory is set to $setting MB." + ramgb=$((setting / 1024)) echo -e "\nMax memory is set to $ramgb GB." fi else