假设您已获悉这样的坏扇区:
[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.
如何找出哪个文件可能包含该扇区?如何将扇区映射到文件?或者如何查明它是否仅映射到可用文件系统空间?
映射过程应该能够处理通常的存储堆栈。
例如,在上面的示例中,堆栈如下所示:
/dev/sda+sdb -> Linux MD RAID 1 -> LVM PV -> LVM VG -> LVM LV -> XFS
但是,当然,它甚至可以是这样的:
/dev/sda+sdb -> Linux MD RAID 1 -> DM_CRYPT -> LVM PV -> LVM VG -> LVM LV -> XFS
答案1
传统的方法是将所有文件复制到其他地方,然后查看哪个文件触发了读取错误。当然,如果错误被 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 成员设备的哪个块。
最后,您需要考虑分区偏移量,除非您直接使用磁盘而不进行任何分区。