最近固态价格越来越便宜了,就买了一个航雄M2移动硬盘盒,方案是 RTL9120B,支持 Nvme/Sata 双协议,然后弄了一块 1T 的大杯固态。然后把用了2年多的 U盘 Debian系统迁移过去。具体迁移方法过后再写篇文章仔细描述,GPT/UEFI 系统迁移实在是太简单了。

之前用的 U盘,没有 SMART 信息,换移动硬盘后就发现,当笔记本关机后,移动硬盘还是工作状态,我这个硬盘盒指示灯是双色,绿色代表工作(总线桥接中),蓝色代表待机(Nvme电源关闭),关机后直到电脑 USB 自动断电,硬盘盒断电,再进入系统看 SMART 就可以看到“不安全关机(Unsafe Shutown Counts”会递增 1。虽然固态硬盘这个计数实际不会损害,但是过于膈应,而且我觉得系统本身不可能不支持自动给移动硬盘自动弹出。

这个跟旧固件的 RTK9210B 硬盘盒 bug 不同,我的硬盘盒固件是比较新的 1.31,弹出硬盘不安全关机次数递增的 bug 已经修正了。我这种情况是 Linux 系统装在移动硬盘上,然后关机时系统没有通知 USB 设备进入待机(Standby)状态。查询了许多资料,都是让在 /lib/systemd/system-shutdown 中使用 udisksctl 或者 hdparm 去卸载/关闭 USB 存储,实际操作下来并没有什么用,直到看到论坛帖子 Graceful way to spin down (unload head) USB attached mobile hard drive BEFRORE shutdown(poweroff/reboot/halt),才找到正确的解决方案。

具体就是,需要使能系统 scsi_disk 模块对于 USB 存储的 manage_start_stop 标志,这样系统就会管理这些设备的启动和停止任务。对于一般的外置移动硬盘而言,通常是用户自行加载移除设备,但是对于运行了系统的移动硬盘而言,用户无法自行处理移除,需要系统自己在关机时处理。比较奇怪的是为什么 Linux 没有默认使能这个标志。

解决方案:

  1. 手动处理(需要root权限,重启失效):
1
2
3
4
# 使能 manage_start_stop, [...] 为硬盘节点,可以补全
echo 1 | sudo tee /sys/class/scsi_disk/[...]/manage_start_stop
# 检查
cat /sys/class/scsi_disk/[...]/manage_start_stop
  1. 利用 udev 规则,自动处理:
1
2
# 创建文件 /etc/udev/rules.d/01-manage-start-stop.rules
echo 'ACTION=="add|change", DRIVERS=="usb-storage|uas", SUBSYSTEM=="scsi_disk", ATTR{manage_start_stop}="1"' | sudo tee /etc/udev/rules.d/01-manage-start-stop.rules

另外,对于使用 RTL9210b 方案,Linux 系统默认状态下固态并不支持 TRIM 指令,可以通过一个 udev 规则来默认激活 TRIM 支持:

1
echo 'ACTION=="add|change", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="9210", SUBSYSTEM=="scsi_disk", ATTR{provisioning_mode}="unmap"' | sudo tee /etc/udev/rules.d/10-uas-discard.rules

然后通过命令 lsblk -D 检查 TRIM 支持:

1
2
3
4
5
6
7
$ lsblk -D
NAME        DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda                0      512B       4G         0
├─sda1             0      512B       4G         0
├─sda2             0      512B       4G         0
├─sda3             0      512B       4G         0
└─sda4             0      512B       4G         0