CS01-HS Posted May 22, 2020 Share Posted May 22, 2020 (edited) I have a USB HDD in unassigned devices which I use for backups. The drive won't spin down for whatever reason, mounted or not. My solution was a modified version of this script that I have User Scripts run every hour. It takes a list of drives, checks for activity and spins them down if they're inactive and spun up. I thought I'd share it. NOTE: The green "led" in Unassigned Devices stays green even when the drive's spun down, I don't know how or if it detects power status. #!/bin/bash # This script looks for recent disk access, and if nothing has changed, puts /dev/disk/by-id/${drive} into spindown mode. # # Set your drive identifiers (listed in /dev/disk/by-id/) ignoring characters after the last "-" # e.g. listing: usb-WD_My_Passport_25E2_75831314363630505A37-0:0 # becomes: usb-WD_My_Passport_25E2_75831314363630505A37 drives=( "<DRIVE_IDENTIFIER_1>" "<DRIVE_IDENTIFIER_2>" ) # spindown delay in minutes SPINDOWN_DELAY=30 # Uncomment to enable debug mode #DEBUG=true # Set the directory where the status files will be stored, # /tmp/ is a fine default STATUS_DIR="/tmp" current=`date` # create status_dir if it doesn't exist mkdir -p ${STATUS_DIR} do_device() { local device_id=$1 device=`ls -l /dev/disk/by-id/ | grep ${device_id} | head -1 | tail -c4` filename="${STATUS_DIR}/diskaccess-${device_id}.status" is_awake=`smartctl --nocheck standby -i /dev/${device} | grep 'Power mode is' | egrep -c 'ACTIVE|IDLE'` if [ "${is_awake}" == "1" ]; then if [ "$DEBUG" = true ]; then echo "${device} is awake" fi stat_new=$(grep "${device}1 " /proc/diskstats | tr -dc "[:digit:]") if [ ! -f "${filename}" ]; then echo ${current} "- ${filename} file does not exist; creating it now." echo ${stat_new} > ${filename} else stat_old=`cat ${filename} | tr -dc "[:digit:]"` # calculate minutes since last update to see if we should sleep current_time=$(date +%s) last_mod=$(stat ${filename} -c %Y) seconds_ago=$(expr $current_time - $last_mod) minutes_ago=$(expr $seconds_ago / 60) if [ "$DEBUG" = true ]; then echo "${device} old stat: ${stat_old}" echo "${device} new stat: ${stat_new}" echo "${device} new stat modified ${minutes_ago} minutes ago" fi if [ "${stat_old}" == "${stat_new}" ]; then if [ $minutes_ago -ge $SPINDOWN_DELAY ]; then echo ${current} "- Drive /dev/${device} is awake and hasn't been used in ${minutes_ago} minutes; spinning down" hdparm -y /dev/${device} > /dev/null 2>&1 else echo ${current} "- Drive /dev/${device} was last used ${minutes_ago} minutes ago, less than spindown setting ($SPINDOWN_DELAY)" fi else echo ${current} "- Drive /dev/${device} has been used..." echo ${stat_new} > ${filename} fi fi else if [ "$DEBUG" = true ]; then echo "${device} is asleep" fi fi } for device_id in ${drives[*]} do do_device ${device_id} done Edited August 12, 2021 by CS01-HS updated to work with 6.9.0-beta30 1 Quote Link to comment
CS01-HS Posted October 12, 2020 Author Share Posted October 12, 2020 Updated the script to work with with 6.9.0-beta30 I don't know if it's the new kernel or unraid itself but now the drive's diskstats seem to increment even without access (maybe SMART polling?) Keying off the partition's diskstats seems to solve it. Note, this looks for reads/writes on the first partition - if you have a multi-partition drive it won't work properly (and may sleep you drive while you're accessing it,) Quote Link to comment
jinlife Posted August 12, 2021 Share Posted August 12, 2021 Thanks for the great script. But my unraid has problem that the USB HDD spin up unexpected every hours, so the script runs every hours and I can see the HDD is always awake in the script log. I have already unmounted the USB HDD but don't know why it is still awaken frequently. Any suggestions? Quote Link to comment
CS01-HS Posted August 12, 2021 Author Share Posted August 12, 2021 (edited) On 8/11/2021 at 9:18 PM, jinlife said: Thanks for the great script. But my unraid has problem that the USB HDD spin up unexpected every hours, so the script runs every hours and I can see the HDD is always awake in the script log. I have already unmounted the USB HDD but don't know why it is still awaken frequently. Any suggestions? You say the USB HDD spins up every hour, so it must be spinning down. Is it spinning down on its own or is my script spinning it down? You could try disabling the USB HDD's internal power management: Find the disk's ID with: find /dev/disk/by-id/ ! -name '*-part1' The line for your USB disk will look like: /dev/disk/by-id/usb-XXXXXX Take that and disable power management with the command: /usr/sbin/smartctl -s apm,off /dev/disk/by-id/usb-XXXXXX If that fixes it add the command exactly the way you ran it to your /boot/config/go because reboot resets it. Edited August 14, 2021 by CS01-HS Quote Link to comment
jinlife Posted August 12, 2021 Share Posted August 12, 2021 I use the script to spin down the disk and the disk was also unmounted before, so there should be no activity on the disk. But it always spin up unexpectedly, so even I scheduled to run the script every hour, the disk is always awaken. It is endless loop: up, down, up, down ... I will try to disable power management and get back to you about the result. Really appreciate for the help. Quote Link to comment
jinlife Posted August 12, 2021 Share Posted August 12, 2021 (edited) Bad news, it still work like before even disabled the power management. Run this script and disk will spin down, but the standy mode will only last for 20~30 minutes, then it will spin up unexpectly, then the script will spin down it again... There is no log in syslog. Edited August 12, 2021 by jinlife Quote Link to comment
dlandon Posted August 12, 2021 Share Posted August 12, 2021 You can't spin the disk down that way. Unraid controls the spin up/down of the disk in later versions of 6.9 and 6.10. You are confusing Unraid. Go to the UD web page and look at the help you'll see a command to spin down the disk using the UD script that uses the Unraid api. Unraid then knows the proper spin status. Quote Link to comment
CS01-HS Posted August 12, 2021 Author Share Posted August 12, 2021 (edited) 3 hours ago, dlandon said: You can't spin the disk down that way. Unraid controls the spin up/down of the disk in later versions of 6.9 and 6.10. You are confusing Unraid. Go to the UD web page and look at the help you'll see a command to spin down the disk using the UD script that uses the Unraid api. Unraid then knows the proper spin status. Thanks, I see this command in help: /usr/local/sbin/rc.unassigned spindown devX I wish I'd known about it earlier, still the script worked well for me in 6.8 and 6.9. 4 hours ago, jinlife said: Bad news, it still work like before even disabled the power management. Run this script and disk will spin down, but the standy mode will only last for 20~30 minutes, then it will spin up unexpectly, then the script will spin down it again... There is no log in syslog. jinlife: I'd say disable the script for now, unmount the drive, run the command above where "devX is the device name in the UD page. If the device name is 'Dev 1', then use dev1 as the device to spin down." Edited August 12, 2021 by CS01-HS corrected per post below Quote Link to comment
dlandon Posted August 12, 2021 Share Posted August 12, 2021 You didn't do the command correctly: /usr/local/sbin/rc.unassigned spindown devX' - spin down a disk. The devX is the device name in the UD page. If the device name is 'Dev 1', then use dev1 as the device to spin down. SSDs will not spin down. Use devX, not sdX. Besides being incorrect for rc.unassigned, the sdX can change after a reboot and you'd reference the wrong disk. The spin down of UD disks was changed in a later version of 6.9rc. 1 Quote Link to comment
jinlife Posted August 13, 2021 Share Posted August 13, 2021 (edited) Good to know that. Thanks guys. The script is good for old Unraid versions. I will try the new command. Thanks again. Edited August 13, 2021 by jinlife Quote Link to comment
jinlife Posted August 16, 2021 Share Posted August 16, 2021 (edited) On 8/13/2021 at 8:08 AM, jinlife said: Good to know that. Thanks guys. The script is good for old Unraid versions. I will try the new command. Thanks again. Just add some comments here, in case someone has same requirement, I want to spindown my NTFS formated USB HDD mounted by UHD plugin. 1. Unraid 6.8.x with this script, it works, but it will spinup by Unraid after 20~30 minutes later. No log at all. 2. Unraid 6.9.2, no need to use this script. Unraid will manage USB HDD automatically, including Array and Unassigned disk. But it will spinup USB HDD after 20~30 minutes with log "emhttpd: read SMART". Looks like tons of complaints in the forum with no solution but revert back to 6.9.1 3. Unraid 6.9.1, just works like 6.9.2 but it won't spinup USB HDD, it is the perfect solution to me now. Edited August 16, 2021 by jinlife 1 Quote Link to comment
CS01-HS Posted August 16, 2021 Author Share Posted August 16, 2021 To add further complication behavior seems to depend on the particular USB drive/controller. This script worked (and was necessary) for me for all 6.8.X and 6.9.X versions. I don't know about 6.10 because I've switched from USB to an odroid HC2 (nice little machine.) If I remember right unraid had issues tracking spindown state because my drive (WD Passport) would exit with an error code from hdparm -C /dev/sdX - something about "bad/missing sense" but that indicated it was actually spun down. smartctl worked properly however. To work around it I modified unRAID's sdspin to ignore that particular error and prefer smartctl to hdparm with USB drives. In /boot/config/go I put: # Custom sdspin (to handle substandard USB drive controller) cp /usr/local/sbin/sdspin /usr/local/sbin/sdspin.unraid cp /boot/extras/utilities/sdspin /usr/local/sbin/sdspin chmod 755 /usr/local/sbin/sdspin where /boot/extras/utilities/sdspin was my customized version: #!/bin/bash # spin device up or down or get spinning status # $1 device name # $2 up or down or status # ATA only # hattip to Community Dev @doron RDEVNAME=/dev/${1#'/dev/'} # So that we can be called with either "sdX" or "/dev/sdX" get_device_id () { LABEL="${RDEVNAME:5}" DEVICE_ID=`ls -l /dev/disk/by-id/ | grep -v " wwn-" | grep "${LABEL}$" | rev | cut -d ' ' -f3 | rev` echo "$DEVICE_ID" } smartctl_status () { OUTPUT=$(/usr/sbin/smartctl --nocheck standby -i $RDEVNAME 2>&1) RET=$? # Ignore Bit 1 error (Device open failed) which usually indicates standby [[ $RET == 2 && $(($RET & 2)) == 2 ]] && RET=0 } hdparm () { OUTPUT=$(/usr/sbin/hdparm $1 $RDEVNAME 2>&1) RET=$? # ignore missing sense warning which might be caused by a substandard USB interface if [[ ! "$(get_device_id)" =~ ^usb-.* ]]; then [[ $RET == 0 && ${OUTPUT,,} =~ "bad/missing sense" ]] && RET=1 fi } if [[ "$2" == "up" ]]; then hdparm "-S0" elif [[ "$2" == "down" ]]; then hdparm "-y" else # use smartctl (instead of hdparm) for USB drives if [[ "$(get_device_id)" =~ ^usb-.* ]]; then smartctl_status else hdparm "-C" fi [[ $RET == 0 && ${OUTPUT,,} =~ "standby" ]] && RET=2 fi Very hacky. Quote Link to comment
sergiu.topan Posted January 25 Share Posted January 25 On 5/22/2020 at 4:43 PM, CS01-HS said: I have a USB HDD in unassigned devices which I use for backups. The drive won't spin down for whatever reason, mounted or not. My solution was a modified version of this script that I have User Scripts run every hour. It takes a list of drives, checks for activity and spins them down if they're inactive and spun up. I thought I'd share it. NOTE: The green "led" in Unassigned Devices stays green even when the drive's spun down, I don't know how or if it detects power status. #!/bin/bash # This script looks for recent disk access, and if nothing has changed, puts /dev/disk/by-id/${drive} into spindown mode. # # Set your drive identifiers (listed in /dev/disk/by-id/) ignoring characters after the last "-" # e.g. listing: usb-WD_My_Passport_25E2_75831314363630505A37-0:0 # becomes: usb-WD_My_Passport_25E2_75831314363630505A37 drives=( "<DRIVE_IDENTIFIER_1>" "<DRIVE_IDENTIFIER_2>" ) # spindown delay in minutes SPINDOWN_DELAY=30 # Uncomment to enable debug mode #DEBUG=true # Set the directory where the status files will be stored, # /tmp/ is a fine default STATUS_DIR="/tmp" current=`date` # create status_dir if it doesn't exist mkdir -p ${STATUS_DIR} do_device() { local device_id=$1 device=`ls -l /dev/disk/by-id/ | grep ${device_id} | head -1 | tail -c4` filename="${STATUS_DIR}/diskaccess-${device_id}.status" is_awake=`smartctl --nocheck standby -i /dev/${device} | grep 'Power mode is' | egrep -c 'ACTIVE|IDLE'` if [ "${is_awake}" == "1" ]; then if [ "$DEBUG" = true ]; then echo "${device} is awake" fi stat_new=$(grep "${device}1 " /proc/diskstats | tr -dc "[:digit:]") if [ ! -f "${filename}" ]; then echo ${current} "- ${filename} file does not exist; creating it now." echo ${stat_new} > ${filename} else stat_old=`cat ${filename} | tr -dc "[:digit:]"` # calculate minutes since last update to see if we should sleep current_time=$(date +%s) last_mod=$(stat ${filename} -c %Y) seconds_ago=$(expr $current_time - $last_mod) minutes_ago=$(expr $seconds_ago / 60) if [ "$DEBUG" = true ]; then echo "${device} old stat: ${stat_old}" echo "${device} new stat: ${stat_new}" echo "${device} new stat modified ${minutes_ago} minutes ago" fi if [ "${stat_old}" == "${stat_new}" ]; then if [ $minutes_ago -ge $SPINDOWN_DELAY ]; then echo ${current} "- Drive /dev/${device} is awake and hasn't been used in ${minutes_ago} minutes; spinning down" hdparm -y /dev/${device} > /dev/null 2>&1 else echo ${current} "- Drive /dev/${device} was last used ${minutes_ago} minutes ago, less than spindown setting ($SPINDOWN_DELAY)" fi else echo ${current} "- Drive /dev/${device} has been used..." echo ${stat_new} > ${filename} fi fi else if [ "$DEBUG" = true ]; then echo "${device} is asleep" fi fi } for device_id in ${drives[*]} do do_device ${device_id} done I tried this script and I noticed that doesn't detect properly when the drive is being used and every time I try to run it the drives are spinning down and up. I use unraid 6.12.6. After further investigation I changed stat_new=$(grep "${device}1 " /proc/diskstats | tr -dc "[:digit:]") to stat_new=$(grep "${device} " /proc/diskstats | tr -dc "[:digit:]") In this way it search for ativity on the drive not partition and like this is working properly. 1 Quote Link to comment
CS01-HS Posted February 12 Author Share Posted February 12 On 1/25/2024 at 4:22 AM, sergiu.topan said: In this way it search for ativity on the drive not partition and like this is working properly. That's how I had it initially: On 10/12/2020 at 6:05 PM, CS01-HS said: Updated the script to work with with 6.9.0-beta30 I don't know if it's the new kernel or unraid itself but now the drive's diskstats seem to increment even without access (maybe SMART polling?) Keying off the partition's diskstats seems to solve it. But I haven't used this script in years (I eliminated the USB drive) so much may have changed. If it works, it works! Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.