免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10188 | 回复: 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
2 [报告]
发表于 2011-01-20 09:49 |只看该作者

分析Superblock,其内容及个字节的作用如下:


  

字节位置

  
  

类 型

  
  




  
  

0-3

  
  

__le32

  
  

总的inode数

  
  

4-7

  
  

__le32

  
  

总的block数

  
  

8-11

  
  

__le32

  
  

文件系统保留的块数

  
  

12-15

  
  

__le32

  
  

空闲块数

  
  

16-19

  
  

__le32

  
  

空闲inode数

  
  

20-23

  
  

__le32

  
  

块组0的起始块号

  
  

24-27

  
  

__le32

  
  

块大小

  
  

28-31

  
  

__le32

  
  

片断(Fragment)大小

  
  

32-35

  
  

__le32

  
  

每个块组所包含的块数

  
  

36-39

  
  

__le32

  
  

每个块组所包含的片断数

  
  

40-43

  
  

__le32

  
  

每个块组所包含的inode数

  
  

44-47

  
  

__le32

  
  

最后挂载时间

  
  

48-51

  
  

__le32

  
  

最后写入时间

  
  

52-53

  
  

__le16

  
  

当被前挂载数

  
  

54-55

  
  

__le16

  
  

最大挂载数

  
  

56-57

  
  

__le16

  
  

魔术签名(Magic signature)

  
  

58-59

  
  

__le16

  
  

文件系统状态

  
  

60-61

  
  

__le16

  
  

检测到错误后的行为

  
  

62-63

  
  

__le16

  
  

子版本级别

  
  

64-67

  
  

__le32

  
  

最后检测的时间

  
  

68-71

  
  

__le32

  
  

两次检测间的最长间隔

  
  

72-75

  
  

__le32

  
  

操作系统类型

  
  

76-79

  
  

__le32

  
  

主版本级别

  
  

80-81

  
  

__le16

  
  

默认UID保留块

  
  

82-83

  
  

__le16

  
  

默认GID保留块

  
  

84-87

  
  

__le32

  
  

第一个非保留inode

  
  

88-89

  
  

__le16

  
  

节点结构的大小(字节数)

  
  

90-91

  
  

__le16

  
  

该超级块所在的块组(Block group)

  
  

92-95

  
  

__le32

  
  

兼容特征

  
  

96-99

  
  

__le32

  
  

非兼容特征

  
  

100-103

  
  

__le32

  
  

只读兼容特征

  
  

104-119

  
  

__u8[16]

  
  

128位的UUID表示文件系统ID

  
  

120-135

  
  

char[16]

  
  

卷名(Volume  name)

  
  

136-199

  
  

char[64]

  
  

最后一次挂载的目录

  
  

200-203

  
  

__le32

  
  

压缩方法

  
  

204

  
  

__u8

  
  

文件再分配块数

  
  

205

  
  

__u8

  
  

目录再分配块数

  
  

206-207

  
  

__le16

  
  

每组描述符在线增长数

  
  

208-223

  
  

__u8[16]

  
  

日志超级块的uuid

  
  

224-227

  
  

__le32

  
  

日志文件(journal file)inode

  
  

228-231

  
  

__le32

  
  

日志文件设备的inode

  
  

232-235

  
  

__le32

  
  

被删除节点的列表的开始处

  
  

236-251

  
  

__le32[4]

  
  

Hash种子树

  
  

252

  
  

__u8

  
  

默认使用的hash版本

  
  

253-255

  
  


  
  

保留

  
  

256-259

  
  

__le32

  
  

默认挂载选项

  
  

260-263

  
  

__le32

  
  

第一个元块块组

  
  

264-1023

  
  


  
  

保留

  


下面通过一个具体的实例来分析一下超级块,这是一款在使用中的80G硬盘,为了好理解,在WinHexOffset部分使用了两种进制的表示方法


十六表示:


  

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

  


十进制表示:


  

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

  


下面分析一下本例:


0-3:占用4个字节,表示总的节点数为0065F8=26104


4-7
:占用4个字节,表示总的块数000197C4=104388


8-11
:占用4个字节,表示保留的块数00001463=5219


