How to spindown(sleep) a SATA hard disk drive after being idle (Linux)

[UPDATE] If your BIOS supports the AHCI standard,  you may try to turn it on, and try to use the ‘hdparm -S1 /dev/sdn’ command again, or all the variants your distro suggests for powering down your hard disk.

BUT! Read here carefully about possible complications: http://en.wikipedia.org/wiki/Advanced_Host_Controller_Interface. If you don’t have such an BIOS switch or it doesn’t work for you for other reasons, you may read ahead.[/UPDATE]

It was easy to set an IDE(PATA) hard disk drive into standby mode. You just invoked the hdparm command with the -S switch.

hdparm -S180 /dev/hdb

e.g. sets your IDE hard disk drive into the standby mode after 15 minutes idle time, where almost no energy was consumed anymore, and for some of us more important than that, no noise was generated as well. If you wanted to make these setting persistent, you’ve simply wrote these rules into the /etc/hdparm.conf. The day I bought my first SATA disk, I’ve almost instantly tried the sdparm command with the same switch “-S180“. Haha, that doesn’t work of course you might say now, because you’ve tried the same nonsense also. Then you probably also started your journey for the right command to set your drive after a certain amount of time into standby. Well – I found nothing. Laptop_mode tools didn’t work for me. After setting these values in the /etc/laptop-mode/laptop-mode.conf

ENABLE_LAPTOP_MODE_ON_AC=1 HD="/dev/[hs]d[bcdefgh]" CONTROL_HD_IDLE_TIMEOUT=1 NOLM_HD_IDLE_TIMEOUT_SECONDS=20

and running "/etc/init.d/laptop-mode restart" or invoking it from the console “laptop_mode” I only got a bunch of these ones:

HDIO_DRIVE_CMD failed: Input/output error

This all may of course due to the fact, that this machine is not a notebook at all, but my media server. S.M.A.R.T doesn’t work for me (don’t know why, and I don’t intend to become a rocket scientist to understand that), and there are tons of other commands and scripts out there, which let your SATA drive sleep after being idle for some time. This e.g. is an excellent site, where likely all possible methods are described how you can let your SATA disk go into standby, but there’s no hdparm -S180. Crap, isn’t it? I’ve studied the site a bit, and decided to do it completely different. Here we go (I assume you’re know what you’re doing and you’re not new to Linux either

):


This is a simple ‘Two Steps HOWTO’ for Linux. This example is running on an Ubuntu 8.10 / Intrepid Ibex

  1. Install sg3-utils:

    apitude install sg3-utils

  2. enter these 3 (blue) lines as root user into your crontab by entering
    crontab -e
    ...
    #==Acmelabs 2008 ===== Spin down SATA disks after a given idle time ==
    0-59/15 * * * * ( if [ ! -f /dev/shm/1 ] ; then touch /dev/shm/1 /dev/shm/2; fi ; mv /dev/shm/1 /dev/shm/2; cat /proc/diskstats > /dev/shm/1 ) >/dev/null 2>&1
    0-59/15 * * * * ( export HD="sda "; if [ "$(diff /dev/shm/1 /dev/shm/2 | grep $HD )" =  "" ] ; then /usr/bin/sg_start --stop /dev/$HD; fi ) >/dev/null 2>&1

save and exit the crontab editor. That’s it. Watch out, on cut and paste the lines above, they are one-liner, and there are, inlcuding the comment line, three of them. Be careful with the quotes also. It’s better you type instead of cut&pasting -> learning by doing ;-)


I’m personally using

export EDITOR=vi

because nano makes me go mad as the standard editor for crontab, but this is only a matter of taste. And if you like more hard drives go to sleep, just copy the last line, and replace sda, e.g. with sdb. The “15” is the idle time in minutes, after which your drives should go to sleep. If you don’t know the name of your drives, just perform a “df” command. Note: The /usr/share/doc/sg3-utils/README.sg_start sais

…Be aware that the Linux SCSI subsystem at this time does not autmatically starts stopped devices, so stopping a device which is in use may have fatal results for you…

I personally don’t know, whether the author just wants to sound a bit dramatic, or it’s the plain truth, because countless hamsters have been grilled or other natural disaster hit the earth after this command has been used. It’s working for me actually. But please, I won’t be upset if you enlighten me bye saying: Hey, why don’t you use…? ;-)

7 thoughts on “How to spindown(sleep) a SATA hard disk drive after being idle (Linux)

  1. Christian

    Why don’t you use hdparm for SATA-drives as well? It works the same way for PATA and for SATA drives.

  2. acmelab68 Post author

    @Christian
    Well, actually I do have a few (mostly newer) machines hdparm is working right away for SATA drives, but only because the BIOS supports AHCI. This is definitely also true in your case, just look into your BIOS and see for yourself.

  3. KingOfDos

    Thanks for this. I’d was searching for a method how to check for disk-inactivity. I’ve replaced the ‘spindown command’ with hdparm -y /dev/sda, because that suits my setup (Western Digital MyBook World Edition, SATA disk, no spindown).

  4. doomy

    hello,

    i created a little script that is called in crontab i still would like to add a automatic detection of every disk in the system

    #!/bin/bash
    if [ ! -f /dev/shm/1 ]
    then
    touch /dev/shm/1 /dev/shm/2
    echo “$(date ‘+%F %T’) Tempfile does not exist, creating” >> /var/log/hd_spindown.log
    fi
    mv /dev/shm/1 /dev/shm/2
    cat /proc/diskstats > /dev/shm/1

    export HD=”sdf ”
    if [ "$(diff /dev/shm/1 /dev/shm/2 | grep $HD )" = "" ]
    then
    if [ "$(/sbin/hdparm -C /dev/$HD | grep "drive state" | cut -d: -f2 | awk '{ print $1}')" = "standby" ]
    then
    echo “$(date ‘+%F %T’) $HD already spun down” >> /var/log/hd_spindown.log
    else
    /sbin/hdparm -y /dev/$HD
    echo “$(date ‘+%F %T’) Spindown $HD” >> /var/log/hd_spindown.log
    fi
    else
    echo “$(date ‘+%F %T’) $HD is in use” >> /var/log/hd_spindown.log
    fi

  5. frazzmatazz

    Here’s my hacked together version:

    The following line in /etc/crontab…

    */10 *  * * *   root    /usr/local/bin/check-bigspace-unmounted >/dev/null 2>&1
    

    Runs this script every 10 minutes (or is that 6) to see if “Bigspace” (my 2nd SATA drive for bulk storage) is not mounted. And if not, then it spins it down:

    mount |grep Bigspace
    if [ $? -ne 0 ] ; then
       echo "Bigspace is not mounted"
       /sbin/hdparm -C /dev/disk/by-label/Bigspace |grep standby
       if [ $? -ne 0 ] ; then
          echo "Spinning down Bigspace"
          spindown-bigspace
          exit 0
       fi
       echo "Bigspace is spundown"
    else 
       echo "Bigspace is mounted"
       exit 1
    
    fi 
    
    
    I sadly haven't found a graceful way of doing this yet. But it works.
  6. Masel

    Hi,

    this solution does not work on my Archlinux system…
    After inserting the Cronjob in Cron.d the log replies as follows :
    Bad User Name…

    Has anyone an idea ?

Comments are closed.