免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10268 | 回复: 15
打印 上一主题 下一主题

[其他] 对ext3下的文件恢复1 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-01-20 09:42 |只看该作者 |正序浏览


任何一个系统管理员,包括有经验的和新手,误删除一个有用的文件是迟早发生的事,发生了这种事后果你比谁都清楚,别人删除了文件找你你还有的说,自己删的又是有用的,那就什么也别说了,想办法找吧!



对于ext2文件系统,现在用的很少了,而且也比较好恢复,在这里就不说了,现在用的最多的是ext3文件系统,ext4也已经成熟,有不少Linux的发行版本中已经开始使用了。


那么就针对ext3文件系统来恢复,注意ext3grep只对ext3文件系统来恢复。



1 下载并安装ext3grep



工具ext3grep是一款开源软件,功能比较强大,但遗憾的是这个项目没有自己的主页,也没有相关的文档,在该地址http://code.google.com/p/ext3grep/可以找到相关的下载连接,当前最新的版本为0.10.2.,另外在这个比较干净页面上,你必须注意到一处“here”,如下图,在这里你可以找到你想要的东西,我们在后面会用到这个文档:



file:///C:/DOCUME%7E1/t/LOCALS%7E1/Temp/msohtml1/01/clip_image002.jpg



1.下载ext3grep


  

[root@nas  ~]#wget http://ext3grep.googlecode.com/files/ext3grep-0.10.2.tar.gz

  


2. 解压并安装:


  

[root@nas  ~]# tar -zxvf ext3grep-0.10.2.tar.gz

  

[root@nas  ~]#cd ext3grep-0.10.2

  

[root@nas  ext3grep-0.10.2]# ./configure
--prefix=/usr/local/ext3grep

  

[root@nas  ext3grep-0.10.2]# make

  

[root@nas  ext3grep-0.10.2]# make check

  

[root@nas  ext3grep-0.10.2]# make install

  


……

  

make[2]:  Entering directory `/root/ext3grep-0.10.2/src'

  

make[3]:  Entering directory `/root/ext3grep-0.10.2/src'

  

test -z  "/usr/local/ext3grep/bin" || /bin/mkdir -p  "/usr/local/ext3grep/bin"

  



/usr/bin/install -c ext3grep  '/usr/local/ext3grep/bin'

  

make[3]:  Nothing to be done for `install-data-am'.

  

make[3]:  Leaving directory `/root/ext3grep-0.10.2/src'

  

……

  


  


3. ext3grep的使用方法


从安装的结果来看只有一个ext3grep文件,连个man文档都没有,只能通过该命令的帮助获取的信息了:


  

[root@nas bin]# ./ext3grep --help

  

Running ext3grep version 0.10.2

  

Usage: ./ext3grep [options] [--] device-file

  

…… //省略

  


分析理解一下上面省略的参数,我们将它分为三部分来分析,以便于了解ext3grep的功能。


选项(Options)


  



  
  







  
  

--version, -[vV]

  
  

显示 ext3grep的版本号并退出

  
  

--help

  
  

显示帮助信息并退出

  
  

--superblock

  
  

显示superblock的内容

  
  

--print

  
  

显示block或inode的内容

  
  

--ls

  
  

一行一个条目的显示目录

  
  

--accept filen

  
  

接受'filen'作为合法的(legal)文件名,可以多次使用--accept;如果改变了任何--accept,那么必须删除那两个stage*文件

  
  

--accept-all

  
  

简单的接受一切作为文件名

  
  

--journal

  
  

显示journal内容

  
  

--show-path-inodes

  
  

在路径中显示每一个组成目录的inode

  


过滤器(Filters)



通过使用过滤器,你可以过滤感兴趣的数据,以便在零乱的数据中找到你有用东西。


  





  
  






  
  

--group grp

  
  

只处理指定的组'grp'

  
  

--directory

  
  

只处理目录节点

  
  

--after dtime

  
  

只包括指定的'dtime'时间以后删除的文件

  
  

--before dtime

  
  

只包括指定的'dtime'时间以前删除的文件

  
  

--deleted

  
  

只显示/处理被删除的文件

  
  

--allocated

  
  

只显示/处理分配的inodes/blocks

  
  

--unallocated

  
  

只显示/处理没有分配的inodes/blocks  

  
  

--reallocated

  
  