12-15
:占用4个字节,表示空闲块数00009A68=39528


16-19
:占用4个字节,表示空闲inode数0065BD=26072


20-23
:占用4个字节,表示块组0的起始块号00000001=1


24-27
:占用4个字节,表示块大小00000000=0,按照它的算法表示1024


28-31
:占用4个字节,表示片断大小00000000=0按照算法表示1024


32-35
:占用4个字节,表示块组所包含的块数00002000=8192


36-39
:占用4个字节,表示块组所包含的片断数00002000=8192



40-43
:占用4个字节,表示每个块组所包含的inode数000007D8=2008


44-47
:占用4个字节,表示最后挂载时间4BEC98F3


48-51
:占用4个字节,表示最后写入时间4BEC98F3


52-53
:占用2个字节,表示当被前挂载数006A


54-55
:占用2个字节,表示最大挂载数FFFF


56-57
:占用2个字节,表示魔术签名“EF 53


58-59:占用2个字节,表示文件系统状态0001=1,表示系统正常


60-61
:占用2个字节,表示检测到错误后的行为0001=1,表示继续


62-63
:占用2个字节,表示子版本级别00000=0


64-67
:占用4个字节,表示最后检测的时间478B4310


68-71
:占用4个字节,表示两次检测间的最长间隔00000000=0,默认检查


72-75
:占用4个字节,表示操作系统类型00000000=0,表示Linux系统


76-79
:占用4个字节,表示主版本级别00000001=1,动态版本


80-81
:占用2个字节,默认UID保留块0000



82-83
:占用2个字节,默认GID保留块0000


84-87
:占用4个字节,表示第一个非保留inode,0000000B=11


88-89
:占用2个字节,表示节点结构的大小0080=128


90-91占用2个字节,表示该超级块所在的块组0000=0


92-95
:占用4个字节,表示兼容特征0000003C


96-99
:占用4个字节,表示非兼容特征00000006


100-103
:占用4个字节,表示只读兼容特征00000001


104-119
占用16个字节,128位文件系统ID8BAE9731909DB09C544614DCBF47233D


120-135
:占用16个字节,表示卷名0000000000000000000000746F6F622F


136-199
:占用64个字节,表示最后一次挂载的目录


0000000000000000 0000000000000000 0000000000000000


0000000000000000 0000000000000000 0000000000000000


0000000000000000 0000000000000000


200-203:占用4个字节,表示压缩方法00000000


204
:占用1个字节,表示文件再分配块数00


205
:占用1个字节,表示目录再分配块数00


206-207
:占用2个字节,表示每组描述符在线增长数0100


208-223
:占用16个字节,表示日志超级块的uuid

00000000000000000000000000000000


224-227
:占用4个字节,表示日志文件(journal file)inode:00000008=8


228-231
:占用4个字节,表示日志文件设备的inode:00000000


232-235
:占用4个字节,表示被删除节点的列表的开始处00000000


236-251
:占用16个字节,表示Hash种子树

77CF569C98C528BE614039B87F7756D3


252
:占用1个字节,表示默认使用的hash版本02


253-255
: 保留

256-259:占用4个字节,表示默认挂载选项0000000C

260-263:占用4个字节,表示第一个元块块组00000000=0


下面是通过dumpe2fs得到的信息:


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

下面是通过dumpe2fs得到的信息:


  

[root@nas ~]# dumpe2fs /dev/sdb1

  

dumpe2fs 1.39 (29-May-2006)

  

Filesystem volume name:
<none>

  

Last mounted on:
<not available>

  

Filesystem UUID:
c6e67db9-f86a-41e5-9fb0-c09bd41b577a

  

Filesystem magic number:
0xEF53

  

Filesystem revision #:
1 (dynamic)

  

Filesystem features:
has_journal resize_inode dir_index  filetype sparse_super large_file

  

Default mount options:
(none)

  

Filesystem state:
clean

  

Errors behavior:

Continue

  

Filesystem OS type:
Linux

  

Inode count:
9781248

  

Block count:
19531015

  

Reserved block count:
976550

  

Free blocks:
19178024

  

Free inodes:
9781237

  

First block:
0

  

