max*_*zig 8 linux filesystems data-recovery disk
假设您已获悉这样的坏扇区:
[48792.329933] Add. Sense: Unrecovered read error - auto reallocate failed
[48792.329936] sd 0:0:0:0: [sda] CDB:
[48792.329938] Read(10): ...
[48792.329949] end_request: I/O error, dev sda, sector 1545882485
[48792.329968] md/raid1:md126: sda: unrecoverable I/O read error
for block 1544848128
[48792.330018] md: md126: recovery interrupted.
Run Code Online (Sandbox Code Playgroud)
如何找出哪个文件可能包含该扇区?如何将扇区映射到文件?或者如何确定它是否只是映射到可用的文件系统空间?
映射过程应该能够处理通常的存储堆栈。
例如,在上面的示例中,堆栈如下所示:
/dev/sda+sdb -> Linux MD RAID 1 -> LVM PV -> LVM VG -> LVM LV -> XFS
Run Code Online (Sandbox Code Playgroud)
但是,当然,它甚至可以是这样的:
/dev/sda+sdb -> Linux MD RAID 1 -> DM_CRYPT -> LVM PV -> LVM VG -> LVM LV -> XFS
Run Code Online (Sandbox Code Playgroud)
传统的方法是将所有文件复制到别处,看看哪个触发了读取错误。当然,如果错误被 RAID 层的冗余所隐藏,这根本无法回答问题。
除此之外,我只知道手动方法。这太麻烦了,无法实际完成,如果有一种工具可以为您带来这种魔力,我还没有听说过,而且我不确定更通用的工具(如blktrace)是否会对此有所帮助看待。
对于文件系统,您可以使用filefrag或hdparm --fibmap来确定所有文件的块范围。一些文件系统提供了在另一个方向进行查找的工具(例如debugfs icheck),但我不知道有一个系统调用可以做同样的事情,所以似乎没有用于块->文件查找的通用接口。
对于LVM,可以使用lvs -o +devices查看每个LV的存放位置;您还需要知道pvs -o +pe_start,vg_extent_size物理范围偏移/大小。它实际上可能在vgcfgbackup. 这应该允许您将文件系统地址转换为每个 PV 中的块地址。
对于 LUKS,您可以在cryptsetup luksDump.
对于 mdadm,您可以在mdadm --examine. 如果 RAID 级别不是 1,您还需要做一些数学计算,更具体地说,您需要知道 RAID 布局,以便了解md设备上的哪个地址可以转换为哪个 RAID 成员设备的哪个块。
最后,您需要考虑分区偏移量,除非您直接使用磁盘而不进行任何分区。