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

如何找出通过 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

答案1

您将需要所有遇到的坏块的块号(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

因此文件系统块大小为 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

所以十六进制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  |................|

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

$ printf "%i\n" 0x5400
21504
$ expr 21504 / 1024
21

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

$ /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

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

210330128384 - 7815168 * 512 = 206328762368

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

206328762368 / 4096 = 50373233.0

这就是您应该测试的块debugfs

答案2

NTFS、ext3、ext4

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

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

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

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

btrfs、zfs

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

答案3

我会推荐一个已经实现的实用程序,称为ddrutility.这将消除手动繁琐的计算。

你应该在你的克隆上运行它复制(不是原来的)驱动设备如下:

ddru_findbad /dev/sdb /ddrescue-disk-copy.map

此处必须使用地图文件(第二个参数)。

该实用程序非常智能,支持不同的文件系统(甚至 NTFS),并且还具有测试尚未分割的错误扇区的功能(将它们标记为临时坏扇区),因此您应该能够估计是否需要整个ddrescue过程待完成。另请注意,/dev/sdb此处用作整个磁盘(不是像 的某些分区/dev/sdb1),因为整个磁盘最初是克隆的。

该实用程序在 Debian 存储库中可用,并且可以通过以下方式安装:

sudo apt install ddrutility

该项目的维基百科:https://sourceforge.net/p/ddrutility/wiki/Home

答案4

我使用 Filezilla simple 并解决了我的问题。使用常规 Filezilla 备份所有好的数据。我注意到一个大文件未正确复制(中途停止并重新启动传输)。幸运的是我有相同文件的先前备份。要复制磁盘,我必须使用以下过程找到磁盘上的坏块:

首先找出问题磁盘,使用识别高清信息fdisk -l

第二个如果假设你的磁盘是/dev/sdb那么你需要运行命令 坏块 -v /dev/sdb它会列出驱动器上的所有坏块。幸运的是会有一些。如果没有发现坏块,则说明您的驱动器块没问题,需要解决其他问题。我的块大小是 512,所以我使用该默认数字来运行 DD

第三个每个块的大小是 512,所以我所做的是设置 bs=512

每次我像往常一样定期运行 DD 时,我的数据在出现错误后就会损坏。因此,我使用页面上说明的参数https://www.gnu.org/software/coreutils/manual/html_node/dd-inspiration.html搜索“故障磁盘”部分。

dd if=/dev/sdb of=/dev/sda bs=512 conv=noerror,sync iflag=fullblock 

花了一段时间。每个坏块都会遇到类似故障驱动器撞击声的声音。它确实逐块复制,并且通过我所有的坏块发出相同的噪音。发出噪音的次数是因为它发现了另一个坏块并告诉您有关显示错误消息的信息。什么是'转换=无错误,同步'是用 NUL 填充坏读,而'iflag=全块'适合短时间阅读,但始终保持数据同步。根本没有损坏,它只是不复制错误的块并用空的 NUL 填充它。

使用 DD 复制完成后,我只需替换那个坏文件,从过去的备份中恢复 Filezilla,一切工作正常。我希望这对其他尝试备份故障驱动器的人有用。

注意:我的坏块彼此非常接近。大约一次将 4 个区块分组在一起检测到不良情况。如果您的块遍布整个磁盘,则多个文件可能会受到影响。幸运的是,就我而言,仅一个 4GB 的大数据库文件受到影响。

相关内容