Browse Source

Update syno_hdd_db.sh

Bug fix for SAS drives that work with hdparm.
develop
007revad 3 years ago
committed by GitHub
parent
commit
0729382798
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 276
      syno_hdd_db.sh

276
syno_hdd_db.sh

@ -18,27 +18,83 @@
# sudo /volume1/scripts/syno_hdd_db.sh # sudo /volume1/scripts/syno_hdd_db.sh
# or # or
# sudo /volume1/scripts/syno_hdd_db.sh -showedits # sudo /volume1/scripts/syno_hdd_db.sh -showedits
# or
# sudo /volume1/scripts/syno_hdd_db.sh -force -showedits
#-------------------------------------------------------------------------------------------------- #--------------------------------------------------------------------------------------------------
# TODO # TODO
# Detect if expansion unit(s) connected and get model(s) and edit expansion unit db files. # 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 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. # 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 # 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. # Add support for NVMe drives.
#
# Prevent DSM auto updating the drive database.
#
# Optionally disable "support_disk_compatibility".
scriptver="1.1.9"
# 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 # Check for flags with getopts
if [[ ${1,,} == "-s" ]] || [[ ${1,,} == "-showedits" ]]; then showedits=yes; fi 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=$(cat /proc/sys/kernel/syno_hw_version)
model=${model,,} # convert to lower case model=${model,,} # convert to lower case
# Check for -j after model - GitHub issue #2 # Check for -j after model - GitHub issue #2
if [[ $model =~ '-j'$ ]]; then if [[ $model =~ '-j'$ ]]; then
model=${model%??} # remove last to chars model=${model%??} # remove last two chars
fi fi
# Get DSM major version # Get DSM major version
@ -55,60 +111,109 @@ fi
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Get list of installed HDDs and SATA SSDs # Get list of installed SATA, SAS and NVMe drives
# SATA drives, sata1, sata2 etc getModel() {
for drive in /dev/sata*; do hdmodel=$(smartctl -i "$1" | grep -i "Device Model:" | awk '{print $3 $4 $5}')
if [[ $drive =~ /dev/sata[1-9][0-9]?[0-9]?$ ]]; then if [[ ! $hdmodel ]]; then
tmp=$(hdparm -i "$drive" | grep Model) hdmodel=$(smartctl -i "$1" | grep -i "Product:" | awk '{print $2 $3 $4}')
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 fi
#echo "Model: $hdmodel" # debug
# Brands that return "BRAND <model>" 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
# Add extra model without "WDC " to fix issue #1
if [[ $hdmodel =~ ^WDC.* ]]; then
hdmodel2=${hdmodel#"WDC "} # Remove "WDC " from start
#echo "$hdmodel2" " Without 'WDC ' brand" # debug
shopt -s extglob shopt -s extglob
hdmodel2=${hdmodel2/#*([[:space:]])} # Remove leading spaces hdmodel=${hdmodel/#*([[:space:]])} # Remove leading spaces
#echo "$hdmodel2" " Without leading spaces" # debug hdmodel=${hdmodel/%*([[:space:]])} # Remove trailing spaces
shopt -u extglob shopt -u extglob
if [[ $hdmodel2 ]] && [[ $fwrev ]]; then #echo "Model: $hdmodel" # debug
hdparm+=("${hdmodel2},${fwrev}") }
fi
fi
getFwVersion() {
if [[ $2 == "sas" ]]; then
# hdparm does not work with some SAS drives
fwrev=$(smartctl -i "$1" | grep -i "Firmware Version:" | awk '{print $3}')
if [[ ! $hdmodel ]]; then
fwrev=$(smartctl -i "$1" | grep -i "Revision:" | awk '{print $2}')
fi fi
done else
tmp=$(hdparm -i "$1" | grep Model)
# SATA drives sda, sdb etc
for drive in /dev/sd*; do
if [[ $drive =~ /dev/sd[a-z]{1,3}$ ]]; 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) fwrev=$(printf %s "$tmp" | cut -d"," -f 2 | cut -d"=" -f 2)
if [[ $hdmodel ]] && [[ $fwrev ]]; then
hdparm+=("${hdmodel},${fwrev}")
fi fi
#echo "Firmware: $fwrev" # debug
}
# Add extra model without "WDC " to fix issue #1 getNVMeModel() {
if [[ $hdmodel =~ ^WDC.* ]]; then nvmemodel=$(cat $1/model)
hdmodel2=${hdmodel#"WDC "} # Remove "WDC " from start
#echo "$hdmodel2" " Without 'WDC ' brand" # debug
shopt -s extglob shopt -s extglob
hdmodel2=${hdmodel2/#*([[:space:]])} # Remove leading spaces nvmemodel=${nvmemodel/#*([[:space:]])} # Remove leading spaces
#echo "$hdmodel2" " Without leading spaces" # debug nvmemodel=${nvmemodel/%*([[:space:]])} # Remove trailing spaces
shopt -u extglob shopt -u extglob
if [[ $hdmodel2 ]] && [[ $fwrev ]]; then #echo "NVMe Model: $nvmemodel" # debug
hdparm+=("${hdmodel2},${fwrev}") }
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 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
fi fi
;;
sas*|sata*)
if [[ $d =~ (sas|sata)[0-9][0-9]?[0-9]?$ ]]; then
#echo -e "\n$d" # debug
getModel "/dev/$d"
if [[ $d =~ (sas)[0-9][0-9]?[0-9]?$ ]]; then
# hdparm does not work with some SAS drives
getFwVersion "/dev/$d" "sas"
else
getFwVersion "/dev/$d"
fi
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 done
# Sort hdparm array into new hdds array to remove duplicates # Sort hdparm array into new hdds array to remove duplicates
if [[ ${#hdparm[@]} -gt "0" ]]; then if [[ ${#hdparm[@]} -gt "0" ]]; then
while IFS= read -r -d '' x; do while IFS= read -r -d '' x; do
@ -130,25 +235,6 @@ else
fi 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)
nvmemodel=$(echo "$nvmemodel" | xargs) # trim leading and trailing white space
#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 # Sort nvmelist array into new nvmes array to remove duplicates
if [[ ${#nvmelist[@]} -gt "0" ]]; then if [[ ${#nvmelist[@]} -gt "0" ]]; then
while IFS= read -r -d '' x; do while IFS= read -r -d '' x; do
@ -156,7 +242,7 @@ if [[ $express ]]; then
done < <(printf "%s\0" "${nvmelist[@]}" | sort -uz) done < <(printf "%s\0" "${nvmelist[@]}" | sort -uz)
fi fi
# Check hdds array isn't empty # Check nvmes array isn't empty
if [[ ${#nvmes[@]} -eq "0" ]]; then if [[ ${#nvmes[@]} -eq "0" ]]; then
echo -e "No NVMe drives found\n" echo -e "No NVMe drives found\n"
else else
@ -168,7 +254,6 @@ if [[ $express ]]; then
done done
echo echo
fi fi
fi
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -251,23 +336,82 @@ while [[ $num -lt "${#nvmes[@]}" ]]; do
done done
# Optionally disable "support_disk_compatibility"
sdc=support_disk_compatibility
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"
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 # Show the changes
if [[ ${showedits,,} == "yes" ]]; then if [[ ${showedits,,} == "yes" ]]; then
lines=$(((db2Edits *12) +4)) lines=$(((db2Edits *12) +4))
if [[ $db1Edits -gt "0" ]]; then if [[ $db1Edits -gt "0" ]]; then
#echo -e "\nChanges to $(basename -- "$db1")"
echo -e "\nChanges to ${Cyan}$(basename -- "$db1")${Off}" 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 jq . "$db1" | tail -n "$lines" # show last 20 lines per edit
fi fi
if [[ $db2Edits -gt "0" ]]; then if [[ $db2Edits -gt "0" ]]; then
#echo -e "\nChanges to $(basename -- "$db2")"
echo -e "\nChanges to ${Cyan}$(basename -- "$db2")${Off}" 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 jq . "$db2" | tail -n "$lines" # show last 20 lines per edit
fi fi
fi fi
echo -e "\nYou may need to ${Cyan}reboot the Synology${Off} to see the changes."
exit exit

Loading…
Cancel
Save