Block size:

4096

  

Fragment size:
4096

  

Reserved GDT blocks:
1019

  

Blocks per group:
32768

  

Fragments per group:
32768

  

Inodes per group:
16384

  

Inode blocks per group:
512

  

Filesystem created:
Thu May 13 19:04:35 2010

  

Last mount time:
Thu May 13 19:06:10 2010

  

Last write time:
Thu May 13 19:06:21 2010

  

Mount count:
2

  

Maximum mount count:
36

  

Last checked:
Thu May 13 19:04:35 2010

  

Check interval:
15552000 (6 months)

  

Next check after:
Tue Nov
9 19:04:35 2010

  

Reserved blocks uid:
0 (user root)

  

Reserved blocks gid:
0 (group root)

  

First inode:
11

  

Inode size:
128

  

Journal inode:
8

  

Default directory hash:
tea

  

Directory Hash Seed:
9e0f6a8c-ae09-4473-b821-088e5b189b47

  

Journal backup:
inode blocks

  

Journal size:
128M

  


  


  

Group 0: (Blocks 0-32767)

  


Primary superblock at 0, Group descriptors at 1-5

  


Reserved GDT blocks at 6-1024

  


Block bitmap at 1025 (+1025), Inode bitmap at 1026 (+1026)

  


Inode table at 1027-1538 (+1027)

  


0 free blocks, 16373 free inodes, 2 directories

  


Free blocks:

  


Free inodes: 12-16384

  


……

  

Group 596: (Blocks 19529728-19531014)

  


Block bitmap at 19529728 (+0), Inode bitmap at 19529729 (+1)

  


Inode table at 19529730-19530241 (+2)

  


773 free blocks, 16384 free inodes, 0 directories

  


Free blocks: 19530242-19531014

  


Free inodes: 9764865-9781248

  


3、组(Groups)


每一个ext3文件系统都被分成很多组,每一组都包含一个固定数目的block,除了最后的一个组,最后的一个组包含了剩余的block。每一个group包含的block数已在superblock中给定,例如:


  

[root@nas ~]# ext3grep /dev/sda3
--superblock | grep 'Blocks per group'

  

Blocks per group:
32768

  


  


同样也可以通过上面dumpe2fs命令查看。由于组描述表紧挨超级块,所以可以使用上面的方法用DD命令来得到,然后在进行分析。


每一组使用一个block作为位图(bitmap),以此来保持该组内块的分配(被使用情况),因此可以计算一下,每个block的大小为4096字节,每字节8位,那么4096 * 8 = 32768就是一个组的block数量。文件和目录都是存储在块中的,而块的分配情况是记录在块位图中,ext3按照块组来管理块,因此就会在每个块组中设置块位图。


节点数据结构是128个字节(在理论上它们可以被扩展;但真实的大小在superblock中再次给定)存储在一个表中,在每一个组中(4096 / 128 = 32节点/block)。在位图中至多32768bit,即每个bit对应1个块,每个字节对应8个块。可以得出结论,每一组最多32768inode,于是32768 / 32 = 1024block,这就是在每一组节点表中的block数。节点表的真实大小由存储在superblock中的“Number ofinodes per group”给定。

例如:


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

例如:


  

[root@nas ~]# ext3grep /dev/sda3
--superblock | egrep 'Size of inode|inodes  per group'

  

Number of inodes per group:  32736

  

Size of inode structure: 128

  


看一下“/usr/include/linux/ext3_fs.h”,在这里节选了块组描述的结构,块位图号和节点表块号的开始处均在此定义:


  

[root@mail ~]# more  /usr/include/linux/ext3_fs.h

  


……

  

/*

  


* Structure of a blocks group descriptor

  


*/

  

struct ext3_group_desc

  

{

  


__le32
bg_block_bitmap;
/* Blocks bitmap block */

  


__le32
bg_inode_bitmap;
/* Inodes bitmap block */

  


__le32
bg_inode_table;
/* Inodes table block */

  


__le16
bg_free_blocks_count;
/* Free blocks count */

  


__le16
bg_free_inodes_count;
/* Free inodes count */

  


__le16
bg_used_dirs_count;
/* Directories count */

  


__u16
bg_pad;

  


__le32
bg_reserved[3];

  

};

  


