如何恢复 Linux 上删除的文件.docx
- 文档编号:5900702
- 上传时间:2023-05-09
- 格式:DOCX
- 页数:15
- 大小:71.60KB
如何恢复 Linux 上删除的文件.docx
《如何恢复 Linux 上删除的文件.docx》由会员分享,可在线阅读,更多相关《如何恢复 Linux 上删除的文件.docx(15页珍藏版)》请在冰点文库上搜索。
如何恢复Linux上删除的文件
如何恢复Linux上删除的文件,第1部分
原理及普通文件的恢复
要想恢复误删除的文件,必须清楚数据在磁盘上究竟是如何存储的,以及如何定位并恢复数据。
本文从数据恢复的角度,着重介绍了ext2文件系统中使用的一些基本概念和重要数据结构,并通过几个实例介绍了如何手工恢复已经删除的文件。
最后针对ext2现有实现存在的大文件无法正常恢复的问题,通过修改内核中的实现,给出了一种解决方案。
对于很多Linux的用户来说,可能有一个问题一直都非常头疼:
对于那些不小心删除的数据来说,怎样才能恢复出来呢?
大家知道,在Windows系统上,回收站中保存了最近使用资源管理器时删除的文件。
即便是对于那些在命令行中删除的文件来说,也有很多工具(例如recover4all,FinalDataRecovery)可以把这些已经删除的文件恢复出来。
在Linux下这一切是否可能呢?
实际上,为了方便用户的使用,现在Linux上流行的桌面管理工具(例如gnome和KDE)中都已经集成了回收站的功能。
其基本思想是在桌面管理工具中捕获对文件的删除操作,将要删除的文件移动到用户根目录下的.Trash文件夹中,但却并不真正删除该文件。
当然,像在Windows上一样,如果用户在删除文件的同时,按下了Shift键并确认删除该文件,那么这个文件就不会被移动到.Trash文件夹中,也就无从恢复了。
此时,习惯了使用Windows上各种恢复工具的人就会顿足捶胸,抱怨Linux上工具的缺乏了。
但是请稍等一下,难道按照这种方式删除的文件就真的无从恢复了么?
或者换一个角度来看,使用rm命令删除的文件是否还有办法能够恢复出来呢?
背景知识
在开始真正进行实践之前,让我们首先来了解一下在Linux系统中,文件是如何进行存储和定位的,这对于理解如何恢复文件来说非常重要。
我们知道,数据最终以数据块的形式保存在磁盘上,而操作系统是通过文件系统来管理这些数据的。
ext2/ext3是Linux上应用最为广泛的文件系统,本文将以ext2文件系统为例展开介绍。
我们知道,在操作系统中,文件系统是采用一种层次化的形式表示的,通常可以表示成一棵倒置的树。
所有的文件和子目录都是通过查找其父目录项来定位的,目录项中通过匹配文件名可以找到对应的索引节点号(inode),通过查找索引节点表(inodetable)就可以找到文件在磁盘上的位置,整个过程如图1所示。
图1.文件数据定位过程
对于ext2类型的文件系统来说,目录项是使用一个名为ext2_dir_entry_2的结构来表示的,该结构定义如下所示:
清单1.ext2_dir_entry_2结构定义
structext2_dir_entry_2{__le32inode;/*索引节点号*/__le16rec_len;/*目录项的长度*/__u8name_len;/*文件名长度*/__u8file_type;/*文件类型*/charname[EXT2_NAME_LEN];/*文件名*/};
在Unix/Linux系统中,目录只是一种特殊的文件。
目录和文件是通过file_type域来区分的,该值为1则表示是普通文件,该值为2则表示是目录。
对于每个ext2分区来说,其在物理磁盘上的布局如图2所示:
图2.ext2分区的布局
从图2中可以看到,对于ext2文件系统来说,磁盘被划分成一个个大小相同的数据块,每个块的大小可以是1024、2048或4096个字节。
其中,第一个块称为引导块,一般保留做引导扇区使用,因此ext2文件系统一般都是从第二个块开始的。
剩余的块被划分为一个个的块组,ext2文件系统会试图尽量将相同文件的数据块都保存在同一个块组中,并且尽量保证文件在磁盘上的连续性,从而提高文件读写时的性能。
至于一个分区中到底有多少个块组,这取决于两个因素:
1.分区大小。
2.块大小。
最终的计算公式如下:
分区中的块组数=分区大小/(块大小*8)
这是由于在每个块组中使用了一个数据块位图来标识数据块是否空闲,因此每个块组中最多可以有(块大小*8)个块;该值除上分区大小就是分区中总的块组数。
每个块组都包含以下内容:
1.超级块。
存放文件系统超级块的一个拷贝。
2.组描述符。
该块组的组描述符。
3.数据块位图。
标识相应的数据块是否空闲。
4.索引节点位图。
标识相应的索引节点是否空闲。
5.索引节点表。
存放所有索引节点的数据。
6.数据块。
该块组中用来保存实际数据的数据块。
在每个块组中都保存了超级块的一个拷贝,默认情况下,只有第一个块组中的超级块结构才会被系统内核使用;其他块组中的超级块可以在e2fsck之类的程序对磁盘上的文件系统进行一致性检查使用。
在ext2文件系统中,超级块的结构会通过一个名为ext2_super_block的结构进行引用。
该结构的一些重要域如下所示:
清单2.ext2_super_block结构定义
structext2_super_block{__le32s_inodes_count;/*索引节点总数*/__le32s_blocks_count;/*块数,即文件系统以块为单位的大小*/__le32s_r_blocks_count;/*系统预留的块数*/__le32s_free_blocks_count;/*空闲块数*/__le32s_free_inodes_count;/*空闲索引节点数*/__le32s_first_data_block;/*第一个可用数据块的块号*/__le32s_log_block_size;/*块大小*/__le32s_blocks_per_group;/*每个块组中的块数*/__le32s_inodes_per_group;/*每个块组中的索引节点个数*/...}
每个块组都有自己的组描述符,在ext2文件系统中是通过一个名为ext2_group_desc的结构进行引用的。
该结构的定义如下:
清单3.ext2_group_desc结构定义
/**Structureofablocksgroupdescriptor*/structext2_group_desc{__le32bg_block_bitmap;/*数据块位图的块号*/__le32bg_inode_bitmap;/*索引节点位图的块号*/__le32bg_inode_table;/*第一个索引节点表的块号*/__le16bg_free_blocks_count;/*该组中空闲块数*/__le16bg_free_inodes_count;/*该组中空闲索引节点数*/__le16bg_used_dirs_count;/*该组中的目录项*/__le16bg_pad;__le32bg_reserved[3];};
数据块位图和索引节点位图分别占用一个块的大小,其每一位描述了对应数据块或索引节点是否空闲,如果该位为0,则表示空闲;如果该位为1,则表示已经使用。
索引节点表存放在一系列连续的数据块中,每个数据块中可以包括若干个索引节点。
每个索引节点在ext2文件系统中都通过一个名为ext2_inode的结构进行引用,该结构大小固定为128个字节,其中一些重要的域如下所示:
清单4.ext2_inode结构定义
/**Structureofaninodeonthedisk*/structext2_inode{__le16i_mode;/*文件模式*/__le16i_uid;/*文件所有者的uid*/__le32i_size;/*以字节为单位的文件长度*/__le32i_atime;/*最后一次访问该文件的时间*/__le32i_ctime;/*索引节点最后改变的时间*/__le32i_mtime;/*文件内容最后改变的时间*/__le32i_dtime;/*文件删除的时间*/__le16i_gid;/*文件所有者的gid*/__le16i_links_count;/*硬链接数*/__le32i_blocks;/*文件的数据块数*/...__le32i_block[EXT2_N_BLOCKS];/*指向数据块的指针*/...};
第一个索引节点所在的块号保存在该块组描述符的bg_inode_table域中。
请注意i_block域,其中就包含了保存数据的数据块的位置。
有关如何对数据块进行寻址,请参看后文“数据块寻址方式”一节的内容。
需要知道的是,在普通的删除文件操作中,操作系统并不会逐一清空保存该文件的数据块的内容,而只会释放该文件所占用的索引节点和数据块,方法是将索引节点位图和数据块位图中的相应标识位设置为空闲状态。
因此,如果我们可以找到文件对应的索引节点,由此查到相应的数据块,就可能从磁盘上将已经删除的文件恢复出来。
幸运的是,这一切都是可能的!
本文将通过几个实验来了解一下如何从磁盘上恢复删除的文件。
数据块寻址方式
回想一下,ext2_inode结构的i_block域是一个大小为EXT2_N_BLOCKS的数组,其中保存的就是真正存放文件数据的数据块的位置。
通常来说,EXT2_N_BLOCKS大小为15。
在ext2文件系统,采用了直接寻址和间接寻址两种方式来对数据块进行寻址,原理如图3所示:
图3.数据块寻址方式
·对于i_block的前12个元素(i_block[0]到i_block[11])来说,其中存放的就是实际的数据块号,即对应于文件的0到11块。
这种方式称为直接寻址。
·对于第13个元素(i_block[12])来说,其中存放的是另外一个数据块的逻辑块号;这个块中并不存放真正的数据,而是存放真正保存数据的数据块的块号。
即i_block[12]指向一个二级数组,其每个元素都是对应数据块的逻辑块号。
由于每个块号需要使用4个字节表示,因此这种寻址方式可以访问的对应文件的块号范围为12到(块大小/4)+11。
这种寻址方式称为间接寻址。
·对于第14个元素(i_block[13])来说,其中存放也是另外一个数据块的逻辑块号。
与间接寻址方式不同的是,i_block[13]所指向的是一个数据块的逻辑块号的二级数组,而这个二级数组的每个元素又都指向一个三级数组,三级数组的每个元素都是对应数据块的逻辑块号。
这种寻址方式称为二次间接寻址,对应文件块号的寻址范围为(块大小/4)+12到(块大小/4)2+(块大小/4)+11。
·对于第15个元素(i_block[14])来说,则利用了三级间接索引,其第四级数组中存放的才是逻辑块号对应的文件块号,其寻址范围从(块大小/4)2+(块大小/4)+12到(块大小/4)3+(块大小/4)2+(块大小/4)+11。
ext2文件系统可以支持1024、2048和4096字节三种大小的块,对应的寻址能力如下表所示:
表1.各种数据块对应的文件寻址范围
块大小
直接寻址
间接寻址
二次间接寻址
三次间接寻址
1024
12KB
268KB
64.26MB
16.06GB
2048
24KB
1.02MB
513.02MB
265.5GB
4096
48KB
4.04MB
4GB
~4TB
掌握上面介绍的知识之后,我们就可以开始恢复文件的实验了。
准备文件系统
为了防止破坏已有系统,本文将采用一个新的分区进行恢复删除文件的实验。
首先让我们准备好一个新的分区,并在上面创建ext2格式的文件系统。
下面的命令可以帮助创建一个20GB的分区:
清单5.新建磁盘分区
#fdisk/dev/sdb< 在笔者的机器上,这个分区是/dev/sdb6。 然后创建文件系统: 清单6.在新分区上创建ext2文件系统 #mke2fs/dev/sdb6 并将其挂载到系统上来: 清单7.挂载创建的ext2文件系统 #mkdir/tmp/test#mount/dev/sdb6/tmp/test 在真正使用这个文件系统之前,让我们首先使用系统提供的一个命令dumpe2fs来熟悉一下这个文件系统的一些具体参数: 清单8.使用dumpe2fs熟悉这个文件系统的参数 #dumpe2fs/dev/sdb6dumpe2fs1.39(29-May-2006)Filesystemvolumename: d8b10aa9-c065-4aa5-ab6f-96a9bcda52ceFilesystemmagicnumber: 0xEF53Filesystemrevision#: 1(dynamic)Filesystemfeatures: ext_attrresize_inodedir_indexfiletypesparse_superlarge_fileDefaultmountoptions: (none)Filesystemstate: notcleanErrorsbehavior: ContinueFilesystemOStype: LinuxInodecount: 2443200Blockcount: 4885760Reservedblockcount: 244288Freeblocks: 4797829Freeinodes: 2443189Firstblock: 0Blocksize: 4096Fragmentsize: 4096ReservedGDTblocks: 1022Blockspergroup: 32768Fragmentspergroup: 32768Inodespergroup: 16288Inodeblockspergroup: 509Filesystemcreated: MonOct2920: 04: 162007Lastmounttime: MonOct2920: 06: 522007Lastwritetime: MonOct2920: 08: 312007Mountcount: 1Maximummountcount: 39Lastchecked: MonOct2920: 04: 162007Checkinterval: 15552000(6months)Nextcheckafter: SatApr2620: 04: 162008Reservedblocksuid: 0(userroot)Reservedblocksgid: 0(grouproot)Firstinode: 11Inodesize: 128Defaultdirectoryhash: teaDirectoryHashSeed: d1432419-2def-4762-954a-1a26fef9d5e8Group0: (Blocks0-32767)Primarysuperblockat0,Groupdescriptorsat1-2ReservedGDTblocksat3-1024Blockbitmapat1025(+1025),Inodebitmapat1026(+1026)Inodetableat1027-1535(+1027)31224freeblocks,16276freeinodes,2directoriesFreeblocks: 1543-22535,22537-32767Freeinodes: 12,14-16288...Group149: (Blocks4882432-4885759)Blockbitmapat4882432(+0),Inodebitmapat4882433(+1)Inodetableat4882434-4882942(+2)2817freeblocks,16288freeinodes,0directoriesFreeblocks: 4882943-4885759Freeinodes: 2426913-2443200 应用前面介绍的一些知识,我们可以看到,这个文件系统中,块大小(Blocksize)为4096字节,因此每个块组中的块数应该是4096*8=32768个(Blockspergroup),每个块组的大小是128MB,整个分区被划分成20GB/(4KB*32768)=160个。 但是为什么我们只看到150个块组(0到149)呢? 实际上,在fdisk中,我们虽然输入要创建的分区大小为20GB,但实际上,真正分配的空间并不是严格的20GB,而是只有大约20*109个字节,准确地说,应该是(4885760*4096)/(1024*1024*1024)=18.64GB。 这是由于不同程序的计数单位的不同造成的,在使用存储设备时经常遇到这种问题。 因此,这个分区被划分成150个块组,前149个块组分别包含32768个块(即128B),最后一个块组只包含3328个块。 另外,我们还可以看出,每个索引节点的大小是128字节,每个块组中包含16288个索引节点,在磁盘上使用509个块来存储(16288*128/4096),在第一个块组中,索引节点表保存在1027到1535块上。 数据块和索引节点是否空闲,是分别使用块位图和索引节点位图来标识的,在第一个块组中,块位图和索引节点位图分别保存在1025和1026块上。 dumpe2fs的输出结果中还包含了其他一些信息,我们暂时先不用详细关心这些信息。 准备测试文件 现在请将附件中的createfile.sh文件下载到本地,并将其保存到/tmp/test目录中,这个脚本可以帮助我们创建一个特殊的文件,其中每行包含1KB字符,最开始的14个字符表示行号。 之所以采用这种文件格式,是为了方便地确认所恢复出来的文件与原始文件之间的区别。 这个脚本的用法如下: 清单9.createfile.sh脚本的用法 #./createfile.sh[sizeinKB][filename] 第1个参数表示所生成的文件大小,单位是KB;第2个参数表示所生成文件的名字。 下面让我们创建几个测试文件: 清单10.准备测试文件 #cd/tmp/test#./createfile.sh35testfile.35K#./createfile.sh10240testfile.10M#cptestfile.35Ktestfile.35K.orig#cptestfile.10Mtestfile.10M.orig 上面的命令新创建了大小为35KB和9000KB的两个文件,并为它们各自保存了一个备份,备份文件的目的是为了方便使用diff之类的工具验证最终恢复出来的文件与原始文件完全一致。 ls命令的–i选项可以查看有关保存文件使用的索引节点的信息: 清单11.查看文件的索引节点号 #ls-li|sort11drwx------2rootroot16384Oct2920: 08lost+found12-rwxr-xr-x1rootroot1406Oct2920: 09createfile.sh13-rw-r--r--1rootroot35840Oct2920: 09testfile.35K14-rw-r--r--1rootroot10485760Oct2920: 10testfile.10M15-rw-r--r--1rootroot35840Oct2920: 10testfile.35K.orig16-rw-r--r--1rootroot10485760Oct2920: 11testfile.10M.orig 第一列中的数字就是索引节点号。 从上面的输出结果我们可以看出,索引节点号是按照我们创建文件的顺序而逐渐自增的,我们刚才创建的35K大小的文件的索引节点号为13,10M大小的文件的索引节点号为14。 debugfs中提供了很多工具,可以帮助我们了解进一步的信息。 现在执行下面的命令: 清单12.查看索引节点<13>的详细信息 #echo"stat<13>"|debugfs/dev/sdb6debugfs1.39(29-May-2006)Inode: 13Type: regularMode: 0644Flags: 0x0Generation: 2957086759User: 0Group: 0Size: 35840FileACL: 0DirectoryACL: 0Links: 1Blockcount: 72Fragment: Address: 0Number: 0Size: 0ctime: 0x47268467--MonOct2920: 09: 592007atime: 0x4726849d--MonOct2920: 10: 532007mtime: 0x47268467--MonOct2920: 09: 592007BLOCKS: (0-8): 4096-4104TOTAL: 9 输出结果显示的就是索引节点13的详细信息,从中我们可以看到诸如文件大小(35840=35K)、权限(0644)等信息,尤其需要注意的是最后3行的信息,即该文件被保存到磁盘上的4096到4104总共9个数据块中。 下面再看一下索引节点14(即testfile.10M文件)的详细信息: 清单13.查看索引节点<14>的详细信息 #echo"stat<14>"|debugfs/dev/sdb6debugfs1.39(29-May-2006)Inode: 14Type: regularMode: 0644Flags: 0x0Generation: 2957086760User: 0Group: 0Size: 10485760FileACL: 0DirectoryACL: 0Links: 1Blockcount: 20512Fragment: Address: 0Num
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 如何恢复 Linux 上删除的文件 如何 恢复 删除 文件
![提示](https://static.bingdoc.com/images/bang_tan.gif)