不阻止再分配节点。如果条目已被删除,但是节点被分配,那么节点会被考虑重新分配。

  
  

--zeroed-inodes

  
  

不阻止零节点

  
  

--depth depth

  
  

对目录处理的递归深度。

  


动作(Actions):


  




  
  




  
  

--inode-to-block ino

  
  

显示包含节点 'ino'的block

  
  

--inode ino

  
  

显示节点 'ino'的资料信息。如果使用了--ls并且节点是一个目录,那么还可以使用过滤器。如果不使用--ls,那么--print参数被暗包含使用

  
  

--block blk

  
  

显示块'blk'的资料信息。如果使用了--ls,并且该块是目录的第一个块,那么可以使用过滤器。如果不使用--ls,那么--print参数被暗包含使用

  
  

--histogram=[atime|ctime

  

|mtime|dtime|group]

  


  
  

基于一个给定的规格产生一种基于柱状图,以便给出说明,使用atime,ctime或 mtime的目的在于使用过滤器--after 和 --before之间的时间产生柱状图。

  
  

--journal-block jblk

  
  

显示日志块'jblk'的信息。

  
  

--journal-transaction seq

  
  

显示通过处理序号'seq'得到的信息。

  
  

--dump-names

  
  

在标准的输出设备上打印出文件的路径。这暗示了--ls参数,但是抑制了它的输出

  
  

--search-start str

  
  

查找以'str'固定字符串开始的块

  
  

--search str

  
  

查找包含固定字符串'str'的块

  
  

--search-inode blk

  
  

查找节点,就是指的'blk'的块

  
  

--search-zeroed-inodes

  
  

返回零节点分配表

  
  

--inode-dirblock-table dir

  
  

为目录路径“dir”打印成表,包括目录的block数,以及每一个文件使用的inode

  
  

--show-journal-inodes ino

  
  

显示仍在日志中的“ino”节点的拷贝

  
  

--restore-inode  ino[@seqnr][,ino[@seqnr],...]

  
  

恢复指定的inode节点号文件,被恢复的文件会放在一个被建立的目录./RESTORED_FILES/下,该文件的扩展名为它们的节点号(例如,inode.12345)。如果使用了“@seqn”,那么journal条目的序列号将会被使用,否则仅会使用最后条目的序号。

  
  

--restore-file 'path'

  

[--restore-file 'path' ...]

  
  

恢复文件'path'。'path'和分区的根相关,不要以'/'开始(it
must be one of the paths returned by  --dump-names),被恢复的目录、文件或者是符号链接被放置在'RESTORED_FILES/path'中

  
  

--restore-all

  
  

同--restore-file的功能一样,但是它试图恢复所有的文件,强烈推荐同--after一起使用,因为如果只使用--restore-all那么可能会去恢复很旧的文件,这样可能会导致一个删除很久的文件却被连接到一个最近删除的文件上,这样会影响恢复的意义。

  
  

--show-hardlinks

  
  

显示所有被两个或三个文件共享的节点

  


论坛徽章:
0
16 [报告]
发表于 2011-02-22 10:03 |只看该作者
回复 16# 柳拂风


    试着传了,可是传不上去!

论坛徽章:
0
15 [报告]
发表于 2011-02-15 09:49 |只看该作者
楼主,能不能把文档作为一个附件发上来啊?

论坛徽章:
7
双子座
日期:2013-09-09 15:55:31CU大牛徽章
日期:2013-09-18 15:22:06CU大牛徽章
日期:2013-09-18 15:22:20CU大牛徽章
日期:2013-09-18 15:22:26CU大牛徽章
日期:2013-09-18 15:22:31CU大牛徽章
日期:2013-09-18 15:22:37CU大牛徽章
日期:2013-09-18 15:22:46
14 [报告]
发表于 2011-01-20 21:19 |只看该作者
好文章,可惜没文档啊。

论坛徽章:
0
13 [报告]
发表于 2011-01-20 10:32 |只看该作者
回复 13# nhuczp


   本来是文档,可是这论坛的帖子字数有限。

论坛徽章:
0
12 [报告]
发表于 2011-01-20 10:18 |只看该作者
好长啊!!

建议整个文档发出来!!

论坛徽章:
0
11 [报告]
发表于 2011-01-20 09:59 |只看该作者

注意:


我分析一下上面的结果:



