understandable linux tips, tricks and tutorials

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:

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

5 Comments
  1. Nice tutorial, thanks. Why Ubuntu uses dash: “The major reason to switch the default shell was efficiency. bash is an excellent full-featured shell appropriate for interactive use; indeed, it is still the default login shell. However, it is rather large and slow to start up and operate by comparison with dash. A large number of shell instances are started as part of the Ubuntu boot process. Rather than change each of them individually to run explicitly under /bin/dash, a change which would require significant ongoing maintenance and which would be liable to regress if not paid close attention, the Ubuntu core development team felt that it was best simply to change the default shell. The boot speed improvements in Ubuntu 6.10 were often incorrectly attributed to Upstart, which is a fine platform for future development of the init system but in Ubuntu 6.10 was primarily running in System V compatibility mode with only small behavioural changes. These improvements were in fact largely due to the changed /bin/sh. “

  2. What’s the script again. 1395504092814fe03e55b65c7a58c3ec000 doesnt make any sense.

    Thanks

  3. You can use udev to make sure you always get the same device name on the drive, thus removing the need to figure out the name in the script : http://blog.wains.be/2010/04/10/udev-always-the-same-device-name-for-your-usb-drives/

  4. In my system, the Orico 7629RUS3 enclosure connected by USB appears as SCSI, but sdparm don’t work with it. This works fine for me:

    [code]

    #!/bin/bash
    DISKNAME=`ls -l /dev/disk/by-uuid/ | grep "XXXXXXXXXXXX" | mawk '{ print $(NF) }' | sed s_\.\.\/\.\.\/__`
    isstandby=`hdparm -C /dev/$DISKNAME | grep -c standby`
    if [ $isstandby == 0 ]
    then
    a=0
    #check 100 times with 0.1s gaps and go on adding
    for i in `seq 0 100`
    do
    b=`cat /proc/diskstats | grep $DISKNAME | mawk '{ print $(NF-2) }'`
    a=`expr $a + $b`
    sleep 0.1s
    done
    echo $a
    if [ $a == 0 ]
    then
    echo "No Activity"
    #sdparm -C stop /dev/$DISKNAME
    hdparm -y /dev/$DISKNAME
    else
    echo "Disk Active"
    fi
    fi
    exit 0

    [/code]

  5. Me again. Remove the lines:

    isstandby=`hdparm -C /dev/$DISKNAME | grep -c standby`
    if [ $isstandby == 0 ]
    then
    … # Not these
    fi

    Sorry

Leave a Reply

Site last updated October 20, 2012 @ 12:53 pm; This content last updated September 12, 2012 @ 3:19 am