如何通过 ddrescue 恢复尝试找出丢失了哪些文件?

Dav*_*lla 12 data-recovery hard-disk ddrescue

我正在从 1 TB 故障驱动器中抢救数据(在更换硬盘的过程中询问过它)。我ddrescue从系统救援 USB 中完成了 557568 B 在 191 个错误中产生的错误大小,可能全部在/home(我假设它所谓的“错误”不是坏扇区,而是它们的连续序列)。

现在,我看到的几个指南建议e2fsck在新磁盘上做,我希望这会以某种方式发现某些文件已被分配“空白扇区/块”,至少知道哪些文件无法保存所有的。但是根本没有发现任何错误(我运行它但没有-y确保我没有遗漏任何东西)。现在我用 再次运行它-c,但到目前为止 95% 没有发现错误;我想我有一个新驱动器,里面有一些看起来正常的文件,里面有归零或随机的部分,直到我用相应的软件打开它们或 Linux Mint 需要它们时才能检测到它们。

我可以对旧/新驱动器做任何事情以获得可能损坏的文件的列表吗?我不知道它们有多少,因为那 191 个可以跨文件,但至少总大小并不大;我最关心的是一大堆旧的家庭照片和视频(每个 1+ MB),其余的可能无关紧要或最近已备份。

更新:e2fsck 的新通行证确实提供了一些新的东西,我对此一无所知:

Block bitmap differences:  +231216947 +(231216964--231216965) +231216970 +231217707 +231217852 +(231217870--231217871) +231218486
Fix<y>? yes
Free blocks count wrong for group #7056 (497, counted=488).                    
Fix<y>? yes
Free blocks count wrong (44259598, counted=44259589).
Fix<y>? yes
Run Code Online (Sandbox Code Playgroud)

dir*_*rkt 6

您将需要所有遇到的坏块的块号(ddrescue应该给您一个列表,我希望您保存它),然后您需要找出哪些文件使用这些块(参见例如此处。如果有很多坏块,您可能需要编写此脚本。

e2fsck没有帮助,它只是检查文件系统本身的一致性,因此它只会对包含“管理”文件系统信息的坏块起作用。

文件中的坏块将只是空的。

编辑

好吧,让我们弄清楚块大小。让我们用 512 字节设备块制作一个试用文件系统:

$ dd if=/dev/zero of=fs bs=512 count=200
$ /sbin/mke2fs fs

$ ll fs
-rw-r--r-- 1 dirk dirk 102400 Apr 27 10:03 fs

$ /sbin/tune2fs -l fs
...
Block count:              100
...
Block size:               1024
Fragment size:            1024
Blocks per group:         8192
Fragments per group:      8192
Run Code Online (Sandbox Code Playgroud)

因此文件系统块大小为 1024,我们有 100 个文件系统块(以及 200 个 512 字节设备块)。拯救它:

$ ddrescue -b512 fs fs.new fs.log
GNU ddrescue 1.19
Press Ctrl-C to interrupt
rescued:    102400 B,  errsize:       0 B,  current rate:     102 kB/s
   ipos:     65536 B,   errors:       0,    average rate:     102 kB/s
   opos:     65536 B, run time:       1 s,  successful read:       0 s ago
Finished                                     

$ cat fs.log
# Rescue Logfile. Created by GNU ddrescue version 1.19
# Command line: ddrescue fs fs.new fs.log
# Start time:   2017-04-27 10:04:03
# Current time: 2017-04-27 10:04:03
# Finished
# current_pos  current_status
0x00010000     +
#      pos        size  status
0x00000000  0x00019000  +

$ printf "%i\n" 0x00019000
102400
Run Code Online (Sandbox Code Playgroud)

所以十六进制ddrescue单位是字节,而不是任何块。最后我们看看有什么debugfs用。首先,创建一个文件并找到其内容:

$ sudo mount -o loop fs /mnt/tmp
$ sudo chmod go+rwx /mnt/tmp/
$ echo 'abcdefghijk' > /mnt/tmp/foo
$ sudo umount /mnt/tmp

$ hexdump -C fs
...
00005400  61 62 63 64 65 66 67 68  69 6a 6b 0a 00 00 00 00  |abcdefghijk.....|
00005410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
Run Code Online (Sandbox Code Playgroud)

所以数据的字节地址是0x5400。将其转换为 1024 字节文件系统块:

$ printf "%i\n" 0x5400
21504
$ expr 21504 / 1024
21
Run Code Online (Sandbox Code Playgroud)

让我们也尝试一下块范围:

$ /sbin/debugfs fs
debugfs 1.43.3 (04-Sep-2016)
debugfs:  testb 0
testb: Invalid block number 0
debugfs:  testb 1
Block 1 marked in use
debugfs:  testb 99
Block 99 not in use
debugfs:  testb 100
Illegal block number passed to ext2fs_test_block_bitmap #100 for block bitmap for fs
Block 100 not in use
debugfs:  testb 21
Block 21 marked in use
debugfs:  icheck 21
Block   Inode number
21      12
debugfs:  ncheck 12
Inode   Pathname
12      //foo
Run Code Online (Sandbox Code Playgroud)

因此,结果符合预期,但块 0 无效,可能是因为文件系统元数据在那里。因此,对于0x30F8A71000来自的字节地址ddrescue,假设您在整个磁盘而不是分区上工作,我们减去分区起始的字节地址

210330128384 - 7815168 * 512 = 206328762368

将其除以tune2fs块大小即可得到文件系统块(请注意,由于多个物理块(可能已损坏)组成了一个文件系统块,因此数字不必是精确的倍数):

206328762368 / 4096 = 50373233.0

这就是您应该测试的块debugfs


Tom*_*ale 6

NTFS、ext3、ext4

使用 复制故障驱动器上的数据后ddrescue,使用ddrutility查找受影响的文件名。

我成功地让它ddrescue在 20 秒内列出了给定映射文件的 1TB 分区上受影响的 NTFS 文件。

它将日志文件写入当前目录。

链接页面提到了对 NTFS、ext3 和 ext4 的支持。

btrfs、zfs

这些文件系统有自己的内置scrub功能。