QUESTION :
I have a laptop with a ssd for primary OS drive, and a large Spinning disk for storage. I currently have an alias I use for manually spinning down the drive when I’m not using it (after umount of course):
sudo hdparm -y /dev/disk/by-id/ata-WDC_WD7500BPKX-80HPJT0_WD-WX31AB3N6985
Is this safe to use? Will hdparm
refuse to do this if the drive has yet to sync or if I forget to umount it?
If not, is there a way to use hdparm
(or another util) to check if it is safe to do this?
UPDATE —
As much as I appreciate both of your answers, they don’t help me at all, because I’ve tried countless different value combinations for the APM and Spin-down time settings, with no results aside from a) less than 10 seconds before spin-down b) no spin-down but random parking, or c) no spin-down or parking. I’ve also tried to search the web for my specific drive model and its respective APM values, to no avail.
So, the direction I’d like to go in is this:
I need to figure out a way to see if the disk is in use so I can write a systemd service. The closest I can come to so far is lsof | grep /mnt/data
, or some such nonesense. But, as you can see, that is far less than ideal. I’d like a method of attaining this that doesn’t depend on a predetermined mount point, or the cpu greedy multiple invocations of lsof +D mntpoint in the answer I provided myself.
Check out my answer below for an idea of what I’m trying to do
ANSWER :
Instead of manually trying to figure this out, rely on existing stuff. I use hd-idle on my file server, it works great. I also don’t unmount my drives because there’s really no reason to do so. If I want to access a file, the disks will spin up. Then, after the timeout passes, they’ll spin down again.
If you’re super paranoid about data integrity, you can use autofs, which can automatically mount and umount your filesystems on an as-needed basis. I haven’t used it myself, but the ArchWiki page offers some info that looks quite usable.
You have an alias! Maybe it’s better to have a script that does sync / unmount and then calls hdparm. Add the script to the sudoers file.
cat >/usr/local/sbin/spindown
disk=/dev/disk/by-uuid/c542a956-fbfe-42f7-ac8f-44c029a35a69
sync && unmount /bigdisk/volume &&
hdparam -y $disk
The && makes sure the previous command exits successfully before trying the next.
Then add to sudoers. This might work:
cat >/etc/sudoers.d/spindown <<EOF
ALL ALL=(ALL) NOPASSWD:/usr/local/sbin/spindown
EOF
DanielB made a brilliant suggestion: Use autofs to automatically mount/unmount a local disk (I’ve never thought of using it that way since I usually work on servers and since autofs was traditionally for NFS). Then once that’s set up (don’t ask ME how;) ), add something like this to a cronjob:
cat >/etc/cron.d/spindown << EOF
* * * * * hdparm -C | grep -q -E "idle|active" DISK-DEV && grep -q MOUNTPOINT /etc/mtab && hdparm -y DISK-DEV
EOF
Be sure to replace DISK-DEV and MOUNTPOINT (if Disk-dev has 0 or 1 partition, you can use it for MOUNTPOINT). Please note: I cannot actually test this since the one physical system I have access to ATM is a RAID device and the controller doesn’t support those commands.
Note
You don’t need to umount the partitions in order to spin down the hard drive. It will be easier if you just set a standby timeout (that will trigger after some time not being used). This way, when needed, the disk will awake (spin-up) and you’ll be able to use it straight away without the need to remount the partitions.
Command-line solution
As @Nattgew has suggested on a comment, use hdparm
(if that’s the tool you like to use) with the -S
option to set a standby timeout:
-S Set standby (spindown) timeout
This way the disk will automatically spin down when there’s no activity.
In order to make this change permanent (i.e. after reboot), you may need to make changes to /etc/hdparm.conf
. Or maybe, as your distribution is likely nowadays using systemd
, you may need to create a unit:
https://unix.stackexchange.com/a/89013/66295
Probably the easiest way would be to use a graphical tool… (yeah, sometimes, when you already have a graphical interface enabled in your system, it is the fastest way)
GUI solution (GNOME)
As you are saying you are using your laptop, I assume you actually have a graphical interface. With GNOME distributions, there’s a program named “Disks”:
Once you select the hard drive you want to put in standby mode, you can click on “Drive settings” from the menu (or CTRL + E may be a shortcut as well):
Then change the standby timeout settings:
Here is my hack of a script so far. I will keep this open until somebody finds a better solution…
#!/bin/bash
# for each disk specified as disk
# if disk is active/idle
# disk in use as inuse = false
# for each mount point as mntpoint accociated with it
# if (lsof | grep mntpoint)
# inuse = true
# break
# endif
# endfor
# if inuse
# spin down disk
# endif
# endif
# endfor
DISKS_LEN=1
DISKS[1]=ata-WDC_WD7500BPKX-80HPJT0_WD-WX31AB3N6985
spindown_disk() {
(sync $1 && sudo hdparm -y /dev/$1 >/dev/null) &
}
diskArr_len=0
for i in `seq $DISKS_LEN`; do
linkpath=$(readlink /dev/disk/by-id/${DISKS[$i]})
((diskArr_len+=1))
diskArr[$i]=${linkpath##*/}
done
for i in `seq $diskArr_len`; do
disk=${diskArr[$i]}
if (sudo hdparm -C /dev/$disk | grep -B1 'active/idle'); then
inuse=false
mntpoints="$(mktemp)"
mount
| grep "^/dev/$disk[0-9]"
| sed -r "s|^/dev/$disk[0-9] on (.*) type.*$|1|"
>"$mntpoints"
while read mntpoint; do
while read openfile; do
[ $inuse = false ] && echo open files:
echo $'t'/${openfile#*/}
inuse=true
done < <(lsof | grep "$mntpoint")
done <"$mntpoints"
rm -f "$mntpoints"
if [ "$inuse" = true ]; then
echo $disk is in use
else
echo spinning down $disk (after sync)
spindown_disk $disk
fi
else
echo $disk is already inactive
fi
done
exit 0
I will still have to figure out how to wrap this up in a systemd service that runs every X minutes. Obviously it would be better if there was an alternative to using lsof and grep. Also, I’m not sure if this would work with funny mount point characters because of the use of grep. Also, it would need to be revised if you had more than 9 partitions.
Please, if you have ANY suggestions don’t hesitate.