①、“WARNING”,这种情况出现在系统处于“脏”的状态或者是被恢复磁盘处于挂接状态,特别要注意,对于被恢复文件所在的磁盘一定要处于未被挂接的状态;

②、“Writing output to directory RESTORED_FILES/恢复完成后会在用户当前所在的目录中创建一个名RESTORED_FILES的目录,恢复的文件就放置在该目录相应的目录中;同时也要注意,如果在目录RESTORED_FILES/jj已存在,那么它不会被覆盖;

③、“D”和“d”,“D”表了包含了目录的开始;而“d”表示了包含多个目录条目;

④、“sdb1.ext3grep.stage2包含了分析报告;

⑤、“Restoring jj”表示成功恢复了该文件。


按次序,恢复工作会经过两个阶段(stage),阶段1和阶段2,并且创建了两个文件DEVICE.ext3grep.stage1DEVICE.ext3grep.stage2



我们看一下,以下是在执行“ext3grep
/dev/sdb1--restore-file jj
”命令之前的目录结构,只有ext3grep命令:


  

[root@nas bin]# pwd

  

/usr/local/ext3grep/bin

  

[root@nas bin]# tree

  

.

  

`-- ext3grep

  


  

0 directories, 1  file

  



在执行完成“ext3grep
/dev/sdb1--restore-file jj
”命令之后的目录结构:


  

[root@nas bin]#  tree

  

.

  

|-- RESTORED_FILES

  

|
`-- jj

  

|-- ext3grep

  

|--  sdb1.ext3grep.stage1

  

