断开热插拔 SATA 硬盘的正确方法是什么?

断开热插拔 SATA 硬盘的正确方法是什么?

我正在使用 SATA 热插拔托架,并且在 BIOS 中将此特定端口专门配置为“热插拔”。

该托架具有方便的“电源开/关”按钮,因此插入/拔出电缆时不会发生中断。

当我打开驱动器时,在它安装之前我立即收到一些内核错误:

[1263413.036674] ata6: exception Emask 0x10 SAct 0x0 SErr 0x4040000 action 0xe frozen
[1263413.036680] ata6: irq_stat 0x00000040, connection status changed
[1263413.036683] ata6: SError: { CommWake DevExch }
[1263413.036698] ata6: hard resetting link
[1263418.796687] ata6: link is slow to respond, please be patient (ready=0)
[1263423.052529] ata6: COMRESET failed (errno=-16)
[1263423.052547] ata6: hard resetting link
[1263428.032390] ata6: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
[1263428.032836] ACPI Error: [DSSP] Namespace lookup failure, AE_NOT_FOUND (20150930/psargs-359)
[1263428.032846] ACPI Error: Method parse/execution failed [\_SB.PCI0.SAT0.SPT5._GTF] (Node ffff88040e0c5780), AE_NOT_FOUND (20150930/psparse-542)
[1263428.159582] ata6.00: ATA-9: HGST HDN726040ALE614, APGNW7JH, max UDMA/133
[1263428.159588] ata6.00: 7814037168 sectors, multi 0: LBA48 NCQ (depth 31/32), AA
[1263428.161980] ACPI Error: [DSSP] Namespace lookup failure, AE_NOT_FOUND (20150930/psargs-359)
[1263428.161988] ACPI Error: Method parse/execution failed [\_SB.PCI0.SAT0.SPT5._GTF] (Node ffff88040e0c5780), AE_NOT_FOUND (20150930/psparse-542)
[1263428.164472] ata6.00: configured for UDMA/133
[1263428.164483] ata6: EH complete
[1263428.164650] scsi 5:0:0:0: Direct-Access     ATA      HGST HDN726040AL W7JH PQ: 0 ANSI: 5
[1263428.165064] sd 5:0:0:0: Attached scsi generic sg4 type 0
[1263428.165502] sd 5:0:0:0: [sdd] 7814037168 512-byte logical blocks: (4.00 TB/3.64 TiB)
[1263428.165508] sd 5:0:0:0: [sdd] 4096-byte physical blocks
[1263428.165582] sd 5:0:0:0: [sdd] Write Protect is off
[1263428.165587] sd 5:0:0:0: [sdd] Mode Sense: 00 3a 00 00
[1263428.165618] sd 5:0:0:0: [sdd] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[1263428.213630]  sdd: sdd1
[1263428.214062] sd 5:0:0:0: [sdd] Attached SCSI disk
[1263534.534238] EXT4-fs (dm-5): mounted filesystem with ordered data mode. Opts: (null)

当我卸载它(像任何其他驱动器一样)然后关闭托架时,我从内核得到了更多奇怪的输出(最后部分发生在关闭后约 10 秒 - 系统仍然认为驱动器已连接一段时间直到超时):

[1263588.964461] ata6: exception Emask 0x10 SAct 0x0 SErr 0x4090000 action 0xe frozen
[1263588.964467] ata6: irq_stat 0x00400040, connection status changed
[1263588.964478] ata6: SError: { PHYRdyChg 10B8B DevExch }
[1263588.964483] ata6: hard resetting link
[1263589.687000] ata6: SATA link down (SStatus 0 SControl 300)
[1263594.686806] ata6: hard resetting link
[1263595.006827] ata6: SATA link down (SStatus 0 SControl 300)
[1263595.006837] ata6: limiting SATA link speed to 1.5 Gbps
[1263600.006678] ata6: hard resetting link
[1263600.330626] ata6: SATA link down (SStatus 0 SControl 310)
[1263600.330634] ata6.00: disabled
[1263600.330645] ata6: EH complete
[1263600.330653] ata6.00: detaching (SCSI 5:0:0:0)
[1263600.334909] sd 5:0:0:0: [sdd] Synchronizing SCSI cache
[1263600.334943] sd 5:0:0:0: [sdd] Synchronize Cache(10) failed: Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[1263600.334946] sd 5:0:0:0: [sdd] Stopping disk
[1263600.334955] sd 5:0:0:0: [sdd] Start/Stop Unit failed: Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK

