使用hdparm控制硬盘自动休眠

AI大语言模型

硬盘管理中,常用到smartctl和hdparm这两个工具:

sudo apt install smartmontools hdparm

使用lsblk命令查看设备名称:

lsblk

使用smartctl查看硬盘信息:

sudo smartctl -a /dev/sdX

对于机械硬盘,使用以下命令查看磁头加载次数(LCC计数):

sudo smartctl -A /dev/sdX | grep Load_Cycle_Count

在磁头加载时LCC计数会累加一次,也就是硬盘从休眠状态唤醒时增加一次,而从活动状态转入休眠不计数。如果硬盘频繁休眠唤醒,LCC计数值就会非常大,消费级硬盘上限是30万次左右,企业级硬盘可达60万次。

对于机械硬盘,磁头频繁的加/卸载会造成机械部件磨损,长期运转造成的磨损反而更小。SSD固态硬盘由于没有机械部件,所以频繁休眠唤醒带来的影响相对较小。

休眠是为了节能,就是为了省电,要平衡节能和硬盘寿命,需要根据对硬盘的使用频率权衡设置休眠超时。

硬盘高级电源管理

查看硬盘电源管理级别:

sudo hdparm -B

配置硬盘电源管理级别:

sudo hdparm -B 128 /dev/sdX

硬盘电源管理级别数值范围:

  • 1–127:低功耗模式,数值越小越省电,但性能越差,可能频繁停转磁盘;
  • 128–254:高性能模式,禁止硬盘自动停转,数值越高性能越强,功耗增加;
  • 255:完全禁用APM,某些厂商可能不支持。

如果不确定该值多少合适,可以设置为128平衡功耗与性能。

硬盘电源管理可能影响主轴电机转速、减少缓存刷新频率、延迟写入、控制磁头加载/卸载频率等。该参数不直接影响休眠,它的作用是控制硬盘的工作方式:如何跑?是快速的跑?还是慢慢的跑?

硬盘自动休眠设置

休眠决定停还是跑,设置休眠超时值:

sudo hdparm -S 240 /dev/sdX

休眠超时值说明:

  • 0:禁用休眠;
  • 1-240:单位5秒,计算方法:数值 × 5秒。例如:240 = 240 × 5 = 1200秒 = 20分钟;
  • 241-251:单位30分钟,只看超出240的部份,计算方法:(数值 - 240) × 30分钟。例如:242 = (242 - 240) × 30 = 60分钟 = 1小时。某些厂商可能不支持大于240的值
  • 252-255:厂商自定义,不同硬件厂商设定不同,在不清楚的情况下慎用。

当硬盘处于空闲状态时开始倒计时,计时结束进入休眠状态。如果在计时期间有进程使用硬盘,计时重置重新倒计时。所以,如果有进程频繁访问硬盘,就可能导致永不休眠,或刚休眠就被唤醒。

使用hdparm命令查看硬盘状态,该查询不会造成唤醒,LCC计数不增加:

sudo hdparm -C /dev/sdX
  • Active/Idle:工作中;
  • Standby:休眠。

可以在倒计时开始前触发一下硬盘的访问,以便观察设置是否有效:

sudo hdparm -t /dev/sdX

每分钟轮循查看硬盘状态:

start=$(date); while state=$(sudo hdparm -C /dev/sdX 2>/dev/null | awk '/drive state/ {print $4}'); [[ "$state" != "standby" ]]; do echo "$(date): $state"; sleep 60; done; echo "$start - $(date): standby"

硬盘厂商建议休眠超时不要小于5分钟,由于后台进程对硬盘访问的不确定性,过短的休眠超时值可能导致频繁休眠/唤醒,而过长的休眠超时值可能导致硬盘永不休眠。

根据LCC计数30万次上限计算,如果期待硬盘能够使用10年,每天的LCC次数可达82次。如果将休眠超时值设置为240,即20分钟,即使刚进入休眠就被唤醒,24小时LCC理论最大值为72次,也未达到上限。

实际使用中,刚进入休眠就有进程访问导致硬盘唤醒的概率不高。影响硬盘寿命的因素也很多,可能LCC计数远未达到上限硬盘就已经损坏。实际观察到的数据,许多LCC数值很高的硬盘仍工作得很好,而LCC数值不高的硬盘也有损坏的情况。

鉴于以上计算,休眠超时值一般设置为15-30分钟即可,可以分别设置不同值观察一两周,根据观察结果选择最优值。个人认为,20分钟(值240)是一个不错的平衡功耗和性能的值。

需要注意,smartctl和hdparm命令可能造成唤醒导致LCC次数增加。

配置重启生效

编辑配置文件hdparm.conf:

sudo nano /etc/hdparm.conf

添加如下配置:

/dev/sdX {
	apm = 128
	spindown_time = 240
}

也可以使用硬盘UUID:

/dev/disk/by-uuid/你的硬盘UUID {
	apm = 128
	spindown_time = 240
}

USB接口的外置硬盘

对于移动硬盘,或使用硬盘盒、SATA转USB线挂载的硬盘,这些设备自带了休眠机制,与hdparm的设置可能冲突。或这些设备的USB桥接芯片不透传hdparm指令,导致hdparm设置无效。

可以联系硬件厂商提供固件升级工具重刷固件关闭或修改休眠超时值。我的硬盘盒是绿联的,联系商家获取刷机工具很快就刷好了。

要测试hdparm指令是否有效,可以在硬盘活动状态时强制休眠硬盘。注意,硬盘有进程访问时执行以下命令可能会造成数据丢失或分区损坏等风险:

sudo hdparm -y /dev/sdX

检查是否有进程正在访问硬盘:

sudo lsof /dev/sdX >/dev/null 2>&1

执行完上面的命令后立即执行:

echo $?

返回0说明有进程正在使用硬盘,可以使用以下命令相对安全的执行强制休眠:

sync && ! sudo lsof /dev/sdX >/dev/null 2>&1 && sudo hdparm -Y /dev/sdX

查看硬盘状态如果从活动状态转入休眠,则说明hdparm -s能够生效:

sudo hdparm -C /dev/sdX

如果确定hdparm设置无效,还可以尝试使用hd-idle工具。

AI大语言模型