分析组描述符,其内容及个字节的作用如下:


  

  
  

类型

  
  



  
  

0-3

  
  

__le32

  
  

块位图块号

  
  

4-7

  
  

__le32

  
  

Inode节点位图块号

  
  

8-11

  
  

__le32

  
  

Inode节点表块号

  
  

12-13

  
  

__le16

  
  

本块组中空闲的块数

  
  

14-15

  
  

__le16

  
  

本块组中空闲的节点数

  
  

16-17

  
  

__le16

  
  

本块组中的目录数

  
  

18-31

  
  


  
  

保留

  


由于结构的大小是2的幂,因此选择了32个字节,描述用了18个字节,其余的被保留。

注意一个4096字节block已经能够用于128个组描述符(128*32=4096)。每一个组描述表能够存储32768block,因此一个4096字节block可以管理(4096*32768*128=)17179869184字节。


所以只有大于(17179869184/(1024*1024*1024))=16GB的分区才会使用多于1block的组描述表。


可以通过ext3grep打印出组描述表的内容,例如:


  

[root@nas ~]# ext3grep /dev/sdb1

  

Running ext3grep version 0.10.2

  

No action specified; implying  --superblock.

  


……

  

Number of groups: 597

  


Group
0: block bitmap at 1025, inodes bitmap at 1026, inode table at 1027

  


0 free blocks, 16373 free inodes,  2 used directory

  



……

  


Group
294: block bitmap at 9633792, inodes bitmap at 9633793, inode table at  9633794

  


32254 free blocks, 16384 free  inodes, 0 used directory

  


……

  

Group
596: block bitmap at  19529728, inodes bitmap at 19529729, inode table at 19529730

  


773 free blocks, 16384 free  inodes, 0 used directory

  


4、节点(Inodes)


节点表存储节点,节点表存在于每一个组中,节点用于存放各种元数据,这些元数据的类型包括符号链接、目录、文件、FIFO或者是UNIX socket等等。就文件和目录而言,真实的数据存储在inode之外的文件系统blocks中。


12个块号用于存储节点,如果需要更多的块,那么节点会指向一个间接的block,随后节点会被存储在一个间接块中,或者是三次间接块中。


每一组的节点表中的节点包含元数据,该元数据存储着每种文件系统的数据类型,这种类型可能是一个符号链接,也可能是一个目录,文件,FIFOUNIX socket,等等。对于文件和目录,真是的数据被存储在文件系统块以外的inodeinode结构是用C语言实现的,ext3_inode结构在头文件/usr/include/linux/ext3_fs.h中给出,在下面给出了头文件中的结构和并用表格说明其用法。


节点结构由C语言所写,ext3_inode的结构在头文件/usr/include/linux/ext3_fs.h中,如下


  

[root@mail ~]# more /usr/include/linux/ext3_fs.h

  


……

  

/*

  


* Structure of an inode on the disk

  


*/

  