然而驱动器工作正常,没有任何问题或数据错误,但我感觉它可能以更好/更安全的方式完成,而不会出现这样的超时。

有没有更合适的方法来断开热插拔 SATA ?


我一直在尝试发送udisksctl power-off -b /dev/sdd命令,但尽管它对 USB 驱动器有效,但对 SATA 却无能为力。我认为最好的办法是在关闭电源之前暂停驱动器,但内核输出无论如何都是一样的。


$ uname -a
Linux dev 4.4.0-93-generic #116-Ubuntu SMP Fri Aug 11 21:17:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

答案1

下面是一个最奇怪的命令,它实际上能达到我所寻找的目的:

device=sde; sudo sh -c "echo 1 > /sys/block/${device}/device/delete"

sde在此示例中,用相应的驱动器替换。sh是到的链接/bin/dash

... 之后是:

[1285227.129329] sd 5:0:0:0: [sde] Synchronizing SCSI cache
[1285227.129566] sd 5:0:0:0: [sde] Stopping disk
[1285228.209095] ata6.00: disabled

...现在我可以关机了,然后它:

[1285259.491044] ata6: exception Emask 0x10 SAct 0x0 SErr 0x4090000 action 0xe frozen
[1285259.491049] ata6: irq_stat 0x00400040, connection status changed
[1285259.491052] ata6: SError: { PHYRdyChg 10B8B DevExch }
[1285259.491058] ata6: hard resetting link
[1285260.211923] ata6: SATA link down (SStatus 0 SControl 300)
[1285260.211934] ata6: EH complete

虽然需要 root 权限,但看起来更令人满意 :)

答案2

当您卸载了驱动器中所有带有文件系统的分区(并交换了所有活动的交换分区)后,您可以关闭电源而不会对文件系统(甚至是处于休眠状态的数据存储)造成任何风险,之后您可以断开驱动器的连接。

我已经使用该方法对 eSATA 驱动器进行备份多年,没有遇到任何问题。


卸载过程从刷新缓冲区开始(完成将数据写入已挂载的文件系统,这也可以使用命令单独完成sync),然后卸载过程完成(并且文件系统不再可用)。

以下链接可能有助于描述卸载和弹出 USB 闪存盘(弹出 = 卸载并关闭电源),

  • 有关卸载的更多信息:在 Ubuntu u盘上卸载我的 Windows 专用驱动器

  • 卸载与弹出:如何从命令行卸载 MTP USB 设备

    这是卸载。缓冲区已刷新,因此可以安全地拔下设备。设备仍处于通电状态,因此可以“在桌面上看到”,并且可以再次安装。这与 喷射。弹出的 U 盘将会关闭,如果要安装它,必须拔下并重新插入。

    我没有在 Linux 中使用任何通用的 [e]SATA 驱动器自动弹出方法,但你可以使用以下操作顺序,

    • 卸载
    • 关掉电源
    • 断开

您可以通过找到hdparm关闭 SATA 驱动器的方法,但我没有使用过它们,而且我认为它们没有必要。

答案3

我编写了一个脚本来卸载驱动器上的所有分区,然后使用 hdparm 暂停驱动器。它很好地满足了我的需求,但请检查代码并自行承担使用风险。(下面的 github 链接)

1:卸载分区并检查错误

umount /dev/sdx? 

2:如果检测到错误,请检查所有驱动器是否先前已卸载或是否处于繁忙状态。如果繁忙,则退出程序。如果不是,则继续

if [ $? -ne 0 ]; then
    for File in /dev/${1}?
    do
    findmnt ${File}
        if [ $? -ne 0 ]; then
            echo "${File} is not mounted"
        else
            echo
            echo "ERROR: ${File} is still mounted!!"
            echo
            exit 11
        fi
    done
else
    echo "${1} unmounted" 
fi

3:等待三秒钟(这是必要的,因为如果我在卸载后过早尝试暂停它就不会起作用。)

echo "wait three seconds"

对于 {3..1} 中的索引,请回显“在 ${Index} 中停车”睡眠 1 完成

4:如果驱动器先前已被卸载或者卸载成功,则暂停驱动器以停放磁头。

hdparm -$Mode /dev/${1}

如果 [ $? -ne 0 ]; 然后 echo echo "错误:无法将驱动器置于待机状态" echo exit 12 fi return 0

请参阅 github 上的完整程序,它包括功能选项和文本 UI https://github.com/BMarkley/ParkDrive

相关内容