@ -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/<script-name>
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