`-- sdb1.ext3grep.stage2

  



为了证实,你可看一下文件jj的内容:


  

[root@nas bin]#  cat RESTORED_FILES/jj

  

123456

  



没问题,绝对恢复了,这是我们要得到的结果。


ext3grep的命令行选项中使用--dump-names可以转储所有文件的文件名:


  

[root@nas ~]# ext3grep
/dev/sdb1 --dump-names

  

Running ext3grep version 0.10.2

  

Number of groups: 597

  

Minimum / maximum journal block: 1545  / 35886

  

Loading journal descriptors...  sorting... done

  

The oldest inode block that is still  in the journal, appears to be from 1273827555 = Fri May 14 16:59:15 2010

  

Number of descriptors in journal: 109;  min / max sequence numbers: 5 / 39

  

Loading sdb1.ext3grep.stage2... done

  

.jj.swp

  

jj

  

lost+found

  

pp

  


如果对选项--dump-names的输出满意,那么就可以用--restore-all选项代替--dump-names来恢复所有文件。--restore-all在效果上实际上就是--restore-file--dump-names的组合。


正如以前提到的,正确的使用选项--after 是一个明智的选择,这样使得ext3grep工作更有效,既避免了ext3grep试图恢复更旧的文件,也缩短了用户的等待时间。注意,这时--dump-names的输出是未滤过的,而--restore-file(--restore-all)可以联合使用--after选项。


例如:


  

[root@nas ~]#ext3grep
/dev/sdb1 --restore-all --after=1274249319

  

Running ext3grep version 0.10.2

  

Only show/process deleted entries if  they are deleted on or after Wed May 19 14:08:39 2010.

  


  

Number of groups: 597

  

Minimum / maximum journal block: 1545  / 35886

  

Loading journal descriptors...  sorting... done

  

The oldest inode block that is still  in the journal, appears to be from 1273827555 = Fri May 14 16:59:15 2010

  

Number of descriptors in journal: 109;  min / max sequence numbers: 5 / 39

  

Loading sdb1.ext3grep.stage2... done

  

Not undeleting ".jj.swp"  because it was deleted before 1274249319 (3214533652)

  

Not undeleting "jj" because  it was deleted before 1274249319 (3214533652)

  

Restoring lost+found

  

Restoring pp

  


可以看到,在这里只有pp文件被恢复,按照--after设定的时间它是最后一个被删除的文件,--after精确到秒级,在设置--after时要比要恢复的文件大1即可。


阶段1的格式:


阶段1的过程被写入DEVICE.ext3grep.stage1文件,这里的DEVICE会被驱动器的名字所替代(例如/dev/sdb1,那么DEVICE就是sdb1)


例如:


  

[root@nas /]# more  sdb1.ext3grep.stage1

  

# Stage 1 data for /dev/sdb1.

  

# Inodes and directory start  blocks that use it for dir entry '.'.

  

# INODE : BLOCK [BLOCK ...]
//
注意这里的格式

  

2 : 1539 1628 1781 1790 2036  2048 2097 3257 3437

  

11 : 1540

  

32769 : 1779 1830 1867 1883  1889 1895 1913 1919 1926 1952 1978 2012 96256

  

507905 : 3435 1021952

  

1048577 : 3255 3266 3282  3293 3299 3309 3317 3323 3338 3561 3568 2123776

  

1048578 : 3337 3344 3352  3357 3370 3378 3383 3396 3409 3414 2111488

  

3522561 : 7057408

  

3522616 : 7072649

  


……

  

7503873 : 15022080

  

# Extended directory blocks.

  

36067

  

102245

  

……

  

7073648

  

# END

  


在这个sdb1.ext3grep.stage1文件中,首先表明了工作对象/dev/sdb1,然后指明了节点和块的格式,在格式这一部分中,第一栏是节点,然后再跟一个空格,空格之后是一个冒号,然后又是一个空格,空格之后是一个使用空格符作为分隔符的block号列表。


阶段2的格式:



阶段2的过程被写入DEVICE.ext3grep.stage2文件,例如:


  

[root@nas bin]#  more sdb1.ext3grep.stage2

  

# Stage 2 data for  /dev/sdb1.

  

# Inodes path and  directory blocks.

  

# INODE PATH BLOCK  [BLOCK ...]

  

2 '' 1539

  

11 'lost+found'  1540 7073648

  

# END

  



在这个阶段,由函数init_directories()来负责,包含了很多启发式的代码。首先决定哪些块是真正的目录开始块,然后分配每一个扩展目录块到其中的目录,最后将这个结果保存在一个文件(DEVICE.ext3grep.stage2),那就是这里的sdb1.ext3grep.stage2。注意文件中每一个条目的格式,万一出了错,你能够通过编辑这个文件(删除无效的或添加正确的块)来修复,然而绝对不要添加或移除注释:如果你对这个文件改变的太多,那么会使得ext3grep感到“困惑”,而不能够正常工作。


最后再次提一点,正确的使用“--after dtime”和“--before dtime”参数特别重要。




论坛徽章:
0
10 [报告]
发表于 2011-01-20 09:58 |只看该作者

上面的结果是自动产生的,要比使用命令行选项--show-journal-inodes快的多。


这个选项用于查找属于一个节点的block,然后再在ext3日志中查找该block的所有拷贝,随后这些仅打印出被请求的inode,而消除了重复性。


  

[root@nas ~]#ext3grep
/dev/sdb1 --show-journal-inodes 49154

  

Running ext3grep version 0.10.2

  

Number of groups: 597

  

Minimum / maximum journal block: 1545  / 35886

  

Loading journal descriptors...  sorting... done

  

The oldest inode block that is still  in the journal, appears to be from 1273827555 = Fri May 14 16:59:15 2010

  

Number of descriptors in journal: 115;  min / max sequence numbers: 5 / 28

  

Copies of inode 49154 found in the  journal:

  


  

--------------Inode 49154 (transaction  ------------------

  

Generation Id: 4288869617

  

uid / gid: 0 / 0

  

mode: rrw-r--r--

  

size: 0

  

num of links: 0

  

sectors: 0 (--> 0 indirect blocks).

  


  

Inode Times:

  

Accessed:

1273827555 = Fri May 14 16:59:15 2010

  

File Modified:
1273827570 = Fri May 14 16:59:30 2010

  

Inode Modified: 1273827570 = Fri May  14 16:59:30 2010

  

Deletion time:
1273827570 = Fri May 14 16:59:30 2010

  


  

Direct Blocks: 0

  


  

--------------Inode 49154 (transaction  7)------------------

  

Generation Id: 4288869617

  

uid / gid: 0 / 0

  

mode: rrw-r--r--

  

size: 7

  

num of links: 1

  

sectors: 8 (--> 0 indirect blocks).

  


  

Inode Times:

  

Accessed:
1273827555 = Fri May 14 16:59:15 2010

  

File Modified:
1273827555 = Fri May 14 16:59:15 2010

  

Inode Modified: 1273827555 = Fri May  14 16:59:15 2010

  

Deletion time:
0

  


  

Direct Blocks: 110600

  


  


文件比较小,只有一个block,通过dd命令拷贝这个block


  

[root@nas ~]# dd if=/dev/sdb1 bs=4096  count=1 skip=110600 of=block.110600

  

1+0 records in

  

1+0 records out

  

4096 bytes (4.1 kB) copied, 0.023085 seconds, 177 kB/s

  


  


然后再通过编辑文件,将尾部的“0”删除,或者是拷贝一下前7个字节(这个大小的选择是上面给出来的“size: 7)


  

[root@nas ~]# dd if=block.110600
bs=1 count=7 of=R_jj

  

7+0 records in

  

7+0 records out

  

7 bytes (7 B) copied, 0.0111848 seconds, 0.6 kB/s

  


然后查看该改恢复的文件:


  

[root@nas ~]# more R_jj

  

123456

  


没错!是我们要找的文件。

2.3恢复多个文件

如果要是恢复大文件,这种情况下,文件存在于许多block中,更不用说手动恢复成千上万个文件了,因此所有的恢复可以自动执行。然而,如果有50,000文件,尤其是被恢复的文件远远的多于你实际想要的,在所有的垃圾文件中很难查找到结果,所以在实际上恢复操作上一定要尽可能的准确的去恢复文件。


下面做一个全新的实验,首先将“/dev/sdb1分区进行格式化


  

[root@nas /]# mkfs.ext3 /dev/sdb1

  

mke2fs 1.39 (29-May-2006)

  

Filesystem label=

  

OS type: Linux

  

Block size=4096 (log=2)

  

Fragment size=4096 (log=2)

  

9781248 inodes, 19531015 blocks

  

976550 blocks (5.00%) reserved for the  super user

  

First data block=0

  

Maximum filesystem blocks=0

  

597 block groups

  

32768 blocks per group, 32768 fragments  per group

  

16384 inodes per group

  

Superblock backups stored on blocks:

  


32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632,  2654208, 4096000, 7962624, 11239424

  


  

Writing inode tables: done

  

Creating journal (32768 blocks): done

  

Writing superblocks and filesystem  accounting information: done

  


  

This filesystem will be automatically  checked every 36 mounts or

  

180 days, whichever comes first.
Use tune2fs -c or -i to override.

  


然后再挂接分区创、建一个文件,再将该文件删除,然后在把分区卸掉:


  

[root@nas ~]#  mount /dev/sdb1 /sdb

  

[root@nas ~]# cd  /sdb

  

[root@nas sdb]# ls

  

lost+found

  

[root@nas sdb]# vi jj

  

123456

  


  

"jj"  [New] 1L, 7C written

  

[root@nas sdb]#

  

[root@nas sdb]# ls

  

lost+found
jj

  

[root@nas sdb]#rm  -f jj

  

[root@nas sdb]# ls

  

lost+found

  

[root@nas /]#  umount /sdb

  

[root@nas /]#

  


使用ext3grep恢复单个文件,只要给出文件的路径就可以了:


  

[root@nas bin]# ./ext3grep
/dev/sdb1 --restore-file jj

  

Running ext3grep version 0.10.2

  

WARNING:  EXT3_FEATURE_INCOMPAT_RECOVER is set. This either means that your partition  is still mounted, and/or the file system is in an unclean state.

  

Number of groups: 597

  

Minimum / maximum journal block: 1545  / 35886

  

Loading journal descriptors...  sorting... done

  

The oldest inode block that is still  in the journal, appears to be from 1294461894 = Sat Jan
8 12:44:54 2011

  

Number of descriptors in journal: 37;  min / max sequence numbers: 2 / 7

  

Writing  output to directory RESTORED_FILES/

  

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.

  


  

Searching group 0: DD++++

  

Searching group 1: WARNING: zero inode  (name: *contains non-ASCII characters* "\004$b,\222D\221D"; block:  36067; offset 0x800)

  

d

  

Searching group 2: D

  

Searching group 3: WARNING: zero inode  (name: "M"; block: 102245; offset 0xf74)

  


  

……
//
省略部分

  

Searching group 215:  DDDDDDDDDDddDDDDDDDDDDDDDDDDDDDDDDDDDDDD

  

……
//
省略部分

  

Searching group 539: D

  

……
//
省略部分

  


  

Writing analysis so far to 'sdb1.ext3grep.stage2'. Delete that  file if you want to do this stage again.

  

Restoring jj

  


  


论坛徽章:
0
9 [报告]
发表于 2011-01-20 09:58 |只看该作者
2.2手动恢复举例

在下面的例子中,将会手动恢复一个小文件。使用“ext3grep
/dev/sdb1 --ls --inode 2来查找想要恢复的文件。


先看一下总体情况:


  

[root@nas ~]# ext3grep
/dev/sdb1 --ls --inode 2

  

Running ext3grep version 0.10.2

  

……

  

Directory block 1539:

  



.-- 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
2 d
2
drwxr-xr-x
..

  


2
end r
11
rrw-r--r--
pp

  


3
4 d 3604481
D 1274249319 Wed May 19 14:08:39 2010
drwxr-xr-x
BB

  


4
end d
98305
D 1274249319 Wed May 19 14:08:39 2010
drwxr-xr-x
CC

  


6
7 r
49153
D 1273827555 Fri May 14 16:59:15 2010
rrw-------
.jj.swp

  


7
end r
49154
D 1273827570 Fri May 14 16:59:30 2010
rrw-r--r--
jj

  


  


可以说显示的内容很多,假如要恢复的文件是jj,那么可以这样:


  

[root@nas ~]# ext3grep
/dev/sdb1 --ls --inode 2 |grep jj

  


6
7 r
49153
D 1273827555 Fri May 14 16:59:15 2010
rrw-------
.jj.swp

  


7
end r
49154
D 1273827570 Fri May 14 16:59:30 2010
rrw-r--r--
jj

  


下面通过ext3grep显示节49154的相关信息:


  

[root@nas ~]#ext3grep
/dev/sdb1 --ls --inode 49154

  

Running ext3grep version 0.10.2

  

Number of groups: 597

  

Minimum / maximum journal block: 1545 / 35886

  

Loading journal descriptors... sorting... done

  

The oldest inode block that is still in the journal,  appears to be from 1273827555 = Fri May 14 16:59:15 2010

  

Number of descriptors in journal: 115; min / max  sequence numbers: 5 / 28

  

Inode is Unallocated

  


  


很显然,节49154已被清除,文件没有被分配节点。


同理如果看文件pp(这个文件没有被删除):


  

[root@nas ~]#ext3grep
/dev/sdb1 --print --inode
11

  

Running ext3grep version 0.10.2

  

Number of groups: 597

  

Loading group metadata... done

  

Minimum / maximum journal block: 1545  / 35886

  

Loading journal descriptors...  sorting... done

  

The oldest inode block that is still  in the journal, appears to be from 1273827555 = Fri May 14 16:59:15 2010

  

Number of descriptors in journal: 109;  min / max sequence numbers: 5 / 39

  


  

Hex dump of inode 11:

  

0000 | a4 81 00 00 07 00 00 00 72 e5 f4 4b 6c e5 f4  4b | ........r..Kl..K

  

0010 | 6c e5 f4  4b 00 00 00 00 00 00 01 00 08 00 00 00 | l..K............

  

0020 | 00 00 00 00 00 00 00 00 2e 8c 00 00 00 00 00 00 | ................

  

0030 | 00 00 00 00 00 00 00 00 00 00  00 00 00 00 00 00 | ................

  

0040 | 00 00 00 00 00 00 00 00 00 00  00 00 00 00 00 00 | ................

  

0050 | 00 00 00 00 00 00 00 00 00 00  00 00 00 00 00 00 | ................

  

0060 | 00 00 00 00 b5 d8 dd 03 00 00  00 00 00 00 00 00 | ................

  

0070 | 00 00 00 00 00 00 00 00 00 00  00 00 00 00 00 00 | ................

  


  

Inode is  Allocated

  

Group: 0

  

Generation Id: 64870581

  

uid / gid: 0 / 0

  

mode: rrw-r--r--

  

size: 7

  

num of links: 1

  

sectors: 8 (--> 0 indirect blocks).

  


  

Inode Times:

  

Accessed:
1274340722 = Thu May 20 15:32:02 2010

  

File Modified:
1274340716 = Thu May 20 15:31:56 2010

  

Inode Modified: 1274340716 = Thu May  20 15:31:56 2010

  

Deletion time:
0

  


  

Direct Blocks: 35886

  


这个“Inode is Allocated”很有说明性。


下面接着恢复这个jj文件,在此我们试图去日志中查找一个老版本的拷贝。首先查找包括本inode的系统块:


  

[root@nas ~]#ext3grep
/dev/sdb1 --inode-to-block 49154 | grep  resides

  

Inode 49154 resides in block 99331 at  offset 0x80.

  


  


然后查找所有与block 99331相关日志块:


  

[root@nas ~]#ext3grep
/dev/sdb1 --journal --block
99331

  

Running ext3grep version 0.10.2

  

No --ls used; implying --print.

  


  

Minimum / maximum journal block: 1545  / 35886

  

Loading journal descriptors...  sorting... done

  

The oldest inode block that is still  in the journal, appears to be from 1273827555 = Fri May 14 16:59:15 2010

  

Number of descriptors in journal: 115;  min / max sequence numbers: 5 / 28

  

Journal descriptors referencing block  99331:

  

6 1699

  

7 1706

  

8 1718

  


  


我们可以看出,ext3的日志描述“block 99331”被记载(或者叫缓存,然而既然是日志,叫做记录更好,可是汉语的角度上讲记录又不是这个意思,所有就叫它记载了!)在:



6 1699

7 1706

8 1718


序号为678block中,换句话说就是序列号为6block是一block 99331的拷贝,它存储在节点1699上,序列号为7block也是一block 99331的拷贝,它存储在节点1706上,等等。


按照规定,最近的序列号在最底部,这应该是最近写入磁盘的块号,因此block 1718的内容应该是和当前block 99331样的。为了查找一个最后的没有删除(叫做擦除更合适)的拷贝,一种可选的方式是从底部开始向上查找。


如果想打印这样一个blockext3grep能够从节点表识别出该block,那么并打印(显示)出所有节点的内容,然而现在只想看到的是节点49154,因此需要使用命令grep


  


[root@nas ~]#ext3grep
/dev/sdb1 --print --block 1718 | grep -A15  'Inode 49154'

  

--------------Inode  49154-----------------------

  

Generation Id: 4288869617

  

uid / gid: 0 / 0

  

mode: rrw-r--r--

  

size: 0

  

num of links: 0

  

sectors: 0 (--> 0 indirect blocks).

  


  

Inode Times:

  

Accessed:
1273827555 = Fri May 14 16:59:15 2010

  

File Modified:
1273827570 = Fri May 14 16:59:30 2010

  

Inode Modified: 1273827570 = Fri May  14 16:59:30 2010

  

Deletion time:
1273827570 = Fri May 14 16:59:30 2010

  


  

Direct Blocks: 0

  


  


确实是这样,我们在99331块中看到的一样,下一步我们可以进一步查看其它的序列号,直到我们找到一个与我们删除时间相差0的一个序列号所代表的块,正如我们现在找到的1718 block


  

[root@nas ~]# ext3grep
/dev/sdb1 --print --block 1699 | grep -A15  'Inode 49154'

  

--------------Inode 49154-----------------------

  

Generation Id: 4288869617

  

uid / gid: 0 / 0

  

mode: rrw-r--r--

  

size: 7

  

num of links: 1

  

sectors: 8 (--> 0 indirect blocks).

  


  

Inode Times:

  

Accessed:
1273827555 = Fri May 14 16:59:15 2010

  

File Modified:
1273827555 = Fri May 14 16:59:15 2010

  

Inode Modified: 1273827555 = Fri May 14 16:59:15 2010

  

Deletion time:
0

  


  

Direct Blocks: 110600

  

论坛徽章:
0
8 [报告]
发表于 2011-01-20 09:57 |只看该作者

可以看到journal的大小是134217728字节,或32768(134217728/4096=3276block,这个值在前面的格式化中也见过“Creating journal (32768 blocks): done”。前12block直接列在该节点内:1545-1156,还有一个间接block1557
这个间接块可以包含1024block,这些block(1158-2181)都跟随在这个间接block之后。然后是一个二次间接(double indirect)2582


Journal文件中的第一个block (在上面的例子为:block 1545),其结构在文件中定义/usr/include/linux/jbd.h


  

/*

  


* The journal superblock.
All fields are in big-endian byte order.

  


*/

  

typedef struct journal_superblock_s

  

{

  

/* 0x0000 */

  


journal_header_t s_header;

  


  

/* 0x000C */

  


/* Static information describing the journal */

  


__be32
s_blocksize;
/* journal device blocksize */

  


__be32
s_maxlen;
/* total blocks in journal  file */

  


__be32
s_first;
/* first block of log information  */

  


  

/* 0x0018 */

  


/* Dynamic information describing the current state of the log */

  


__be32
s_sequence;
/* first commit ID expected in  log */

  


__be32
s_start;
/* blocknr of start of log */

  


  

/* 0x0020 */

  


/* Error value, as set by journal_abort(). */

  


__be32
s_errno;

  


  

/* 0x0024 */

  


/* Remaining fields are only valid in a version-2 superblock */

  


__be32
s_feature_compat;
/* compatible feature set */

  


__be32
s_feature_incompat;
/* incompatible feature set */

  


__be32
s_feature_ro_compat;
/*  readonly-compatible feature set */

  

/* 0x0030 */

  


__u8
s_uuid[16];
/* 128-bit uuid for journal */

  


  

/* 0x0040 */

  


__be32
s_nr_users;
/* Nr of filesystems sharing log  */

  


  


__be32
s_dynsuper;
/* Blocknr of dynamic superblock  copy*/

  


  

/* 0x0048 */

  


__be32
s_max_transaction;
/* Limit of journal blocks per trans.*/

  


__be32
s_max_trans_data;
/* Limit of data blocks per trans. */

  


  

/* 0x0050 */

  


__u32
s_padding[44];

  


  

/* 0x0100 */

  


__u8
s_users[16*48];
/* ids of all fs'es sharing the log  */

  

/* 0x0400 */

  

} journal_superblock_t;

  


ext3grep命令可以得到:


  

[root@nas ~]# ext3grep
/dev/sdb1 --journal --superblock

  

Running ext3grep version 0.10.2

  

Journal Super Block:

  


  

Signature: 0x3225106840

  

Block type: Superblock version 2

  

Sequence Number: 0

  

Journal block size: 4096

  

Number of  journal blocks: 32768

  

Journal block  where the journal actually starts: 1

  

Sequence number of first transaction:  30

  

Journal block of first transaction: 0

  

Error number: 0

  

Compatible Features: 0

  

Incompatible features: 1

  

Read only compatible features: 0

  

Journal UUID: 0xc6 0xe6 0x7d 0xb9 0xf8  0x6a 0x41 0xe5 0x9f 0xb0 0xc0 0x9b 0xd4 0x1b 0x57 0x7a

  

Number of file systems using journal:  1

  

Location of superblock copy: 0

  

Max journal blocks per transaction: 0

  

Max file system blocks per  transaction: 0

  

IDs of all file systems using the journal:

  

1. 0x00 0x00 0x00 0x00 0x00 0x00 0x00  0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

  


  

Minimum / maximum journal block: 1545  / 35886

  

Loading journal descriptors...  sorting... done

  

The oldest inode block that is still  in the journal, appears to be from 1273827555 = Fri May 14 16:59:15 2010

  

Number of descriptors in journal: 115;  min / max sequence numbers: 5 / 28

  


在这里可以看出日志实际上是由Journal Block Number
1开始,最后一个block为“Journal Block Number
32768,不同的文件系统这些值是不一样的,但是你可以通过以下的方法找到真正的block号,例如:


  

[root@nas ~]# ext3grep
/dev/sdb1 --journal --journal-block 1

  

Running ext3grep version 0.10.2

  

Minimum / maximum journal block: 1545  / 35886

  

Loading journal descriptors...  sorting... done

  

The oldest inode block that is still  in the journal, appears to be from 1273827555 = Fri May 14 16:59:15 2010

  

Number of descriptors in journal: 115;  min / max sequence numbers: 5 / 28

  

Group: 0

  

Block 1546  belongs to the journal.

  


  

Block type: Descriptor block

  

Sequence Number: 21

  


1547 = 1027

  


通过上面可以看出“Journal Block Number 1”就是文件系统的block 1546


日志文件由“处理(Transactions)”充满,每一个处理都是一个递增的序列号,如果到达了日志文件的结尾部分,那么会回到日志文件的开始部分继续写,就这样循环写。然而,如果一个文件系统没有“干净”的卸载,那么下一次挂载后,总是会从开始出写入,因此,这个要注意,如果是做恢复,要么别挂载,要么就以只读的方法挂载。


讲了这么多理论,看的都让人烦,这些理论稍微懂点就可以了,反正已不是数据恢复,我们只是考虑恢复误删除的文件或者是在被恶意破坏后的系统中查找点残羹冷炙,然后再品尝一下,哈哈,还觉得不错,找到了!

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP