@ -17,6 +17,10 @@
# https://smarthdd.com/database/
# RECENT CHANGES
# Make DSM read md0 and md1 from SSD drive(s) if internal SSD and HDD are installed.
# https://github.com/007revad/Synology_HDD_db/issues/318
# https://www.techspark.de/speed-up-synology-dsm-with-hdd-ssd/
# https://raid.wiki.kernel.org/index.php/Write-mostly
# TODO
# Enable SMART Attributes button on Storage Manager
@ -25,7 +29,7 @@
# /var/packages/StorageManager/target/ui/storage_panel.js
scriptver = "v3.5.94 "
scriptver = "v3.5.96 "
script = Synology_HDD_db
repo = "007revad/Synology_HDD_db"
scriptname = syno_hdd_db
@ -38,7 +42,7 @@ if [ ! "$(basename "$BASH")" = bash ]; then
fi
# Check script is running on a Synology NAS
if ! /usr/bin/uname -a | grep -i synology >/dev/null ; then
if ! /usr/bin/uname -a | grep -q - i synology; then
echo "This script is NOT running on a Synology NAS!"
echo "Copy the script to a folder on the Synology"
echo "and run it from there."
@ -69,7 +73,15 @@ Options:
DSM 7.2.1 already has WDDA disabled
-p, --pcie Enable creating volumes on M2 in unknown PCIe adaptor
-e, --email Disable colored text in output scheduler emails
--restore Undo all changes made by the script
-S, --ssd= DRIVE Enable write_mostly on slow internal drives so DSM
runs from the fast internal drive( s) .
-S automatically sets internal SSDs as DSM default
--ssd= DRIVE requires the fast drive( s) as argument,
or restore as the argument to set drives to default
--ssd= sata1 or --ssd= sata1,sata2 or --ssd= sda etc
--ssd= sata1 or --ssd= sata1,sata2 or --ssd= sda etc
--ssd= restore
--restore Undo all changes made by the script ( except -S --ssd)
--autoupdate= AGE Auto update script ( useful when script is scheduled)
AGE is how many days old a release must be before
auto-updating. AGE must be a number: 0 or greater
@ -96,12 +108,12 @@ args=("$@")
# Check for flags with getopt
if options = " $( getopt -o abcdefghijklmnopqrstuvwxyz0123456789 -l \
restore,showedits,noupdate,nodbupdate,m2,force,incompatible,ram,pcie,wdda,email,autoupdate:,help,version,debug \
if options = " $( getopt -o S abcdefghijklmnopqrstuvwxyz0123456789 -l \
ssd:, restore,showedits,noupdate,nodbupdate,m2,force,incompatible,ram,pcie,wdda,email,autoupdate:,help,version,debug \
-- " $@ " ) " ; then
eval set -- " $options "
while true; do
case " ${ 1 ,, } " in
case " $ 1" in
--restore) # Restore changes from backups
restore = yes
break
@ -109,6 +121,20 @@ if options="$(getopt -o abcdefghijklmnopqrstuvwxyz0123456789 -l \
-s| --showedits) # Show edits done to host db file
showedits = yes
; ;
-S) # Enable writemostly for md0 and md1
ssd = yes
; ;
--ssd) # Enable writemostly for md0 and md1
ssd = yes
if [ [ ${ 2 ,, } = = "restore" ] ] ; then
ssd_restore = yes
else
IFS = $','
for d in $2 ; do ssds_writemostly += ( " ${ d ,, } " ) ; done
unset IFS
fi
shift
; ;
-n| --nodbupdate| --noupdate) # Disable disk compatibility db updates
nodbupdate = yes
; ;
@ -337,7 +363,7 @@ scriptvol=$(echo "$scriptpath" | cut -d"/" -f2)
vg = $( lvdisplay | grep /volume_" ${ scriptvol #volume } " | cut -d"/" -f3)
md = $( pvdisplay | grep -B 1 -E '[ ]' " $vg " | grep /dev/ | cut -d"/" -f3)
# shellcheck disable=SC2002 # Don't warn about "Useless cat"
if cat /proc/mdstat | grep " $md " | grep nvme >/dev/null ; then
if cat /proc/mdstat | grep " $md " | grep -q nvme; then
echo -e " \n ${ Yellow } WARNING ${ Off } Don't store this script on an NVMe volume! "
fi
@ -734,7 +760,7 @@ set_vendor(){
if [ [ $vendor ] ] ; then
# DS1817+, DS1517+, RS1219+, RS818+ don't have pci_vendor_ids.conf
if [ [ " $vidfile " ] ] ; then
if ! grep " $vid " " $vidfile " >/dev/null ; then
if ! grep -q " $vid " " $vidfile " ; then
/usr/syno/bin/synosetkeyvalue " $vidfile " " ${ vid ,, } " " $vendor "
val = $( /usr/syno/bin/synogetkeyvalue " $vidfile " " ${ vid ,, } " )
if [ [ $val = = " ${ vendor } " ] ] ; then
@ -743,7 +769,7 @@ set_vendor(){
echo -e " \nFailed to add $vendor to pci_vendor_ids! " >& 2
fi
fi
if ! grep " $vid " " $vidfile2 " >/dev/null ; then
if ! grep -q " $vid " " $vidfile2 " ; then
/usr/syno/bin/synosetkeyvalue " $vidfile2 " " ${ vid ,, } " " $vendor "
fi
@ -751,10 +777,10 @@ set_vendor(){
if [ [ ${# vid } -eq "5" ] ] ; then
vid = " 0x0 ${ vid : -3 } "
fi
if ! grep " $vid " " $vidfile " >/dev/null ; then
if ! grep -q " $vid " " $vidfile " ; then
/usr/syno/bin/synosetkeyvalue " $vidfile " " ${ vid ,, } " " $vendor "
fi
if ! grep " $vid " " $vidfile2 " >/dev/null ; then
if ! grep -q " $vid " " $vidfile2 " ; then
/usr/syno/bin/synosetkeyvalue " $vidfile2 " " ${ vid ,, } " " $vendor "
fi
@ -1085,6 +1111,7 @@ else
echo
fi
#------------------------------------------------------------------------------
# Check databases and add our drives if needed
@ -1123,10 +1150,10 @@ fi
getdbtype( ) {
# Detect drive db type
# Synology misspelt compatibility as compatbility
if grep -F '{"disk_compatbility_info":' " $1 " >/dev/null ; then
if grep -q - F '{"disk_compatbility_info":' " $1 " ; then
# DSM 7 drive db files start with {"disk_compatbility_info":
dbtype = 7
elif grep -F '{"success":1,"list":[' " $1 " >/dev/null ; then
elif grep -q - F '{"success":1,"list":[' " $1 " ; then
# DSM 6 drive db files start with {"success":1,"list":[
dbtype = 6
else
@ -1242,7 +1269,7 @@ updatedb(){
if [ [ $dbtype -gt "6" ] ] ; then
# db type 7 used from DSM 7.1 and later
if grep " $hdmodel " '":{"' " $fwrev " " $2 " >/dev/null ; then
if grep -q " $hdmodel " '":{"' " $fwrev " " $2 " ; then
echo -e " ${ Yellow } $hdmodel ${ Off } already exists in ${ Cyan } $( basename -- " $2 " ) ${ Off } " >& 2
else
common_string = \" size_gb\" :$size_gb ,
@ -1264,13 +1291,13 @@ updatedb(){
default = " $default " } ] } } }
# Synology misspelt compatibility as compatbility
if grep '"disk_compatbility_info":{}' " $2 " >/dev/null ; then
if grep -q '"disk_compatbility_info":{}' " $2 " ; then
# Replace "disk_compatbility_info":{} with
# "disk_compatbility_info":{"WD40PURX-64GVNY0":{"80.00A80":{ ... }}},"default":{ ... }}}}
#echo "Edit empty db file:" # debug
editdb7 "empty" " $2 "
elif grep '"' " $hdmodel " '":' " $2 " >/dev/null ; then
elif grep -q '"' " $hdmodel " '":' " $2 " ; then
# Replace "WD40PURX-64GVNY0":{ with "WD40PURX-64GVNY0":{"80.00A80":{ ... }}},
#echo "Insert firmware version:" # debug
editdb7 "insert" " $2 "
@ -1283,25 +1310,25 @@ updatedb(){
fi
# Edit existing drives in db with compatibility:unverified # Issue #224
if grep 'unverified' " $2 " >/dev/null ; then
if grep -q 'unverified' " $2 " ; then
sed -i 's/unverified/support/g' " $2 "
if ! grep 'unverified' " $2 " >/dev/null ; then
if ! grep -q 'unverified' " $2 " ; then
echo -e " Edited unverified drives in ${ Cyan } $( basename -- " $2 " ) ${ Off } " >& 2
fi
fi
# Edit existing drives in db with compatibility:not_support
if [ [ $incompatible = = "yes" ] ] ; then
if grep 'not_support' " $2 " >/dev/null ; then
if grep -q 'not_support' " $2 " ; then
sed -i 's/not_support/support/g' " $2 "
if ! grep 'not_support' " $2 " >/dev/null ; then
if ! grep -q 'not_support' " $2 " ; then
echo -e " Edited incompatible drives in ${ Cyan } $( basename -- " $2 " ) ${ Off } " >& 2
fi
fi
fi
elif [ [ $dbtype -eq "6" ] ] ; then
# db type 6 used up to DSM 7.0.1
if grep " $hdmodel " " $2 " >/dev/null ; then
if grep -q " $hdmodel " " $2 " ; then
echo -e " ${ Yellow } $hdmodel ${ Off } already exists in ${ Cyan } $( basename -- " $2 " ) ${ Off } " >& 2
else
# example:
@ -1402,7 +1429,7 @@ enable_card(){
backupdb " $adapter_cards2 " long
# Check if section exists
if ! grep '^\[' " $2 " '\]$' " $1 " >/dev/null ; then
if ! grep -q '^\[' " $2 " '\]$' " $1 " ; then
echo -e " Section [ $2 ] not found in $( basename -- " $1 " ) ! " >& 2
return
fi
@ -1608,7 +1635,7 @@ edit_modeldtb(){
# Edit model.dts
for c in " ${ cards [@] } " ; do
# Edit model.dts if needed
if ! grep " $c " " $dtb_file " >/dev/null ; then
if ! grep -q " $c " " $dtb_file " ; then
dts_m2_card " $c " " $dts_file "
echo -e " Added ${ Yellow } $c ${ Off } to ${ Cyan } model ${ hwrev } .dtb ${ Off } " >& 2
else
@ -1663,6 +1690,91 @@ for c in "${m2cards[@]}"; do
done
#------------------------------------------------------------------------------
# Set or restore writemostly
set_writemostly( ) {
# $1 is writemostly or in_sync
# $2 is sata1 or sas1 or sda etc
if [ [ ${ 1 : : 2 } = = "sd" ] ] ; then
# sda etc
# md0 DSM system partition
echo " $1 " > /sys/block/md0/md/dev-" ${ 2 } " 1/state
# Show setting
echo -n " $2 DSM partition: "
cat /sys/block/md0/md/dev-" ${ 2 } " 1/state
# md1 DSM swap partition
echo " $1 " > /sys/block/md1/md/dev-" ${ 2 } " 2/state
# Show setting
echo -n " $2 Swap partition: "
cat /sys/block/md1/md/dev-" ${ 2 } " 2/state
else
# sata1 or sas1 etc
# md0 DSM system partition
echo " $1 " > /sys/block/md0/md/dev-" ${ 2 } " p1/state
# Show setting
echo -n " $2 DSM partition: "
cat /sys/block/md0/md/dev-" ${ 2 } " p1/state
# md1 DSM swap partition
echo " $1 " > /sys/block/md1/md/dev-" ${ 2 } " p2/state
# Show setting
echo -n " $2 Swap partition: "
cat /sys/block/md1/md/dev-" ${ 2 } " p2/state
fi
}
if [ [ $ssd = = "yes" ] ] ; then
# Get array of internal drives
readarray -t internal_drives < <( synodisk --enum -t internal | grep 'Disk path' | cut -d"/" -f3)
if [ [ $ssd_restore = = "yes" ] ] ; then
# Restore all internal drives to just in_sync
echo -e "\nRestoring internal drive's state:"
for idrive in " ${ internal_drives [@] } " ; do
#if ! grep -q "write_mostly"; then
set_writemostly -writemostly " $idrive "
#fi
done
elif [ [ ${# ssds_writemostly [@] } -gt "0" ] ] ; then
# User specified their fast drive(s)
echo -e "\nSetting slow internal HDDs state to write_mostly:"
for idrive in " ${ internal_drives [@] } " ; do
if [ [ ! ${ ssds_writemostly [*] } = ~ $idrive ] ] ; then
set_writemostly writemostly " $idrive "
fi
done
else
# Get list of internal HDDs and qty of SSDs
internal_ssd_qty = "0"
for idrive in " ${ internal_drives [@] } " ; do
internal_drive = " $( echo " $idrive " | awk '{printf $4}' ) "
if synodisk --isssd " $internal_drive " >/dev/null; then
# exit code 0 = is not SSD
# exit code 1 = is SSD
# Add internal HDDs to array
internal_hdds += ( " $internal_drive " )
else
# Count number of internal 2.5 inch SSDs
internal_ssd_qty = $(( internal_ssd_qty + 1 ))
fi
done
# Set HDDs to writemostly if there's also internal SSDs
if [ [ $internal_ssd_qty -gt "0" ] ] && [ [ ${# internal_hdds [@] } -gt "0" ] ] ; then
# There are internal SSDs and HDDs
echo -e "\nSetting internal HDDs state to write_mostly:"
for idrive in " ${ internal_hdds [@] } " ; do
set_writemostly writemostly " $idrive "
done
fi
fi
fi
#------------------------------------------------------------------------------
# Edit /etc.defaults/synoinfo.conf
@ -1836,7 +1948,7 @@ fi
# Enable nvme support
# shellcheck disable=SC2010 # Don't warn about "Don't use ls | grep"
if ls /dev | grep nvme >/dev/null ; then
if ls /dev | grep -q nvme; then
if [ [ $m2 != "no" ] ] ; then
# Check if nvme support is enabled
setting = " $( /usr/syno/bin/synogetkeyvalue $synoinfo supportnvme) "
@ -1868,7 +1980,7 @@ fi
# Enable m2 volume support
# shellcheck disable=SC2010 # Don't warn about "Don't use ls | grep"
if ls /dev | grep "nv[em]" >/dev/null ; then
if ls /dev | grep -q "nv[em]" ; then
if [ [ $m2 != "no" ] ] ; then
if [ [ $m2exists = = "yes" ] ] ; then
# Check if m2 volume support is enabled
@ -1971,7 +2083,7 @@ if [[ -f "$strgmgr" ]] && [[ $buildnumber -gt 42962 ]]; then
# DSM 7.2 and later
if [ [ ${# m2cards [@] } -gt "0" ] ] || [ [ $forcepci = = "yes" ] ] ; then
if grep 'notSupportM2Pool_addOnCard' " $strgmgr " >/dev/null ; then
if grep -q 'notSupportM2Pool_addOnCard' " $strgmgr " ; then
# Backup storage_panel.js"
if [ [ $buildnumber -gt 64570 ] ] ; then
@ -1994,7 +2106,7 @@ if [[ -f "$strgmgr" ]] && [[ $buildnumber -gt 42962 ]]; then
sed -i 's/notSupportM2Pool_addOnCard:this.T("disk_info","disk_reason_m2_add_on_card"),//g' " $strgmgr "
sed -i 's/},{isConditionInvalid:0<this.pciSlot,invalidReason:"notSupportM2Pool_addOnCard"//g' " $strgmgr "
# Check if we edited file
if ! grep 'notSupportM2Pool_addOnCard' " $strgmgr " >/dev/null ; then
if ! grep -q 'notSupportM2Pool_addOnCard' " $strgmgr " ; then
echo -e "Enabled creating pool on drives in M.2 adaptor card."
else
echo -e " ${ Error } ERROR ${ Off } Failed to enable creating pool on drives in M.2 adaptor card! "
@ -2052,3 +2164,4 @@ if [[ $dsm -eq "6" ]] || [[ $rebootmsg == "yes" ]]; then
fi
exit