Spin Down Idle USB Drives

When I was setting up my media server, I added a couple of USB disk drives to the server to hold media files. The problem was that leaving these disks permanently attached to the server meant that they kept spinning day and night and got very hot – not good. I wanted the disks to spin down if they were idle for 10 minutes or so. Sadly, the drives I had had no capacity to spin down on their own account. Accordingly, I needed a method to automagically spin them down. This is what I did.

The Script

The first step in getting this going is a simple bash script that checks /proc/diskstats for disk activity, and if there is no activity, it uses the sdparm command to spin down the drive. The script is as follows:

DISKNAME=`ls -l /dev/disk/by-uuid/ | grep "<strong>46BA-C6C7</strong>" | mawk '{ print $(NF) }' | sed s_\.\.\/\.\.\/__`
#check 100 times with 0.1s gaps,
#and go on adding
for i in `seq 0 100`
b=`cat /proc/diskstats | grep $DISKNAME | mawk '{ print $(NF-2) }'`
a=`expr $a + $b`
sleep 0.1s
echo $a
if [ $a == 0 ]
echo "No Activity"
sdparm -C stop /dev/$DISKNAME
echo "Disk Active"
exit 0

The only bit of this script that needs to be customised is the 8 character uuid of the disk drive that you want to shut down. To find this, use the command ls -l /dev/disk/by-uuid. You should get output that looks like this:

matt@mailserver:~$ ls -l /dev/disk/by-uuid/
total 0
lrwxrwxrwx 1 root root 10 2010-01-08 21:52 2C05-61F4 -> ../../sdh1
lrwxrwxrwx 1 root root 10 2010-01-04 15:38 3e28c6a3-10d8-440d-9169-09457e01b3f5 -> ../../sdb3
lrwxrwxrwx 1 root root 10 2010-01-04 16:33 46BA-C6C7 -> ../../sde1
lrwxrwxrwx 1 root root 10 2010-01-04 15:38 4a325cc6-d331-4d04-a515-b58c275319a8 -> ../../sdb1
lrwxrwxrwx 1 root root 10 2010-01-04 15:38 c0a24f9a-5fbb-4d48-bfd7-a384043ea44b -> ../../sdb2
lrwxrwxrwx 1 root root 10 2010-01-04 15:38 f13b037c-5a8c-4116-b5d8-db6eb64cab1e -> ../../sda1

Find the disk you want to spin down (in this case sde1) and copy the corresponding uuid into the script. Then save the file into /usr/local/bin and make it executable using chmod +x /usr/local/bin/scriptname. That’s the script part done.

Checking Disk Status Using Cron

The final step is to run the script every 10 minutes or so to check if the disk has become idle. To do this, you need to add a cron job. However, because sdparm is a system tool, you need to run the cron job as root. Accordingly, you need to change to root using su and then run crontab -e to edit root’s crontab. Please note if you are using and Ubuntu derivative, for some reason adding a job to root’s crontab doesn’t work. Accordingly, you should add the cron job to /etc/crontab. This is the line I added to root’s crontab:

*/10 * * * *    root    /usr/local/bin/scriptname

One issue I ran into when using this script after upgrading to Ubuntu 10.04 was that it didn’t run until I’d changed the default shell from dash to bash – see here how to do this. Why Ubuntu keeps on with using dash as the default shell I will never know.

That’s it – good luck.