Is it safe to use 'dd' to "rejuvinate" a hard drive by setting of=if?

Chu*_*huu 5 hard-drive dd

In an effort to prevent some sources of disk rot due to magnetic flux over time, I want to read and rewrite all the data on a disk. It looks like there is a 'dd' command to do this. Specifically:

dd if=/dev/sda of=/dev/sda
Run Code Online (Sandbox Code Playgroud)

I have some questions regarding this command, specifically:

  1. Is it safe regardless of file system?
  2. 这个过程是否按照我的预期执行,即读取一个扇区,然后立即重写它?
  3. 这是否具有预期的实际效果,或者以这种方式防止某些形式的腐烂蛇油?

Kam*_*ski 5

经验方法。我决定进行测试。简短回答:测试并未显示该程序是不安全的。


试验台

uname -a

Linux foobar 3.2.0-4-amd64 #1 SMP Debian 3.2.86-1 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

摘录自smartctl -a /dev/sdc

Model Family:     Western Digital Caviar Blue EIDE
Device Model:     WDC WD5000AAKB-00H8A0
Firmware Version: 05.04E05
User Capacity:    500,107,862,016 bytes [500 GB]
Sector Size:      512 bytes logical/physical
Run Code Online (Sandbox Code Playgroud)

SMART 也显示磁盘是健康的。

它通过 USB 桥接器(连接到 USB 2.0 集线器)连接。lsusb | grep SATA

Bus 001 Device 003: ID 152d:2509 JMicron Technology Corp. / JMicron USA Technology Corp. JMS539 SuperSpeed SATA II 3.0G Bridge
Run Code Online (Sandbox Code Playgroud)

一个分区,几乎没有未分配的空间。fdisk -l /dev/sdc

Disk /dev/sdc: 465,8 GiB, 500107862016 bytes, 976773168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x202b0b89

Device     Boot Start       End   Sectors   Size Id Type
/dev/sdc1        2048 976773167 976771120 465,8G 83 Linux
Run Code Online (Sandbox Code Playgroud)

健康的 ext4 文件系统,已卸载。file -s /dev/sdc1

/dev/sdc1: Linux rev 1.0 ext4 filesystem data, UUID=… (extents) (large files) (huge files)
Run Code Online (Sandbox Code Playgroud)

文件系统使用率约为 20%,但是:

  • 它已被广泛使用,因此可用空间肯定不会全为零;
  • 我无论如何都不会依赖文件系统,我计算md5sum了整个设备(见下文)。

测试

起初我保存了整个设备内容的校验和:

md5sum -b /dev/sdc > sdc.before.md5
# the throughput was about 24 MB/s
Run Code Online (Sandbox Code Playgroud)

实际dd-ing:

dd if=/dev/sdc of=/dev/sdc
# took 800 minutes, 10,4 MB/s

dd if=/dev/sdc of=/dev/sdc bs=128M conv=sync
# 630 minutes, 13,2 MB/s

dd if=/dev/sdc of=/dev/sdc bs=512 conv=sync
# 795 minutes, 10,5 MB/s
Run Code Online (Sandbox Code Playgroud)

每次dd我跑后sync,然后md5sum -b /dev/sdc所有校验和匹配sdc.before.md5

我也喜欢strace dd if=/dev/sdc of=/dev/sdc它,它用成对的线淹没了我的终端,例如:

read(0, "]\203\0\0]\203\1\0]\203\2\0]\203\3\0]\203\4\0]\203\f\0]\203\r\0]\203\30\0"..., 512) = 512
write(1, "]\203\0\0]\203\1\0]\203\2\0]\203\3\0]\203\4\0]\203\f\0]\203\r\0]\203\30\0"..., 512) = 512
Run Code Online (Sandbox Code Playgroud)

或(对于大bs

read(0, "A\260_4\245\316\273\321p\203\331\250\3022\354\303\6\30\233\366\345\237\303\244\fx\10@=0\221+"..., 134217728) = 134217728
write(1, "A\260_4\245\316\273\321p\203\331\250\3022\354\303\6\30\233\366\345\237\303\244\fx\10@=0\221+"..., 134217728) = 134217728
Run Code Online (Sandbox Code Playgroud)

结论和答案

  1. 无论文件系统如何,它都安全吗?

校验和保持不变,这里没有任何特定于文件系统的内容。用相同的数据覆盖数据应该是安全的。

注意:这适用于直接覆盖扇区的磁驱动器。另一方面,SSD(我不确定是否所有这些)需要擦除一个扇区(或一次多个扇区)才能再次写入。相同的逻辑扇区可能会写入不同的物理“单元”等。如果断电,这可能会导致数据损坏(也可能不会,我对 SSD 中的预防措施知之甚少)。你提到了磁通量,所以我想 SSD 无论如何都超出了范围。

  1. 这个过程是否按照我的预期执行,即读取一个扇区,然后立即重写它?

strace表明这正是发生的事情。缓冲区可能会延迟写入,但似乎每个读取的扇区迟早都会被重写。

我可以想到一种“优化”(在操作系统或 HDD 固件中),它将写入请求与缓存读取进行比较,如果数据已经存在,则可能会丢弃不必要的写入。它可能会使您的程序毫无意义。然而,这似乎不太可能,因为:

  • 除非您故意希望它发生,否则比赛很少会发生;
  • 缓存不够大对大bs值没有影响。

因此,如果有疑问,请使用 large bs。大bs也有利于性能。

  1. 这是否具有预期的实际效果,或者以这种方式防止某些形式的腐烂蛇油?

我同意以下评论之一:

它确实重写了每个扇区,因此大概这是所谓的位腐烂的“治愈方法”。

尽管如此,为了在实践中证实这一点,我们需要长时间对许多磁盘(有些“恢复活力”,有些没有)进行统计分析。我的单一测试无法回答这个问题。