hdparm

Related articles
Power management#Hard disk drive
Securely wipe disk#hdparm
hdparm
and
sdparm
are command line utilities to set and view hardware parameters of
hard disk drives
.
hdparm
can also be used as a simple
benchmarking
tool.
Originally,
hdparm
was created for
IDE
disks and
sdparm
for
SCSI
disks. Nowadays, storage device interfaces are an enhanced mixture of both IDE and SCSI, so
hdparm(8)
and
sdparm(8)
complement each other.
Warning
Changing the disk's default parameters can freeze the system or even irreversibly damage the disk.
Installation
Install
the
hdparm
package. For use with SCSI devices, install the
sdparm
package.
Usage
Disk info
To get information about hard disks, run the following:
# hdparm -I /dev/sda
Benchmarking
hdparm can be used for
Benchmarking#hdparm
.
Power management configuration
Modern hard drives support numerous power management features. The most common ones are summarized in the following table. See
hdparm(8)
for the complete list.
Warning
Overly aggressive power management can reduce the lifespan of hard drives due to frequent parking and spindowns.
Parameter
Description
-B
Set the
Advanced Power Management
feature. Possible values are between 1 and 255, low values mean more aggressive power management and higher values mean better performance. Values from 1 to 127 permit spin-down, whereas values from 128 to 254 do not. A value of 255 completely disables the feature.
-S
Set the standby (spindown) timeout for the drive. The timeout specifies how long to wait in idle (with no disk activity) before turning off the motor to save power. The value of 0 disables spindown, the values from 1 to 240 specify multiples of 5 seconds and values from 241 to 251 specify multiples of 30 minutes.
-M
Set the
Automatic Acoustic Management
feature. Most modern hard disk drives have the ability to speed down the head movements to reduce their noise output. The possible value depends on the disk, some disks may not support this feature.
Note
When passing both
-B
and
-S
parameters, APM values less than 128 might cause the drive to spin down before the
-S
timeout value. See
[1]
.
Current values of
-S
cannot be queried.
To query current value of
-B
, pass the parameter without a value:
# hdparm -B /dev/sda
To apply different value, for example set APM to 127:
# hdparm -B 127 /dev/sda
Write cache
Write caching is the process of temporarily caching files in the
drive's embedded memory
before writing them to the disk, which is essentially a performance boost. Write cache is a feature provided by most hard drives, and it is enabled by default in most cases. To check if that's the case, run:
# hdparm -W /dev/
sdX
Warning
While write cache is a free performance boost, it also comes with a downside. Enabling write cache increases the risk of data loss when the power is suddenly lost.
If it is disabled, one may enable it with:
# hdparm -W 1 /dev/
sdX
Conversely, to disable it, use:
# hdparm -W 0 /dev/
sdX
Note
Changes to the write-cache setting might not be persistent, and might change when the system sleeps, hibernates, or reboots. It is worth double-checking that your desired settings are applied.
The factual accuracy of this article or section is disputed.
Reason:
Re-applying the setting on all disks every 30 seconds is useless. Find out what resets the setting and either disable it or run
hdparm
only after specific events like reboot or suspend. (Discuss in
Talk:Hdparm
)
For an example of forcing disk write caches to be persistently disabled on a machine, we can create a local script
/usr/local/sbin/write-cache-disabler
that uses hdparm and
lsblk(8)
to periodically probe all attached disks and apply the desired setting. This will disable write caches on boot when the service is first ran, and can catch within 30 seconds any infrequent cases that re-enable the write cache, i.e. disk additions and system suspensions.
/usr/local/sbin/write-cache-disabler
#!/bin/sh
set -e

while true; do
        lsblk --raw --scsi --paths -o name \
        | tail --lines='+2' \
        | (while read -r name; do 
                hdparm -W "$name" \
                | (grep --fixed-strings --quiet -e '1 (on)' \
                   && hdparm -W 0 "$name" \
                   || true)
        done)
        sleep 30
done
Make sure the script is
executable
. We can then run this daemon under
systemd
by creating a local
unit
:
/etc/systemd/system/write-cache-disabler.service
[Unit]
Description=Write cache disabler daemon

[Service]
Type=simple
ExecStart=/usr/local/sbin/write-cache-disabler

[Install]
WantedBy=multi-user.target
Enable
write-cache-disabler.service
to start it at boot.
Power off a hard disk drive
A typical usage case, where such a feature is looked for, is with disks connected to a cheap external USB/SATA/FireWire enclosure, or bridge. If it does not properly issue a stop command to the drive when turning off the power switch, the drive is forced to do an emergency head retract. Regularly doing that will, sooner or later, break the drive. One solution is, after one is sure the data has been written to the media, to run a command to power off the drive:
# hdparm -Y /dev/sd
X
Warning
Be absolutely sure
The data was actually written to the media. It is also advised to wait some time so that the drive will become idle.
The device,
/dev/sd
X
in the example, is the one you want to power off.
Tips and tricks
Querying the status of the disk without waking it up
Invoking hdparm with the query option is known to wake-up some drives.  In this case, consider
smartctl
provided by
smartmontools
to query the device which will not wake up a sleeping disk. For example:
# smartctl -i -n standby /dev/sda
smartctl 6.5 2016-05-07 r4318 [x86_64-linux-4.10.13-1-ARCH] (local build)
Copyright (C) 2002-16, Bruce Allen, Christian Franke, www.smartmontools.org

