症状

一块 Seagate 叠瓦盘,运行 smartctl -A /dev/sda -d test 得到类型输出为:

/dev/sda [SAT]: Device of type 'sat' [ATA] detected
/dev/sda [SAT]: Device of type 'sat' [ATA] opened

但是运行 smartctl -A /dev/sda -d sat 时得到错误:Read Device Identity failed: scsi error unsupported field in scsi command

根结

根据这篇文档所说:在某些情况下,LinuxUAS 驱动程序会禁用 SAT 传输,这会阻止 smartmontools(以及其他工具,如 hdparm)与附加的 SATA 设备正常通信。因为 Linux 内核拒绝了某些设备的 SAT ATA 直通命令。受影响的设备列表取决于内核版本,可能包括所有 Seagate 封装、 Initio INIC-3069VIA VL711

当运行在 UAS 模式下时,某些 USB-SATA 桥接芯片组无法正确地将 SAT 命令传递给 SATA 设备。为了绕过这个问题, Linux 会自动为这些芯片组启用 NO_ATA_1X 标志关闭 SAT 直通。smartmontools 无法与这种设备通信。对于很多设备的芯片组, SAT 直通在旧的 BOTusb-storage 驱动程序)模式下可以正常工作,因此,当内核升级到支持 UAS 的版本,或者从一个没有为这块盘设置该旗语的内核升级到一个设置了的内核时,就会发生这种情况。

使用 lsusb -t 命令可以列出每个 USB 口和连接设备的驱动:

Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M
Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
|__ Port 1: Dev 11, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
|__ Port 1: Dev 8, If 0, Class=Mass Storage, Driver=uas, 5000M

其中 Driver=uasDriver=usb-storage 能看出 Linux 对存储设备使用的驱动。

绕过思路

如果想在这些设备上使用 smartmontools,涉及为相关设备设置 quirks 标志。

  • 如果只想使用 smartmontools,而不在乎 UAS 模式的性能提升,则可以简单地使用 IGNORE_UAS 标志,把 usb-storage.quirks 设置上 u 标志就能告诉 Linux 保持 usb-storage 模式。
  • 如果坚信自己的设备正确实现了 SAT 模式,因此想要继续使用 UAS 模式。可以通过在 usb-storage.quirks 设置中传递一个空的标志列表来覆盖该默认配置并抑制 NO_ATA_1Xt 旗语。

永久有效的绕过

  1. 如果 usb-storage 驱动程序是可加载的内核模块,可以在 /etc/modprobe.d/ 下创建一个文件并包含: options usb-storage quirks=供应商编号:产品编号:uoptions usb-storage quirks=供应商编号:产品编号。再重建 initramdisk 。这样就能在初始启动时检测到 usb-storage 驱动程序时应用更改。
  2. 如果 usb-storage 驱动程序内置于内核中,或者不喜欢修改 /etc/modprobe.d/。可以将选项作为启动配置的一部分传递给内核。编辑 /boot/grub/default 添加 GRUB_CMDLINE_LINUX="usb_storage.quirks=供应商编号:设备编号:u"。然后运行 grub-mkconfig

临时绕过

想要临时设置 quirks 旗语而不是进行永久更改。这样在可以在某个时候手动运行 smartctl,但在使用驱动器进行数据传输时继续使用 UAS 模式。可以通过写入对应模块的文件来实现。

cat /sys/module/usb_storage/parameters/quirks
echo "0x供应商编号:0x设备编号:u" > /sys/module/usb_storage/parameters/quirks
cat /sys/module/usb_storage/parameters/quirks

注意 echo 会完全替换当前设置,因此需要第一个 cat 命令检查是否有之前写入的改动。