struct ext3_inode {

  


__le16
i_mode;
/* File mode */

  


__le16
i_uid;
/* Low 16 bits of Owner Uid */

  


__le32
i_size;
/* Size in bytes */

  


__le32
i_atime;
/* Access time */

  


__le32
i_ctime;
/* Creation time */

  


__le32
i_mtime;
/* Modification time */

  


__le32
i_dtime;
/* Deletion Time */

  


__le16
i_gid;
/* Low 16 bits of Group Id */

  


__le16
i_links_count;
/* Links count */

  


__le32
i_blocks;
/* Blocks count */

  


__le32
i_flags;
/* File flags */

  


union {

  


struct {

  


__u32
l_i_reserved1;

  



} linux1;

  


struct {

  


__u32
h_i_translator;

  


} hurd1;

  


struct {

  


__u32
m_i_reserved1;

  


} masix1;

  


} osd1;
/* OS dependent 1 */

  


__le32
i_block[EXT3_N_BLOCKS];/* Pointers to blocks */

  


__le32
i_generation;
/* File version (for NFS) */

  


__le32
i_file_acl;
/* File ACL */

  


__le32
i_dir_acl;
/* Directory ACL */

  


__le32
i_faddr;
/* Fragment address */

  


union {

  


struct {

  


__u8
l_i_frag;
/* Fragment number */

  


__u8
l_i_fsize;
/* Fragment size */

  


__u16
i_pad1;

  



__le16
l_i_uid_high;
/* these 2 fields
*/

  


__le16
l_i_gid_high;
/* were reserved2[0] */

  


__u32
l_i_reserved2;

  


} linux2;

  


struct {

  



__u8
h_i_frag;
/* Fragment number */

  


__u8
h_i_fsize;
/* Fragment size */

  


__u16
h_i_mode_high;

  


__u16
h_i_uid_high;

  


__u16
h_i_gid_high;

  


__u32
h_i_author;

  


} hurd2;

  


struct {

  


__u8
m_i_frag;
/* Fragment number */

  


__u8
m_i_fsize;
/* Fragment size */

  



__u16
m_pad1;

  


__u32
m_i_reserved2[2];

  


} masix2;

  


} osd2;
/* OS dependent 2 */

  


__le16
i_extra_isize;

  


__le16
i_pad1;

  

};

  


节点的用法:


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

节点的用法:



下面是一个inode的结构表。


  

  

  
  

  

  
  


  
  

0-1

  
  

__le16

  
  

文件模式

  
  

2-3

  
  

__le16

  
  

uid的低16

  
  

4-7

  
  

__le32

  
  

字节大小

  
  

8-11

  
  

__le32

  
  

访问时间

  
  

12-15

  
  

__le32

  
  

建立时间

  
  

16-19

  
  

__le32

  
  

修改时间

  
  

20-23

  
  

__le32

  
  

删除时间

  
  

24-25

  
  

__le16

  
  

gid的低16

  
  

26-27

  
  

__le16

  
  

链接数

  
  

28-31

  
  

__le32

  
  

扇区数

  
  

32-35

  
  

__le32

  
  

文件标志

  
  

36-39

  
  

linux1

  
  

操作系统依赖1

  
  

40-99

  
  

__le32[15]

  
  

指向块的指针

  
  

100-103

  
  

__le32

  
  

文件版本(用于NFS)

  
  

104-107

  
  

__le32

  
  

文件ACL

  
  

108-111

  
  

__le32

  
  

目录ACL

  
  

112-115

  
  

__le32

  
  

片断地址

  
  

116-127

  
  

linux2

  
  

操作系统依赖2

  



结合上面的节点表和下面superblock来看:


  

[root@nas bin]# ./ext3grep  /dev/sdb1
--superblock

  

Running ext3grep version 0.10.2

  

Inodes count:  9781248

  

Blocks count: 19531015

  

Reserved blocks count: 976550

  

Free blocks count: 19178024

  

Free inodes count: 9781237

  

First Data Block: 0

  

Block size: 4096

  

Fragment size: 4096

  

Number of blocks per group: 32768

  

Number of fragments per group: 32768

  

Number of  inodes per group: 16384

  

Mount time: Thu Jan
1 08:00:00 1970

  

Write time: Mon Jan 10 08:25:19 2011

  

Mount count: 0

  

Maximal mount count: 33

  

Magic signature: 0xef53

  

File system state: 'Unmounted cleanly'

  

Size of inode structure: 128

  

Block group # of this superblock: 0

  

compatible feature set: HAS_JOURNAL  RESIZE_INODE DIR_INDEX

  

incompatible feature set: FILETYPE

  

readonly-compatible feature set:  SPARSE_SUPER LARGE_FILE

  

Per group desc for online growth: 1019

  

UUID of journal superblock: 0x00 0x00  0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

  

Inode number of journal file: 8

  

Device number of journal file: 0

  

Start of list of inodes to delete: 0

  

First metablock block group: 0

  


  

Number of groups: 597

  


Group
0: block bitmap at 1025, inodes bitmap at 1026, inode table at 1027

  


0 free blocks, 16373 free inodes,  2 used directory

  


Group
1: block bitmap at 33793, inodes bitmap at 33794, inode table at 33795

  


29650 free blocks, 16384 free  inodes, 0 used directory

  


