![我能否找出给定的 ext4 块是否在 inode 表中,如果是,我可以从没有标题的日志中手动挑选它吗?](https://linux22.com/image/35635/%E6%88%91%E8%83%BD%E5%90%A6%E6%89%BE%E5%87%BA%E7%BB%99%E5%AE%9A%E7%9A%84%20ext4%20%E5%9D%97%E6%98%AF%E5%90%A6%E5%9C%A8%20inode%20%E8%A1%A8%E4%B8%AD%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%98%AF%EF%BC%8C%E6%88%91%E5%8F%AF%E4%BB%A5%E4%BB%8E%E6%B2%A1%E6%9C%89%E6%A0%87%E9%A2%98%E7%9A%84%E6%97%A5%E5%BF%97%E4%B8%AD%E6%89%8B%E5%8A%A8%E6%8C%91%E9%80%89%E5%AE%83%E5%90%97%EF%BC%9F.png)
因此,在从我的旧笔记本电脑更换为新笔记本电脑的过程中,我的旧笔记本电脑的硬盘驱动器受到了一些物理损坏。badblocks
报告 64 个坏扇区。我有一个两个月前的 Ubuntu GNOME 设置,带有分割/
和/home
分区。据我所知,其中的一些扇区/
已损坏,但这不是问题。另一方面,/home
的分区给了我这个带注释的 ddrescue 日志:
# Rescue Logfile. Created by GNU ddrescue version 1.17
# Command line: ddrescue -d -r -1 /dev/sdb2 home.img home.log
# current_pos current_status
0x6788008400 -
# pos size status
0x00000000 0x6788000000 +
0x6788000000 0x0000A000 -
first 10 sectors of the ext4 journal
0x678800A000 0x2378016000 +
0x8B00020000 0x00001000 -
inode table entries for /pietro (my $HOME) and a few folders within
0x8B00021000 0x00006000 +
0x8B00027000 0x00001000 -
unknown (inode table?)
0x8B00028000 0x00004000 +
0x8B0002C000 0x00001000 -
unknown (inode table?)
0x8B0002D000 0x001DC000 +
0x8B00209000 0x00001000 -
unknown (inode table?)
0x8B0020A000 0x00090000 +
0x8B0029A000 0x00001000 -
unknown (inode table?)
0x8B0029B000 0x4420E65000 +
我使用 debugfsicheck
和testb
命令进行了注释;所有损坏的块都标记为已使用。一些超级块统计数据:
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 972
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8192
Inode blocks per group: 512
所以我的问题是:
- 如果不是索引节点条目,我能否准确找出这五个未知块是什么?我怀疑它们是 inode 表条目,但
icheck
不想说。如果是的话,我能找出哪些索引节点吗? - 即使日志的前 10 个块丢失,我仍然可以从日志中手动恢复这些 inode 表条目吗?
我宁愿不使用 进行数据恢复fsck
,这只会将我的所有文件转储到/lost+found
一大堆扁平的目录结构和重复文件中......
谢谢。
答案1
好吧,对于第一个问题,命令debugfs
stats
告诉我们组中每个部分的起始块是什么。此外,我猜测 innumbers 必须是连续的并且递增,因此将偏移量基本添加到 inode 表中,并且命令imap
给了我第一个 innumbers;它还证实了我对最后一个坏扇区的怀疑,我的块组计算表明它位于错误的组中。
byte address block group what first inumber
0x8B00020000 145752096 4448 inode table block 0 36438017
0x8B00027000 145752103 4448 inode table block 7 36438129
0x8B0002C000 145752108 4448 inode table block 12 36438209
0x8B00209000 145752585 4448 inode table block 489 36445841
0x8B0029A000 145752730 4449 inode table block 122 36448161
由于一个块为 4096 字节,每个 inode 表条目为 256 字节,因此每个块有 16 个 inode。现在我已经按编号列出了全部 80 个丢失的 inode 表条目。
现在让我们转向日记。我写一个小工具将信息转储到日志的每个块中。由于日志超级块丢失,因此我需要的两条信息丢失了:
- 日志是否保存 64 位块号
- 该期刊是否使用版本 3 校验和
幸运的是,如果我强制打开其中一个(或两个)开关,日志中的某些描述符块就会溢出其块,证明这些标志未设置。
一个 awk 脚本 ( fulllog.awk
) 之后,我有一个以下形式的日志
0x0002A000 - descriptors
0x0002B000 -> block 159383670
0x0002C000 -> block 159383671
0x0002D000 -> block 0
0x0002E000 -> block 155189280
0x0002F000 -> block 195559440
0x00030000 -> block 47
0x00031000 -> block 195559643
0x00032000 -> block 195568036
0x00033000 -> block 159383672
0x0002B000 - invalid/data block
0x0002C000 - invalid/data block
0x0002D000 - invalid/data block
0x0002E000 - invalid/data block
0x0002F000 - invalid/data block
0x00030000 - invalid/data block
0x00031000 - invalid/data block
0x00032000 - invalid/data block
0x00033000 - invalid/data block
0x00034000 - commit record
commit time: 2014-12-25 16:53:13.703902604 -0500 EST
这样,另一个 awk 脚本 ( dumpallfor.awk
) 转储所有块:
byte address block number of journaled blocks
0x8B00020000 145752096 6
0x8B00027000 145752103 10
0x8B0002C000 145752108 206
0x8B00209000 145752585 1
0x8B0029A000 145752730 0
debugfs
所以最后一个块确实丢失了:(如果幸运的话,我可以用的命令找出那里有哪些文件ncheck
。
所以我有一堆块。而且它们似乎都不同!怎么办?
我可以通过撤销记录,但我似乎无法有意义地解析该结构。我可以按照提交记录时间戳进行操作,但在尝试之前,我想看看每个 inode 表块有何不同。所以我写了另一个快速程序( diff.go
) 来找出答案。
大多数情况下,不同的文件仅在时间戳上有所不同,因此我们可以选择具有最新时间戳的文件。我们稍后会这样做。对于所有其他文件,我们得到:
36438023 - size differs
36438139 - OSD1 (file version high dword) differs
36438209 - OSD1 differs
嗯,这不太好...不同大小的文件将是一个问题,我不知道如何处理两个 OSD1 文件。我还尝试使用debugfs
'sncheck
来查看文件是什么,但我们没有匹配的文件。
然后我发现哪些块转储现在具有最新的时间戳(相同的存储库latest.go
)。需要注意的重要一点是,我按照提交时间的时间顺序扫描了块。这不一定与按块编号的数字顺序相同;日志并不总是按时间顺序存储。
然而,事实证明,最新的块(按提交时间)确实是具有最新时间戳的块!
让我们尝试一下这些最新的块,看看是否可以从中恢复任何内容。
sudo dd if=BLOCKFILE of=DDRESCUEIMG bs=1 seek=BYTEOFFSET conv=notrunc
之后我的主目录就回来了!
现在让我们找出这三个不同的文件是什么......
Inode Pathname
36438023 /pietro/.cache/gdm/session.log
36438209 /pietro/.config/liferea
36438139 /pietro/.local/share/zeitgeist/fts.index
唯一重要的是 Liferea 的配置目录,但我不认为它已损坏;它曾是OSD1 不同的之一。
让我们找出最后一个块中我们无法恢复的 16 个 inode:
Inode Pathname
36448176 /pietro/k2
36448175 /pietro/Downloads/sOMe4P7.jpg
36448174 /pietro/Downloads/picture.png
36448164 /pietro/Downloads/tumblr_nfjvg292T21s4pk45o1_1280.png
36448169 /pietro/Downloads/METROID Super Zeromission v.2.3+HARD_v2.4.zip
36448165 /pietro/Downloads/tumblr_mrfex1kuxa1sbx6kgo1_500.jpg
36448173 /pietro/Downloads/1*-vuzP4JAoPf9S6ZdHNR_Jg.jpeg
36448162 /pietro/.cache/upstart/gnome-settings-daemon.log.6.gz
36448163 /pietro/.cache/upstart/dbus.log.7.gz
36448171 /pietro/.cache/upstart/gnome-settings-daemon.log.3.gz
36448161 /pietro/.local/share/applications/Knytt Underground.desktop
36448166 /pietro/Documents/Screenshots/Screenshot from 2014-12-03 15:47:29.png
36448170 /pietro/Documents/Screenshots/Screenshot from 2014-12-03 16:51:26.png
36448172 /pietro/Documents/Screenshots/Screenshot from 2014-12-03 19:08:54.png
36448168 /pietro/Documents/transactions/premiere to operating transaction 4305747926.pdf
36448167 /pietro/Documents/transactions/transaction 4315883542.pdf
简而言之:
- 一个文本文件,其中只有一两个内容,我可以通过暴力方式取回,因为我知道它有日期戳和我的聊天日志中也有的内容
- 一些从互联网上下载的图片;如果我无法从 Firefox 历史记录中获取 URL,那么我可以使用 photorec
- 我可以轻松地再次上网的 ROM hack =P
- 日志文件;这里没有损失
- Steam 游戏的 .desktop 文件
- 屏幕截图;我可以用 photorec 取回这些信息,假设 gnome-screenshot 添加了日期戳作为元数据
- 银行账户交易记录;如果我无法从银行获取它们,我可能可以将它们与 photorec 一起使用
所以虽然不是没有伤亡,但也不是全盘皆输,而且我在这个过程中了解了更多关于 ext4 的知识。不管怎么说,还是要谢谢你!
更新
不妨把这个放在那里:
NOT YET /pietro/k2
FOUND /pietro/Downloads/sOMe4P7.jpg
NOT YET /pietro/Downloads/picture.png
FOUND /pietro/Downloads/tumblr_nfjvg292T21s4pk45o1_1280.png
GOOGLEIT /pietro/Downloads/METROID Super Zeromission v.2.3+HARD_v2.4.zip
FOUND /pietro/Downloads/tumblr_mrfex1kuxa1sbx6kgo1_500.jpg
FOUND /pietro/Downloads/1*-vuzP4JAoPf9S6ZdHNR_Jg.jpeg
UNNEEDED /pietro/.cache/upstart/gnome-settings-daemon.log.6.gz
UNNEEDED /pietro/.cache/upstart/dbus.log.7.gz
UNNEEDED /pietro/.cache/upstart/gnome-settings-daemon.log.3.gz
UNNEEDED /pietro/.local/share/applications/Knytt Underground.desktop
NOT YET /pietro/Documents/Screenshots/Screenshot from 2014-12-03 15:47:29.png
NOT YET /pietro/Documents/Screenshots/Screenshot from 2014-12-03 16:51:26.png
NOT YET /pietro/Documents/Screenshots/Screenshot from 2014-12-03 19:08:54.png
NOT YET /pietro/Documents/transactions/premiere to operating transaction 4305747926.pdf
NOT YET /pietro/Documents/transactions/transaction 4315883542.pdf
如果我不够奇怪的话,下载的图片是:
sOMe4P7.jpg
(对《法律与秩序》标题卡的模仿《与指关节》添加到其中)tumblr_nfjvg292T21s4pk45o1_1280.png
(截图为JK 罗琳的这条推文)tumblr_mrfex1kuxa1sbx6kgo1_500.jpg
(图片显示“Windows 未成功关闭。”广告牌上的错误消息,似乎是在某体育赛事中)1*-vuzP4JAoPf9S6ZdHNR_Jg.jpeg
(这部漫画)
这些都是朋友在聊天中分享的。
我想我会保持更新? (不像会有所作为......)我知道我可以恢复一切;唯一的问题是何时 =P