Put HDD into standby after wake from suspend

I use suspend on my laptop all the time as it works perfectly on Ubuntu with integrated intel graphics. After I bought second classical (spinning) HDD in addition to SSD I was thinking about reducing power consumption and noise as this second HDD gets started on each system start / resume from suspend. Because it will serve only as media storage, it should run only a couple of minutes per day and the rest time should be powered down.

So my requirements were clear:

  • after start/resume, second HDD should be put into standby mode immediately (HDD is not spinning)
  • when second HDD is not active within 10 minutes it should be put into standby mode as well

Spinning and other HDD settings are controlled using hdparm utility. This is how my current hdparm config file looks like:

$ cat /etc/hdparm.conf

/dev/sdb {
    apm = 255
    apm_battery = 255
    # 120 * 5 = 600 seconds = 10 minutes
    spindown_time = 120
    poweron_standby = off
    standby
}

Note: If you want to get your HDD into standby mode, APM level should be in general lower than 128. Failing to do so is a common mistake and reason why people are wondering that HDD won’t stop spinning after spindown_time elapse. However for my Samsung SpinPoint M9T, APM values lower than 128 cause standby only after a few seconds of idleness so the spindown_time is ignored. For that reason I disabled APM completely (value 255) and now HDD is brought into standby properly after configured spindown_time. If you are experience the same issue, try to disable APM, it might help you too.

This hdparm configuration works fine except HDD is not brought automatically into standby mode after wake from suspend. I found out that only apm, apm_battery and spindown_time settings are re-applied after resume, not the standby. This is done using script

/usr/lib/pm-utils/power.d/95hdparm-apm

which gets called from

/lib/systemd/system-sleep/hdparm (systemd hook)

once laptop is suspended or resumed. No other hdaparm settings are re-applied after resume. So in order to spin down HDD after resume, there are 2 options:

  1. create systemd service in /etc/systemd/system/suspend.target.wants
  2. modify /lib/systemd/system-sleep/hdparm script or create new one in the same directory and suspend disk manually when post event occurs

Until Ubuntu 15.04 there was also a third option, place standby invoking script into /etc/pm/sleep.d directory. As from 15.10, systemd has replaced upstart and pm utils scripts are no longer invoked automatically!.

I took the first approach and created following systemd service, which spins down HDD immediately after resume:

$ cat /etc/systemd/system/suspend.target.wants/standby-hdd.service

[Unit]
Description=Turn off power of the media hdd after resume
After=suspend.target

[Service]
ExecStart=/sbin/hdparm -y /dev/sdb

[Install]
WantedBy=suspend.target

This works for me well.