我有一台笔记本电脑,它有一块 ssd 作为主操作系统驱动器,还有一块大型旋转磁盘用于存储。我目前有一个别名,用于在不使用驱动器时手动降低驱动器转速(当然是在卸载之后):
sudo hdparm -y /dev/disk/by-id/ata-WDC_WD7500BPKX-80HPJT0_WD-WX31AB3N6985
使用起来安全吗?hdparm
如果驱动器尚未同步或我忘记卸载它,是否会拒绝执行此操作?如果不安全,是否有办法hdparm
(或其他实用程序)检查这样做是否安全?
更新 -
尽管我很感激你们两个的回答,但它们对我一点帮助都没有,因为我尝试了无数种不同的 APM 和降速时间设置值组合,除了 a) 降速前少于 10 秒 b) 不降速但随机停放,或 c) 不降速或停放外,没有其他结果。我还尝试在网上搜索我的特定驱动器型号及其相应的 APM 值,但无济于事。
因此,我想要的方向是这样的:我需要想办法查看磁盘是否正在使用,以便我可以编写 systemd 服务。到目前为止,我能想到的最接近的方法是lsof | grep /mnt/data
,或者类似的无稽之谈。但是,正如您所见,这远非理想。我想要一种实现此目的的方法,它不依赖于预定的挂载点,也不依赖于我自己提供的答案中对 lsof +D mntpoint 的 CPU 贪婪多次调用。
看看下面的回答,了解我想做什么
答案1
与其手动尝试解决这个问题,不如依靠现有的东西。我使用高清空闲在我的文件服务器上,它运行良好。我也不会卸载驱动器,因为真的没有理由这么做。如果我想访问文件,磁盘会旋转起来。然后,在超时之后,它们会再次旋转下来。
如果你对数据完整性非常担心,你可以使用自动文件系统,它可以根据需要自动挂载和卸载文件系统。我自己没有用过,但是ArchWiki 页面提供了一些看起来很有用的信息。
答案2
您有一个别名!也许最好有一个执行同步/卸载然后调用 hdparm 的脚本。将脚本添加到 sudoers 文件中。
cat >/usr/local/sbin/spindown
disk=/dev/disk/by-uuid/c542a956-fbfe-42f7-ac8f-44c029a35a69
sync && unmount /bigdisk/volume &&
hdparam -y $disk
&& 确保在尝试下一个命令之前前一个命令成功退出。
然后添加到 sudoers。这可能会有效:
cat >/etc/sudoers.d/spindown <<EOF
ALL ALL=(ALL) NOPASSWD:/usr/local/sbin/spindown
EOF
DanielB 提出了一个绝妙的建议:使用 autofs 自动挂载/卸载本地磁盘(我从来没有想过以这种方式使用它,因为我通常在服务器上工作,而且 autofs 传统上用于 NFS)。然后,一旦设置完成(不要问我如何设置;)),将类似以下内容添加到 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
确保替换 DISK-DEV 和 MOUNTPOINT(如果 Disk-dev 有 0 或 1 个分区,则可以将其用作 MOUNTPOINT)。请注意:我无法实际测试这一点,因为身体的我可以访问的系统 ATM 是一个 RAID 设备,并且控制器不支持这些命令。
答案3
笔记
您无需卸载分区即可让硬盘减速。只需设置待机超时(在一段时间未使用后触发)即可。这样,当需要时,磁盘将唤醒(启动),您可以立即使用它,而无需重新安装分区。
命令行解决方案
正如@Nattgew 在评论中所建议的那样,使用hdparm
(如果这是您喜欢使用的工具)并可以-S
选择设置待机超时:
-S Set standby (spindown) timeout
这样,当没有活动时,磁盘将自动旋转停止。
为了使此更改永久生效(即重启后),您可能需要对 进行更改/etc/hdparm.conf
。或者,由于您的发行版现在可能正在使用systemd
,您可能需要创建一个单元:
https://unix.stackexchange.com/a/89013/66295
可能最简单的方法是使用图形工具......(是的,有时,当您的系统中已经启用了图形界面时,这是最快的方法)
GUI 解决方案(GNOME)
既然您说您正在使用笔记本电脑,我假设您实际上有一个图形界面。在 GNOME 发行版中,有一个名为“磁盘”的程序:
选择要置于待机模式的硬盘后,您可以从菜单中单击“驱动器设置”(或CTRL+E也可以是快捷方式):
然后更改待机超时设置:
答案4
这是我目前为止破解的脚本。我会保持开放直到有人找到更好的解决方案...
#!/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
我仍然需要弄清楚如何将其包装到每 X 分钟运行一次的 systemd 服务中。显然,如果有替代 lsof 和 grep 的方法会更好。另外,我不确定这是否适用于由于使用 grep 而产生的奇怪的挂载点字符。此外,如果您有超过 9 个分区,则需要对其进行修改。
如果您有任何建议,请不要犹豫。