Group
2: block bitmap at 65536, inodes bitmap at 65537, inode table at 65538

  


32254 free blocks, 16384 free  inodes, 0 used directory

  


  

……
//
省略部分

  

Group
595: block bitmap at 19496960, inodes bitmap at 19496961, inode table  at 19496962

  


32254 free blocks, 16384 free  inodes, 0 used directory

  

Group
596: block bitmap at 19529728, inodes bitmap at 19529729, inode table  at 19529730

  



773 free blocks, 16384 free  inodes, 0 used directory

  

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 0 = Thu Jan
1 08:00:00 1970

  

Number of descriptors in journal: 0;  min / max sequence numbers: 4294967295 / 0

  


  

……
//
省略部分

  



超级块(superblock)显示了总共有多少inode(例如: Inodes count: 9781248),每一个group有多少inode(例如: Number of inodes pergroup: 16384),通过这个就可以计算出group的总数。因为inode被存储在每组各自的inode表中,因此首先要确定一个inode属于哪个group,因为inode是从1开始统计的,转化从inode到group的公式(确定一个inode属于哪一个group):


group = (inode_number- 1) / inodes_per_group


这将给出了正确的inode表。


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

计算inode的索引(index)


index = inode_number - (group *inodes_per_group + 1)


因此,group能够被确定:每一inode能够被一个数字标识一个连续的地址[1,number_of_inodes],这里的inode可以被给定:


  

[root@nas  ~]# ext3grep
/dev/sdb1 --superblock |  grep 'Inodes count'

  

Inodes  count: 9781248

  


在某些情况下,也许想知道哪些块在文件系统属于inode表存储一个特定的inode,这个可以通过--inode-to-block来做到,例如:


  

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

  


……

  

Inode 2  resides in block 1027 at offset 0x80.

  


