2009年7月23日星期四

恢复ext3文件系统上被删除的文件

发信人: josephpei (linux), 信区: LinuxApp
标  题: 恢复ext3文件系统上被删除的文件
发信站: 水木社区 (Fri Jul 24 00:29:35 2009), 站内

zz未验证

http://mlsx.xplore.cn/2009/07/22/recover-undeleted-files-on-ext3-filesystem.html

是的,我知道ext3文件系统上,一旦文件被删除(rm -rf ),就几乎没有恢复的可能。而且从ext3文件系统的FAQ中提到的一条也能印证这点:

    Q: How can I recover (undelete) deleted files from my ext3 partition?

    Actually, you can’t! This is what one of the developers, Andreas Dilger, said about it:

    In order to ensure that ext3 can safely resume an unlink after a crash, it actually zeros out the block pointers in the inode, whereas ext2 just marks these blocks as unused in the block bitmaps and marks the inode as “deleted” and leaves the block pointers alone.

    Your only hope is to “grep” for parts of your files that have been deleted and hope for the best.

但是,但是,这不是事实的全部,被删除文件的所有信息可能都还在磁盘上,包括块指针。

Carlo Wood在2008年2月7日不小心使用了rm -rf 删除了/home目录,损失数据超过3GB,而唯一的备份还是2007年6月份的,他不甘心他的数据就这么丢失,于是就还是研究ext3文件系统,牛人就 是牛人,他花了3个星期,写了将近5000行代码,他恢复了所有的文件。

光说不练是假把式,我们就祭出他的工具–ext3grep。如果你是debian/ubuntu用户,那你走运了,直接sudo apt-get install ext3grep就可以了,其他系统我没有尝试过,源代码可以在这里下载。

我 们可以一步一步的从文件系统原理来告诉你如何恢复一个文件,但是我怕你还没有看完,就走人了,所以我就先给一个快速演示给大家看看:我们先删除 /boot目录(/dev/sda2分区)下的某一个文件(如果你不相信他能恢复,请先行备份),然后利用这个工具来恢复这个文件。

1)备份并删除文件

root@wgzhao-nb:/boot# cp initrd.img-2.6.28-13-generic  /var/tmp/
root@wgzhao-nb:/boot# mount -o rw,remount /dev/sda2 /boot
root@wgzhao-nb:/boot# rm -rf initrd.img-2.6.28-13-generic
root@wgzhao-nb:/boot# sync

2)如果你为了保险其间,可以立刻将boot分区(/dev/sda2)挂载为只读

root@wgzhao-nb:/boot# mount -o remount,ro /dev/sda2 /boot

3)假定你不记得你要恢复的文件的名字了(大部分情况是不会记得的),我们要列出包含删除文件目录下所有包含的文件,包括被删除的文件。

root@wgzhao-nb:/boot# ext3grep /dev/sda2 --dump-names
Running ext3grep version 0.10.1
WARNING: I don't know what EXT3_FEATURE_COMPAT_EXT_ATTR is.
Number of groups: 13
Minimum / maximum journal block: 527 / 4641
Loading journal descriptors... sorting... done
The oldest inode block that is still in the journal, appears to be from 1246156824 = Sun Jun 28 10:40:24 2009
Number of descriptors in journal: 364; min / max sequence numbers: 310 / 883
Finding all blocks that might be directories.
 
[...]
 
System.map-2.6.18-128.1.14.el5
System.map-2.6.18-53.11AXS3
System.map-2.6.28-13-generic
System.map-2.6.28-14-generic
System.map-2.6.30-10-generic
System.map-2.6.30-10-generic.dpkg-new
System.map-2.6.30-10-generic.dpkg-tmp
 
[...]
lost+found
module-info
symvers-2.6.18-128.1.14.el5.gz
symvers-2.6.18-53.11AXS3.gz
vmcoreinfo-2.6.28-13-generic
vmcoreinfo-2.6.28-14-generic
vmcoreinfo-2.6.30-10-generic
vmcoreinfo-2.6.30-10-generic.dpkg-new
vmcoreinfo-2.6.30-10-generic.dpkg-tmp
vmlinuz
vmlinuz-2.6.18-128.1.14.el5
vmlinuz-2.6.18-53.11AXS3
vmlinuz-2.6.28-13-generic
vmlinuz-2.6.28-14-generic
vmlinuz-2.6.30-10-generic
vmlinuz-2.6.30-10-generic.dpkg-tmp

4)看了这个列表你总知道你要恢复的文件名字了吧,我们这里是initrd.img-2.6.28-13-generic,如果你还是不记得,唉,好人做到底,给你必杀技,使用下面的指令:

root@wgzhao-nb:/boot# ext3grep /dev/sda2 --ls --inode $(ls -id  /boot |awk '{print $1}')
Running ext3grep version 0.10.1
WARNING: I don't know what EXT3_FEATURE_COMPAT_EXT_ATTR is.
Number of groups: 13
Loading group metadata... done
Minimum / maximum journal block: 527 / 4641
Loading journal descriptors... sorting... done
The oldest inode block that is still in the journal, appears to be from 1246156824 = Sun Jun 28 10:40:24 2009
Number of descriptors in journal: 364; min / max sequence numbers: 310 / 883
Inode is Allocated
Finding all blocks that might be directories.
D: block containing directory start, d: block containing more directory entries.
Each plus represents a directory start that references the same inode as a directory start that we found previously.
 
Writing analysis so far to 'sda2.ext3grep.stage2'. Delete that file if you want to do this stage again.
The first block of the directory is 513.
Inode 2 is directory "".
Directory block 513:
.-- File type in dir_entry (r=regular file, d=directory, l=symlink)
|          .-- D: Deleted ; R: Reallocated
Indx Next |  Inode   | Deletion time                        Mode        File name
==========+==========+----------------data-from-inode------+-----------+=========
0    1 d       2                                         drwxr-xr-x  .
1  end d       2                                         drwxr-xr-x  ..
6    7 r      14  D 1248245870 Wed Jul 22 14:57:50 2009  rrw-r--r--  symvers-2.6.18-53.11AXS3.gz
15   16 r    6058  D 1248086531 Mon Jul 20 18:42:11 2009  rrw-r--r--  vmlinuz-2.6.28-13-generic
16   17 r    6063  D 1248086910 Mon Jul 20 18:48:30 2009  rrw-r--r--  System.map-2.6.28-13-generic
17   18 r    6054  D 1248086910 Mon Jul 20 18:48:30 2009  rrw-r--r--  initrd.img-2.6.28-13-generic
18   19 r    6059  D 1248086557 Mon Jul 20 18:42:37 2009  rrw-r--r--  config-2.6.28-13-generic
19   20 r    6064  D 1248086910 Mon Jul 20 18:48:30 2009  rrw-r--r--  vmcoreinfo-2.6.28-13-generic
22   23 r    6057  D 1248086910 Mon Jul 20 18:48:30 2009  rrw-r--r--  abi-2.6.28-13-generic.dpkg-tmp
24   26 r    6056  D 1248086910 Mon Jul 20 18:48:30 2009  rrw-r--r--  config-2.6.28-13-generic.dpkg-tmp
 
[...]

以上你看到的D标志的,就是被删除的文件,这你总知道了吧,还是不知道,那就再往后看,最后有一个必必杀计。

5)接着我们恢复文件,这是关键:

root@wgzhao-nb:~# cd /tmp
root@wgzhao-nb:/tmp# ext3grep $IMAGE --restore-file initrd.img-2.6.28-13-generic
[...]
Restoring initrd.img-2.6.28-13-generic
 
root@wgzhao-nb:/tmp# md5sum RESTORED_FILES/initrd.img-2.6.28-13-generic
22092b1719a7601674fc59ff4a534dc9  RESTORED_FILES/initrd.img-2.6.28-13-generic
root@wgzhao-nb:/tmp# md5sum /var/tmp/initrd.img-2.6.28-13-generic
22092b1719a7601674fc59ff4a534dc9  /var/tmp/initrd.img-2.6.28-13-generic

由 此我们知道恢复出来的文件是完整的。这里要注意的是–restore-file 的文件参数,文件参数应该包括文件相对路径,相对路径指的是相对你指定的设备,比如/dev/sda2就是/boot的根目录,而initrd.img- 2.6.28-13-generic在/boot目录下,因此这里直接给出文件名就好了,如果是需要恢复/boot/grub/grub.conf文件的 话,那么指定的参数就应该像下面这样:
root@wgzhao-nb:#ext3grep /dev/sda2 –restore-file grub/grub.conf

细心的你,你可能知道了,他指定文件的方式就和grub一样,比如(hd0,1)/grub/grub.conf这样。

以上是恢复一个文件的简单步骤,如果你想从ext3文件系统原理着手来看如何逐步恢复一个文件的话,请看ext3grep的作者自己写的howto,那里给出了一个非常详细的步骤,使得你对ext3文件系统一定有更深入的了解。

如 果你有N个文件需要恢复(N>100),那么用上面的方法看就比较恼火了,所以作者给ext3grep增加了一个–restore-all 的参数。它能把指定设备的所有看你能恢复的文件都恢复出来,写入一个RESTORED_FILES目录里。作者建议使用–restore-all的参数 时,同时指定–after参数,表示指定恢复什么时间之后被删除的文件,这是为了防止用恢复过多的旧文件,算是一种过滤方式。参数为时间戳格式,比如:
ext3grep –restore-all –after 1245676061
表示恢复自2009-06-22 21:07以后删除的文件。

OK,更详细更强大的功能,自己去看作者的howto吧。

--
http://josephpei.blogspot.com


※ 来源:・水木社区 newsmth.net・[FROM: 118.203.9.*]

没有评论: