TL;DR

修改硬盘的manage_start_stopmanage_runtime_start_stop属性为1

背景

自从买了硬盘盒,在使用我的服务器“铭凡 MS-01”时,遇到了一个头疼的问题。服务器通过 USB4 接口连接铁威马 D4-320 外置硬盘盒的 USB3.2 Gen2 接口上。

在关机的过程中,我发现硬盘并没有像预期自动复位磁头,反而发出“喀”的一声,并且随着磁盘转速减小而逐渐安静,导致硬盘的 SMART 信息中 C0 计数不断增加。这不仅可能对硬盘寿命产生负面影响,也影响系统的稳定性。

正常来说应该是非常安静的,甚至是低于硬盘执行休眠操作时候的声音。

1
2
# hdparm -Y 休眠硬盘
hdparm -Y /dev/disk/by-id/usb-TerraMas_TDAS_170615C6772F-0:0

定位问题

最初在网上搜索了不少 Linux 关机时候硬盘不能正常关闭,没有检索到有用的相关内容。询问 GPT,回答是 USB 的电源管理相关的设置,尝试后都没用。无奈只能减少服务器的关机次数来避免 SMART 信息中 C0 的不断增加。

幸好,最近再次搜索,可能是换了一下关键词,就搜索到了。

参考文章中提到,在普通 SATA 硬盘上,位于 /sys/class/scsi_disk/ 下的 manages_start_stop 属性默认值为 1,关机时磁头会复位;但在使用 HBA 直通卡时,这个属性会被改为 0,导致关机时磁头不复位。

嗯,说不定 HBA 直通卡和我的铁威马硬盘盒有相似的地方,那就试试?
看看是不是这个原因,检查硬盘的三个属性:

1
2
3
cat /sys/class/scsi_disk/*/manage_shutdown
cat /sys/class/scsi_disk/*/manage_start_stop
cat /sys/class/scsi_disk/*/manage_runtime_start_stop

果不其然,硬盘的这三个属性都是 0。于是尝试修改:

1
2
3
for i in /sys/class/scsi_disk/*/manage_shutdown; do echo 1 > $i; done
for i in /sys/class/scsi_disk/*/manage_start_stop; do echo 1 > $i; done
for i in /sys/class/scsi_disk/*/manage_runtime_start_stop; do echo 1 > $i; done

也正如文中所说,“manage_start_stop”“此属性的读写权限为只读”。
然后再次检查属性,再尝试关机检查硬盘是否仍旧非正常关机。
妙啊!经过实验验证,当将硬盘的 manage_runtime_start_stopmanage_shutdown 属性设置为 1 后,硬盘磁头能够正常复位。

解决方案

结合上述发现,有出以下两步措施可以来解决问题:

  1. 修改属性(临时有效)
1
2
for i in /sys/class/scsi_disk/*/manage_shutdown; do echo 1 > $i; done
for i in /sys/class/scsi_disk/*/manage_runtime_start_stop; do echo 1 > $i; done
  1. 利用 /etc/rc.local 实现开机自动执行脚本(持续有效)
    为了确保每次启动时都执行以上命令,可以直接使用 /etc/rc.local
    /etc/rc.local 中的 exit 0 之前添加以下内容:
1
2
3
4
# 修改硬盘管理属性
for i in /sys/class/scsi_disk/*/manage_shutdown; do echo 1 > $i; done
for i in /sys/class/scsi_disk/*/manage_runtime_start_stop; do echo 1 > $i; done
exit 0

另外记得要赋予文件执行权限:

1
2
# 赋予文件执行权限
chmod +x /etc/rc.local

紧接着启动 rc-local 服务

1
2
# 使用 systemctl 启动
systemctl start rc-local

这样,每次系统启动时,rc.local 脚本都会在开机时自动运行,确保硬盘属性被正确设置,解决了磁头不自动复位的问题。