Spinning down hard drives in Linux

I have a system with an SSD containing my OS (OpenSUSE) and a lot of my data as well as a traditional spinning hard drive with extra data. I don't often access the data on the spinning hard drive so would like to be able to spin it down to both make it quieter and use less energy. This turned out to be harder than originally envisaged. The ultimate solution is below but here's a little background to start.

hdparm and initial troubles

There's a linux utility called hdparm which is designed to get or set parameters on SATA or IDE hard drives. This is what everyone recommends using to set your idle timeout on the drive. The parameter you want to set for spin-down timing is '-S' which is a value from 1 to 255. The values between 1 and 240 represent an idle timeout of value x 5 seconds, e.g. a value of 1 is a timeout of 5 seconds and a value of 120 is a timeout of 10 minutes:

$ sudo hdparm -S 120 /dev/sdb

Unfortunately, this didn't work for me. Even when I set the timeout to 5 seconds, the disk didn't spin down. I tried manually making the disk spin down:

$ sudo hdparm -C /dev/sdb
 /dev/sdb:
  drive state is:  active/idle
$ sudo hdparm -Y /dev/sdb
 /dev/sdb:
  issuing sleep command
$ sudo hdparm -C /dev/sdb
 /dev/sdb:
  drive state is:  standby

This worked fine which suggested that there was perhaps a process still trying to access the disk, thereby preventing it spinning down. To troubleshoot this I installed iotop (available in many distribution's repositories). By running iotop and using the "o" (only active processes) and "a" (accumulating) options in the program, you can see which processes are accessing data from hard drives. I couldn't find a way to distinguish between data access from different hard drives but it was clear from the list of processes that none of them were accessing the hard drive I wanted to spin down:

iotop output

Some further googling led me to this related askubuntu question which suggests that the Advanced Power Management setting may need to be set to a value lower than 128 to allow spinning down to work. Unfortunately, this didn't work in my case as my hard drive (Western Digital, model number WDC WD5000AAKS-00YGA0) doesn't support setting APM values:

$ sudo hdparm -B 127 /dev/sdb
 /dev/sdb:
  setting Advanced Power Management level to 0x7f (127)
  HDIO_DRIVE_CMD failed: Input/output error
  APM_level      = not supported

However, this page also led me to a solution: hd-idle.

The solution: hd-idle

hd-idle is a small utility which was designed to spin down external hard drives. Of course, it also works to spin down stubborn internal drives. To install and start it running with a timeout of 10 minutes, I followed instructions on the homepage and did the following:

$ cvs -d:pserver:anonymous@hd-idle.cvs.sourceforge.net:/cvsroot/hd-idle login
$ cvs -z3 -d:pserver:anonymous@hd-idle.cvs.sourceforge.net:/cvsroot/hd-idle co -P hd-idle
$ cd hd-idle/
$ make
$ sudo make install
$ sudo hd-idle -i 10 -a sdb -i 10

Then, to make sure it ran at every boot, I copied the last line from above and put it in my /etc/init.d/boot.local file.

References

First published on 23rd March 2013 and last modified on 27th March 2013.