Device is in STANDBY mode, exit(2)
Persistent configuration using udev rule
To make the setting persistent across reboot or sleep, one can use a
udev
rule:
/etc/udev/rules.d/69-hdparm.rules
ACTION=="add|change", SUBSYSTEM=="block", KERNEL=="sda", RUN+="/usr/bin/hdparm -B 254 -S 0 /dev/sda"
Because a disk device can be assigned randomly to a changing
/dev/sd
X
, the disk can also be identified by its serial as explained in
Udev#Identifying a disk by its serial
.
Systems with multiple hard drives can apply the rule in a flexible way according to some criteria. For example, to apply power-saving settings to all rotational drives (hard disk with rotational head, excluding in particular
solid state drives
), use the following rule:
/etc/udev/rules.d/69-hdparm.rules
ACTION=="add|change", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="sd*", ATTRS{queue/rotational}=="1", RUN+="/usr/bin/hdparm -B 127 $env{DEVNAME}"
Reapplying configuration after wakeup
If the configuration is lost after system suspension/hibernation, it can be reapplied using
systemd-sleep
.
Put a script into
/usr/lib/systemd/system-sleep/
and make it
executable
:
/usr/lib/systemd/system-sleep/hdparm
#!/bin/sh

case $1 in post)
        /usr/bin/hdparm -B 254 -S 0 /dev/sda
        ;;
esac
Putting a drive to sleep directly after boot
A device which is rarely needed can be put to sleep directly at the end of the boot process. This does not work with the above udev rule because it happens too early. In order to issue the command when the boot is completed, just create a
systemd
service and
enable
it:
/etc/systemd/system/hdparm.service
[Unit]
Description=hdparm sleep

[Service]
Type=oneshot
ExecStart=/usr/bin/hdparm -q -S 120 -y /dev/sdb

[Install]
WantedBy=multi-user.target
Working with unsupported hardware
Some drives do not support spin down via hdparm. A diagnostic error message similar to the following is a good indication this is the case:
# hdparm -S 240 /dev/sda
/dev/sda:
setting standby to 240 (20 minutes)
HDIO_DRIVE_CMD(setidle) failed: Invalid argument
For some other drives, the hdparm command is acknowledged but the drive do not respect the parameters (either APM or spin down timer). This was observed with a Toshiba P300 (model HDWD120) HDD.
Such drives can be spun down using
hd-idle
AUR
which ships with a
systemd
service. One need to edit
/etc/conf.d/hd-idle
and the
HD_IDLE_OPTS
value, then
start
and
enable
hd-idle.service
.
Example using a 10 min idle time for
/dev/sda
and a 1 min idle time for
/dev/disk/by-uuid/01CF0AC9AA5EAF70
:
HD_IDLE_OPTS="-i 0 -a /dev/sda -i 600 -a /dev/disk/by-uuid/01CF0AC9AA5EAF70 -i 60"
the leading
-i 0
parameter indicates that hd-idle is disabled on other drives.
Power management for Western Digital hard disk drives
Western Digital
hard drives have a special
idle3
timer which controls how long the drive waits before positioning its heads in their park position and entering a low power consumption state. There are different ways to amend the
idle3
state:
hdparm
features the
-J
flag:
Specify a value of zero (
0
) to disable the WD
idle3
timer completely:
# hdparm -J 0 --please-destroy-my-drive /dev/sd
drive
, which is not recommended by
hdparm(8)
though—hdparm developers recommend a setting of 30 seconds for Linux use.
See
#Persistent configuration using udev rule
to automatically use this parameter on supported hard drives.
idle3ctl
—provided by the
idle3-tools
package:
Disable the timer completely:
# idle3ctl -d /dev/sdc
.
Set the timer to 30 seconds:
# idle3ctl -s 129 /dev/sdc
.
Tip
A raw
idle3
value is passed as a parameter of the
idle3ctl
command.
The correspondence between this value and the timeout in seconds is provided in the bottom table within
idle3ctl(8)
.
Note
A full power cycle is required for any change to take effect regardless of which program above is used. It means the drive needs to be powered
off
and then
on
, a simple reboot does
not
suffice.
Troubleshooting
APM level reset after suspend
The APM level may get reset after a suspend requiring it to be re-executed after each resume. This can be automated with the following
systemd
unit (adapted from a
forum thread
):
/etc/systemd/system/apm.service
[Unit]
Description=Local system resume actions
After=suspend.target hybrid-sleep.target hibernate.target

[Service]
Type=simple
ExecStart=/usr/bin/hdparm -B 254 /dev/sda

[Install]
WantedBy=sleep.target
Note
The
sleep.target
is pulled by all
suspend
,
hybrid-sleep
and
hibernate
targets, but it finishes starting up
before
the system is suspended, so the three targets have to be specified explicitly. See
[2]
.
Alternatively, create a
hook in /usr/lib/systemd/system-sleep
.