Glorious1
Guru
- Joined
- Nov 23, 2014
- Messages
- 1,211
Many of us want to have drives in one or more pools/volumes go into standby (i.e., stop spinning). I'm no expert, but I was able to do it finally and understand most of what is going on. As cyberjock has said, FreeNAS is not really designed for this, so it's like fitting a round peg in a square hole. Still, the developers left open the possibility.
Note that many of the experts here will tell you that drives last longer if they just keep spinning rather than stopping and starting, and even that less energy and resources are consumed by letting them spin than starting and stopping them and having to manufacture and ship replacement drives. I have no argument with any of that. But some of us may want to have drives spin up once a day (or less) for a task and then spin down.
There are several caveats:
If like me, you have no direct way to tell if drives are spinning, various scripts are available to help. One strategy is based on a camcontrol command. It is nice because, in my testing, it did not reset the standby timer if the disk was spinning. So I could poll the drives every minute and whatch when the went to sleep. However, it doesn't work when you have drives attached through a card.
I now use one based on the return value of a smartctl command, based on a script by joeschmuck. It asks you how often you want the disks checked and prints a compact table headed by drive labels and with each line getting a timestamp. Beware that it will keep your drives awake if the chosen check interval is shorter than the standby timer. As a bonus, the script gives the temperature of the drives that are spinning.
If you want to run it for a while, log in via SSH and start a tmux session first by typing "tmux". Call the script with sudo ./spincheck.sh. The log, spincheck.log, will will get the ouput forked from inside the script. This will keep logging after your SSH session ends. You can monitor progress with "cat spincheck.log". You have to "tmux attach" to get back to the session to end the script with Control-C.
Here's a sample of the output:
And the script:
Note that many of the experts here will tell you that drives last longer if they just keep spinning rather than stopping and starting, and even that less energy and resources are consumed by letting them spin than starting and stopping them and having to manufacture and ship replacement drives. I have no argument with any of that. But some of us may want to have drives spin up once a day (or less) for a task and then spin down.
There are several caveats:
- The first thing to know is that you can't spin down a volume that the system dataset is on. By default, this is the first volume you created. The system dataset gets written to constantly. You can set it to another volume in System > System Dataset (also check Syslog and Reporting Database). Ideally you would put that in a special volume on a solid state drive (SSD) or a SataDOM. I have a SSD in a USB enclosure left over from upgrading the drive in a laptop and it works fine plugged into a USB port. USB flash drives are not recommended as the constant writing is hard on them.
- This will be a dealbreaker for some people: If there are shares on the volume you put in standby, it will spin up any time someone logs into the server, even if they are going into a different volume (does not apply to SSH). FreeNAS, in its wisdom, spins up all disks in volumes that have shares, even if you are going for a share on another volume. I have not tested whether this is true when the person logging in has no access privileges to that share.
- Another caveat is that you can't do this power management stuff through an add-on card, at least not the one I have, LSI 9240-8i flashed to IT mode. I read somewhere that the FreeBSD developers decided that supporting that functionality is not going to happen. So I can control disks attached to the motherboard SATA ports, but not to the card. The GUI lets you make settings on disks attached through the card, but they have no effect. In my case, I have my main volume on the disks on the card, spinning 24/7, and a backup volume on disks on the motherboard, spinning up once a day to receive replication tasks.
- If you need to find out which disks are in the volume you want to spin down, go to Storage > Volumes and click on the volume. Then click the Volume Status icon at the bottom. Under the raid configuration the drives are listed. Note the names (ignore the p2 on the end).
- Go to Storage > Volumes > View Disks. Click on the first of the disks in the volume and click the Edit button at the bottom. "HDD Standby" is the standby timer: number of minutes the disk is idle before it should go into standby. Set Advanced Power Management to 127 (I'm not sure this is needed as -- says APM is off on my drives). Click OK and do the same for all drives in the volume.
- Go to Services > S.M.A.R.T. Settings. Set Power Mode to Standby. This means SMART won't check the drive (and spin it up), if it is in Standby mode (spun down).
- Anything you do to access the volume, even indirectly, will spin it up. This includes creating or editing any share or task, snapshot, replication, rsync, etc., on that volume. If you click on Storage > Snapshots, FreeNAS will spin up all volumes to look for snapshots (I'm not sure if this is true when there are no snapshots on the volume). SSH into the server does not spin it up unless you do something in that volume. An noted above, any login to any share will spin up all volumes with shares.
- If you or a script does a smartctl command on that disk, it may affect the standby state. If the disk is spinning, any smartctl command on it will reset the standby timer. If the disk is in standby, smartctl will spin it up to execute the command unless the "-n standby" option tells it not to.
Code:
sudo camcontrol standby /dev/ada0 -t 600 sudo ataidle -S 10 /dev/ada0
If like me, you have no direct way to tell if drives are spinning, various scripts are available to help. One strategy is based on a camcontrol command. It is nice because, in my testing, it did not reset the standby timer if the disk was spinning. So I could poll the drives every minute and whatch when the went to sleep. However, it doesn't work when you have drives attached through a card.
I now use one based on the return value of a smartctl command, based on a script by joeschmuck. It asks you how often you want the disks checked and prints a compact table headed by drive labels and with each line getting a timestamp. Beware that it will keep your drives awake if the chosen check interval is shorter than the standby timer. As a bonus, the script gives the temperature of the drives that are spinning.
If you want to run it for a while, log in via SSH and start a tmux session first by typing "tmux". Call the script with sudo ./spincheck.sh. The log, spincheck.log, will will get the ouput forked from inside the script. This will keep logging after your SSH session ends. You can monitor progress with "cat spincheck.log". You have to "tmux attach" to get back to the session to end the script with Control-C.
Here's a sample of the output:
Code:
[jim@Tabernacle ~]$ sudo bin/spincheck.sh How many minutes do you want between spin checks? 15 da0 da1 da2 da3 ada0 ada1 ada2 ada3 12:20:28 Spin 30 Spin 31 Spin 32 Spin 31 Spin 28 Spin 30 Spin 28 Spin 28 12:35:29 Spin 31 Spin 31 Spin 33 Spin 32 Spin 29 Spin 31 Spin 29 Spin 29 12:50:29 Spin 31 Spin 31 Spin 32 Spin 32 STANDBY STANDBY STANDBY STANDBY
And the script:
Code:
#!/usr/local/bin/bash # spincheck.sh version 2016-07-02; should work for any board. # Run as superuser. See notes at end. # Creates logfile and sends stdout and stderr to the log, # leaving the previous contents in place. If you want to append # to existing log, add '-a' to the tee command. LOG=spincheck.log exec > >(tee -i $LOG) 2>&1 SP=33.57 # Setpoint mean temperature, for information only function get_disk_name { # The awk statement works by taking the $LINE as input, # setting '(' as a _F_ield separator and taking the second field it separates # (ie after the separator), passing that to another awk that uses # ',' as a separator, and taking the first field (ie before the separator). # In other words, everything between '(' and ',' is kept. DEVID=$(echo $LINE | awk -F '(' '{print $2}' | awk -F ',' '{print$1}') } function print_header { # Header is printed when script starts and each new day DATE=$(date +"%A, %b %d") echo $DATE echo -n " " while read LINE ; do get_disk_name printf "%-8s" $DEVID done <<< "$DEVLIST" # while statement works on DEVLIST printf "%4s %5s %4s %-8s %s \n" "Tmax" "Tmean" } function data { if [[ $i > 0 ]]; then Tmean=$(echo "scale=2; $Tsum / $i" | bc) ERRc=$(echo "scale=2; $Tmean - $SP" | bc) else Tmean= ; ERRc= ; Tmax= fi # print current data printf "^%-3d %5.2f" $Tmax $Tmean printf " ERRc= %5.2f\n" $ERRc } echo "How many minutes do you want between spin checks?" read T SEC=$(bc <<< "$T*60") # bc is a calculator # Get list of drives; remove SanDisk DEVLIST1=$(camcontrol devlist) # Remove lines with flash drives or SSD; edit as needed # You could use another strategy, e.g., find something in the camcontrol devlist # output that is unique to the drives you want, for instance only WDC drives: # if [[ $LINE != *"WDC"* ]] . . . DEVLIST="$(echo "$DEVLIST1"|sed '/KINGSTON/d;/ADATA/d;/SanDisk/d')" print_header # Main loop while [ 1 ] ; do # Print header every quarter day. Expression removes any # leading 0 so it is not seen as octal HM=$(date +%k%M); HM=`expr $HM + 0` R=$(( HM % 600 )) # remainder after dividing by 6 hours if (( $R < $T )); then print_header; fi # print time on each line TIME=$(date "+%H:%M:%S"); echo -n "$TIME " Tmax=0; Tsum=0 # initialize drive temps for new loop through drives i=0 # count number of spinning drives while read LINE ; do get_disk_name TEMP=$(smartctl -a -n standby "/dev/$DEVID" | grep "Temperature_Celsius" | grep -o "..$") smartctl -n standby "/dev/$DEVID" > /var/tempfile RETURN=$? # need to preserve because $? changes with each if comparison if [[ $RETURN == "0" ]] ; then STATE="Spin" elif [[ $RETURN == "2" ]] ; then STATE="STANDBY" else STATE="UNKNOWN" fi printf "%-8s" $STATE" "$TEMP # Update temperatures each drive if [ $STATE == "Spin" ] ; then let Tsum=$Tsum+$TEMP if [[ $TEMP > $Tmax ]]; then Tmax=$TEMP; fi; let "i += 1" fi done <<< "$DEVLIST" data # manage data sleep $(($T*60)) # seconds between runs done # Logs: # - disk status (spinning or standby) # - disk temperature (Celsius) if spinning # - max and mean disk temperature # - fan rpm and mode # - current and new fan duty cycle # - optional diagnostic variables # Includes disks on motherboard and on HBA. # Uses joeschmuck's smartctl method (returns 0 if spinning, 2 in standby) # https://forums.freenas.org/index.php?threads/how-to-find-out-if-a-drive-is-spinning-down-properly.2068/#post-28451 # Other method (camcontrol cmd -a) doesn't work with HBA
Last edited: