如何在清零磁盘时忽略写入错误?

max*_*zig 29 dd hard-disk ddrescue

假设您想将故障硬盘归零。您想尽可能多地用零覆盖。您不想要的是:进程在第一个写入错误时中止。怎么做?

AFAICS,plaindd仅提供忽略读取错误的选项。因此,像

dd if=/dev/zero of=/dev/disk/by-id/lousy-vendor-123 bs=128k
Run Code Online (Sandbox Code Playgroud)

是不足够的。

ddrescue 似乎更擅长忽略错误 - 但它的最佳命令行是什么?

我对 GNU ddrescue 的尝试:

ddrescue --verbose --force --no-split /dev/zero /dev/disk/by-id/lousy-vendor-123
Run Code Online (Sandbox Code Playgroud)

fro*_*utz 16

badblocks为此,我更喜欢破坏性写入模式。它会写入,在遇到错误时继续这样做,最后它会告诉您这些错误的位置,这些信息可能会帮助您决定下一步要做什么(它会混合吗?)。

# badblocks -v -b 4096 -t random -o badblocks.txt -w /dev/destroyme
Checking for bad blocks in read-write mode
From block 0 to 2097151
Testing with random pattern: done
Reading and comparing: done
Pass completed, 52105 bad blocks found. (0/52105/0 errors)
Run Code Online (Sandbox Code Playgroud)

和阻止列表:

# head badblocks.txt
2097000
2097001
2097002
2097003
2097004
Run Code Online (Sandbox Code Playgroud)

之后磁盘上还剩下什么:

# hexdump -C /dev/destroyme
00000000  be e9 2e a5 87 1d 9e 61  e5 3c 98 7e b6 96 c6 ed  |.......a.<.~....|
00000010  2c fe db 06 bf 10 d0 c3  52 52 b8 a1 55 62 6c 13  |,.......RR..Ubl.|
00000020  4b 9a b8 d3 b7 57 34 9c  93 cc 1a 49 62 e0 36 8e  |K....W4....Ib.6.|
Run Code Online (Sandbox Code Playgroud)

请注意,它并不是真正的随机数据 - 模式是重复的,因此如果您跳过,1MiB您会再次看到相同的输出。

它还会尝试通过读回数据来进行验证,因此如果您有一个声称写入成功但在回读时返回错误数据的磁盘,它也会发现这些错误。(确保在坏块运行时没有其他进程写入磁盘以避免误报。)

当然,对于严重损坏的磁盘,这可能需要太长时间:没有代码可以使其完全跳过有缺陷的区域。实现这一目标的唯一方法badblocks是使用更大的块大小。

我不确定这样ddrescue做是否更好;它应该在另一个方向上做到这一点(尽可能快地恢复尽可能多的数据)。您可以通过指定第一个/最后一个块来手动为 dd/ddrescue/badblocks 执行此操作...

  • 如果我使用“-t random”或“-t 0” - 是否会出现坏块,然后只进行一次写入传递?查看手册页 - 似乎没有“-t”,它会执行 4 次传递(对于“0xaa、0x55、0xff、0x00”)。 (2认同)
  • 它对您在命令行上提供的每个 `-t` 执行一次。如您所说,默认值为 4 次。 (2认同)

gar*_*Red 14

如果磁盘没有通过 USB 连接,则考虑使用hdparm(版本 > 9.31)对磁盘进行ATA Secure Erase。此命令会导致驱动器的固件擦除磁盘的内容,包括坏块。

警告:使用正确的驱动器号 - 我已/dev/sdX作为示例显示 - 不要只是复制/粘贴。

首先,检查它是否理解 ATA 命令(过去十年或更长时间制造的大多数驱动器都应该):

$ sudo hdparm -I /dev/sdX
.
# lots of other info here...
.
Security: 
    Master password revision code = 65534
        supported
    not enabled
    not locked
    not frozen
    not expired: security count
        supported: enhanced erase
    202min for SECURITY ERASE UNIT. 202min for ENHANCED SECURITY ERASE UNIT.
Run Code Online (Sandbox Code Playgroud)

摘录的最后两行表明它是受支持的。

因此,向驱动器添加密码(显然是一个要求):

$sudo hdparm --user-master u --security-set-pass p /dev/sdX
security_password="p"
Run Code Online (Sandbox Code Playgroud)

并擦除:

$sudo hdparm --user-master u --security-erase p /dev/sdX
security_password="p"

/dev/sdX:
Issuing SECURITY_ERASE command, password="p", user=user
Run Code Online (Sandbox Code Playgroud)

此处提供有关此过程的更多信息。

  • 如果幸运的话,这可以通过 USB 工作,并且您的 USB &lt;-&gt; SATA 桥可以通过非标准 SATA 命令(并且 Linux 驱动程序 + hdparm 知道如何在该型号上执行此操作)。另外,对于编写示例,`/dev/sdX` 很好,因为如果有人在粘贴和自定义时错过了它的出现,就不会有问题。 (2认同)
  • 链接页面列出了许多与此方法有关的硬件/固件相关警告......有点可怕 (2认同)