节点2(ext3_fs.h文件中有宏定义EXT3_ROOT_INO),总是被用于分区的根:类型为目录。其它所有的特殊节点只使用了EXT3_JOURNAL_INO(number ,例如:


  

[root@share
linux-2.6.32]#  more
include/linux/
ext3_fs.h

  


……

  

/*

  


* Special inodes numbers

  


*/

  

#define EXT3_BAD_INO
1
/* Bad blocks inode */

  

#define EXT3_ROOT_INO

2
/* Root inode */

  

#define EXT3_BOOT_LOADER_INO
5
/* Boot loader inode */

  

#define EXT3_UNDEL_DIR_INO
6
/* Undelete directory inode */

  

#define EXT3_RESIZE_INO

7
/*  Reserved group descriptors inode */

  

#define EXT3_JOURNAL_INO
8
/* Journal inode */

  


……

  


  


通过ext3grep命令,查看一下该节点的内容:


  

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

  

Running ext3grep version 0.10.2

  

Number of groups: 597

  


……

  


  

Hex dump of inode 2:

  

0000 | ed 41 00 00 00 10 00 00 d9 dc  eb 4b d9 dc eb 4b | .A.........K...K

  

0010 | d9 dc eb 4b 00 00 00 00 00 00  03 00 08 00 00 00 | ...K............

  

0020 | 00 00 00 00 00 00 00 00 03 06  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 00 00 00 00 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: 0

  

uid / gid: 0 / 0

  

mode: drwxr-xr-x

  

size: 4096

  

num of links: 3

  

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

  


  

Inode Times:

  

Accessed:
1273748697 = Thu May 13 19:04:57 2010

  

File Modified:
1273748697 = Thu May 13 19:04:57 2010

  

Inode Modified: 1273748697 = Thu May  13 19:04:57 2010

  

Deletion time:
0

  


  

Direct Blocks: 1539

  

The first block of the directory is  1539.

  


……

  

Inode 2 is directory "".

  

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 d
11

drwx------
lost+found

  


分析一下上面的输出:ext3grep导出节点表的十六进制目录,然后又解释了节点表。


规则文件(Regular Files)


如果节点表示一个规则文件,那么块中只是简单的包括了该文件的数据。如果一个文件的大小不是块大小的整倍数时,多余的字节会在最后的一个块中,最后的块中剩余的字节将会以0填满(至少在Linux是这样)


符号链接(Symbolic links)


符号链接的值是一个字符串:一个指向目标的路径名。字符串的长度由i_size给定,如果i_blocks0,那么i_block不包含block编号,但是被直接用于存储字符串。然而,如果目标的名字的长度高于i_block指定的值,那么i_blocks将会是一个非零值,并且i_block[0]将会指向一个包含目标名的block


目录(Directories)


如果节点表示是一个目录,那么它的链表数据结构是ext3_dir_entry_2,每一个块是独立的:块的外部没有文件显示列表入口点。第一个block总是以"."".."目录开始。

结构代码如下,着重看struct ext3_dir_entry_2部分


  

[root@mail ~]# more  /usr/include/linux/ext3_fs.h

  

……

  

*

  


* Structure of a directory entry

  


*/

  

#define EXT3_NAME_LEN 255

  


  

struct ext3_dir_entry {

  


__le32
inode;
/* Inode number */

  


__le16
rec_len;
/* Directory entry length */

  



__le16
name_len;
/* Name length */

  


char
name[EXT3_NAME_LEN];
/* File  name */

  

};

  

/*

  


* The new version of the directory  entry.
Since EXT3 structures are

  


* stored in intel byte order, and the  name_len field could never be

  


* bigger than 255 chars, it's safe to  reclaim the extra byte for the

  


* file_type field.

  


*/

  

struct ext3_dir_entry_2 {

  


__le32
inode;
/* Inode number */

  


__le16
rec_len;
/* Directory entry length */

  


__u8
name_len;
/* Name length */

  


__u8
file_type;

  


char
name[EXT3_NAME_LEN];
/* File  name */

  

};

  


分析struct ext3_dir_entry_2结构:


  

字节

  
  

类型

  
  


  
  

0-3

  
  

__le32

  
  

节点号

  
  

4-5

  
  

__le16

  
  

目录项长度

  
  

6

  
  

__le8

  
  

名字长度

  
  

7

  
  

__le8

  
  

文件类型

  
  

8

  
  

char[]

  
  

文件、符号链接、目录名

  

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

使用ext3grep命令的--ls--inode选项列出每一个节点N的目录块所包含的内容。例如列出分区的根目录:


  

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

  

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 1266736861 = Sun Feb 21 15:21:01 2010

  

Number of descriptors in journal:  1865; min / max sequence numbers: 97 / 308

  

Inode is Allocated

  

The first block of the directory is  1539.

  

Inode 2 is directory "".

  

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
end d


2
drwxr-xr-x
..

  


2
3 d

11
D 1273641978 Wed May 12 13:26:18 2010
drwx------
lost+found

  


3
4 r

49153
D 1273641978 Wed May 12 13:26:18 2010
rrw-r--r--
perl.rpm

  


4
7 d

32769
D 1273641978 Wed May 12 13:26:18 2010
drwxr-xr-x
side

  


5
6 d
4472833
D 1273641976 Wed May 12 13:26:16 2010
drwxr-xr-x
aide

  


6
7 r

49157
D 1273641976 Wed May 12 13:26:16 2010
rrw-r--r--
ft

  


7
9 d
6488065
D 1273641978 Wed May 12 13:26:18 2010
drwxr-xr-x
side2

  


8
9 r

49154
D 1273641976 Wed May 12 13:26:16 2010
rrw-r--r--
f

  


9
end d
5373953
D 1273641978 Wed May 12 13:26:18 2010
drwxr-xr-x
side3

  


10
11 r

49156
D 1273641976 Wed May 12 13:26:16 2010
rrwxr-xr-x
bash

  


11
12 d
7503873
D 1273641976 Wed May 12 13:26:16 2010
drwxr-xr-x
sbin

  


12
end d
3522561
D 1273641978 Wed May 12 13:26:18 2010
drwxr-xr-x
lib

  


13
14 d
1048577
D 1273641976 Wed May 12 13:26:16 2010
drwxr-xr-x
bd

  


14
end d

507905
D 1273641976 Wed May 12 13:26:16 2010
drwxrwxrwx
clamav

  


15
end r

49158
D 1266733035 Sun Feb 21 14:17:15 2010
rrw-r--r--
ft~

  


然后就可以通过使用“ext3grep --ls --inode 节点号” 列出任何节点中包含的内容。例如:


  

[root@nas /]# ext3grep /dev/sda3
--ls --inode
7503873

  


  


……

  


  


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

  


1
end d
2
drwxr-xr-x
..

  


78
79 r 2618953
D 1262030806  Tue Dec 29 04:06:46 2009
rrwxr-xr-x
mkfs.ext2

  


79
80 r 2618953
D 1262030806  Tue Dec 29 04:06:46 2009
rrwxr-xr-x
mkfs.ext3

  


81
82 r 2618953
D 1262030806  Tue Dec 29 04:06:46 2009
rrwxr-xr-x
mke2fs

  


157
158 r 2619027
D 1249454811 Wed Aug
5 14:46:51 2009
rrwxr-xr-x
init

  


注意:使用“ext3grep --ls --inode 节点号”能够显示所有目录条目,但是被删除的不会显示。


看上面的黑体字部分:



Deletiontime
表示删除时间,在下面的每一个条目中,如果删除时间(Deletion Time)部分为非零,那么表示该文件被删除。


日志Journal


ext3的日志模式有三种,其中journal日志模式是这三种模式中最慢的一种,也是最安全的一种日志模式。对于数据的每个变化它都需要向日志中写入一次,磁盘中写入两次,而顺序是首先向日志中写入数据,然后才会向文件写入,在此期间发生意外,那么有日志来保证完成数据的一致性。


日志是一个存在于固定数目的文件中,它是一个特殊的节点,在内核中定义为EXT3_JOURNAL_INO,通常是8, 如下:


  

[root@mail ~]# more /usr/include/linux/ext3_fs.h

  

……

  

/*

  


* Special inodes numbers

  


*/

  

#define EXT3_BAD_INO
1
/* Bad blocks inode */

  

#define EXT3_ROOT_INO
2
/* Root inode */

  

#define  EXT3_BOOT_LOADER_INO
5
/* Boot loader inode */

  

#define EXT3_UNDEL_DIR_INO
6
/* Undelete directory inode */

  

#define EXT3_RESIZE_INO
7


/*  Reserved group descriptors inode */

  

#define  EXT3_JOURNAL_INO

8
/* Journal inode */

  

……

  


实际的节点也可以在superblock中找到:


  

[root@nas ~]# ext3grep /dev/sdb1  --superblock | grep 'Inode number of journal file'

  

Inode number of journal file: 8

  


它的大小可以在节点8找到:


  

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

  

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: 115;  min / max sequence numbers: 5 / 28

  


  

Hex dump of inode 8:

  

0000 | 80 81 00 00 00 00 00 08 00 00  00 00 dc dc eb 4b | ...............K

  

0010 | dc dc eb 4b 00 00 00 00 00 00  01 00 10 01 04 00 | ...K............

  

0020 | 00 00 00 00 00 00 00 00 09 06  00 00 0a 06 00 00  | ................

  

0030 | 0b 06 00 00 0c 06 00 00 0d 06 00 00 0e 06 00 00 |  ................

  

0040 | 0f 06 00 00 10 06 00 00 11 06 00 00 12 06 00 00 |  ................

  

0050 | 13 06 00 00 14 06 00 00 15 06  00 00 16 0a 00 00 |  ................

  

0060 | 00 00 00 00 00 00 00 00 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: 0

  

uid / gid: 0 / 0

  

mode: rrw-------

  

size: 134217728

  

num of links: 1

  

sectors: 262416 (--> 34 indirect blocks).

  


  

Inode Times:

  

Accessed:
0

  

File Modified:
1273748700 = Thu May 13 19:05:00 2010

  

Inode Modified: 1273748700 = Thu May  13 19:05:00 2010

  

Deletion time:
0

  


  

Direct Blocks: 1545 1546 1547 1548 1549  1550 1551 1552 1553 1554 1555 1556

  

Indirect Block: 1557

  

Double Indirect Block: 2582

  


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


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

论坛徽章:
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
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

  


  


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP