`
zhangziyangup
  • 浏览: 1077046 次
文章分类
社区版块
存档分类
最新评论

如何恢复 Linux 上删除的文件,特自动恢复工具 e2undel 和特殊情况的恢复殊文件的恢复

 
阅读更多

在本系列文章的前两部分中,我们介绍了 ext2 文件系统中各种文件在磁盘上的存储结构,以及如何利用 debugfs 工具的辅助,手工恢复这些文件的详细过程。

通过这两部分的学习,我们可以看出恢复系统中删除的文件是一个非常繁琐的过程,需要非常仔细地考虑各种情况,并且要保持足够的细心,才可能把数据准确无误地恢复出来。稍有差错,就会造成数据丢失的情况。聪明的读者肯定会想,如果有一些好工具来自动或辅助完成数据的恢复过程,那简直就太好了。

幸运的是,已经有人开发了这样一些工具,来简化用户的数据恢复工作,e2undel 就是其中功能最为强大的一个。

自动恢复工具 e2undel

回想一下,在 ext2 文件系统中删除一个文件时,该文件本身的数据并没有被真正删除,实际执行的操作如下:

  1. 在块位图中将该文件所占用的数据块标识为可用状态。
  2. 在索引节点位图中将该文件所占用的索引节点标识为可用状态。
  3. 将该文件索引节点中的硬链接数目设置为 0。
  4. 将该文件索引节点中的删除时间设置为当前时间。
  5. 将父目录项中该文件对应项中的索引节点号设置为 0,并扩展前一项,使其包含该项所占用的空间。

而索引节点中的一些关键信息(或称为元数据,包括文件属主、访问权限、文件大小、该文件所占用的数据块等)都并没有发生任何变化。因此只要知道了索引节点号,就完全可以用本系列文章介绍的技术将文件完整地从磁盘上恢复出来了,这正是 e2undel 之类的工具赖以生存的基础。

然而,由于所删除的文件在目录项中对应的项中的索引节点号被清空了,因此我们就无法从索引节点中获得文件名的信息了。不过,由于文件大小、属主和删除时间信息依然能反映文件的原始信息,因此我们可以通过这些信息来帮助判断所删除的文件是哪个。

e2undel 是由Oliver Diedrich 开发的一个用来恢复 ext2 文件系统中已删除文件的工具,它会遍历所检测的文件系统的索引节点表,从中找出所有被标记为删除的索引节点,并按照属主和删除时间列出这些文件。另外, e2undel 还提供了文件大小信息,并试图按照 file 命令的方式来确定文件类型。如果您使用 rm –rf * 之类的命令一次删除了很多文件,这种信息就可以用来非常方便地帮助确定希望恢复的是哪些文件。在选择要恢复的文件之后,e2undel 会从磁盘上读取该文件占用的数据块(这些数据块的信息全部保存在索引节点中),并将其写入到一个新文件中。下面我们来看一下 e2undel 这个工具的详细用法。

首先请从 e2undel 的主页(http://e2undel.sourceforge.net/)上下载最新的源码包(截止到撰写本文为止,最新的版本是 0.82),并将其保存到本地文件系统中。不过这个源码包在最新的 Fedora Core 8 上编译时可能会有些问题,这是由于 ext2 文件系统内部实现中一些数据结构的变化引起来的,读者可以下载本文“下载”部分给出的补丁来修正这个问题(请下载这个补丁文件 e2undel-0.82.patch,并将其保存到与源码包相同的目录中)。要想编译 e2undel,系统中还必须安装 e2fsprogs 和 e2fsprogs-devel 这两个包,其中有编译 e2undel 所需要的一些头文件。Fedora Core 8 中自带的这两个包的版本号是 1.39-7:


清单1. 确认系统中已经安装了 e2fsprogs 和 e2fsprogs-devel

#rpm-qa|grepe2fsprogs
e2fsprogs-libs-
1.39-7
e2fsprogs-
1.39-7
e2fsprogs-devel-
1.39-7

现在就可以开始编译 e2undel 了:


清单2. 编译 e2undel

#tar-zxfe2undel-0.82.tgz

#patch-p0<e2undel-0.82.patch
patchingfilee2undel-
0.82/Makefile
patchingfilee2undel-
0.82/e2undel.h
patchingfilee2undel-
0.82.orig/libundel.c

#cde2undel-0.82
#makeall

编译之后会生成一个名为 e2undel 的可执行文件,其用法如下:

清单3. e2undel 的用法

#./e2undel
./e2undel0.82
usage:
./e2undel-ddevice-spath[-a][-t]
usage:
./e2undel-l
'-d':filesystemwheretolook
fordeletedfiles
'-s':directorywheretosaveundeleted
files
'-a':work
onallfiles,notonlyonthoselistedinundellogfile
'-t':trytodetermine
typeofdeletedfilesw/onames,worksonlywith'-a'
'-l':justgivealistofvalid
filesinundellogfile

e2undel 实际上并没有像前面介绍的使用 e2fsck 那样的方法一样真正将已经删除的文件恢复到原来的文件系统中,因为它并不会修改磁盘上 ext2 使用的内部数据结构(例如索引节点、块位图和索引节点位图)。相反,它仅仅是将所删除文件的数据恢复出来并将这些数据保存到一个新文件中。因此,-s 参数指定是保存恢复出来的文件的目录,最好是在另外一个文件系统上,否则可能会覆盖磁盘上的原有数据。如果指定了 -t 参数,e2undel 会试图读取文件的前 1KB 数据,并试图从中确定该文件的类型,其原理与系统中的 file 命令非常类似,这些信息可以帮助判断正在恢复的是什么文件。

下面让我们来看一个使用 e2undel 恢复文件系统的实例。


清单4. 使用 e2undel 恢复文件的实例

#./e2undel-a-t-d/dev/sda2-s/tmp/recover/
./e2undel0.82
Tryingto
recoverfileson/dev/sda2,savingthemon/tmp/recover/
/dev/sda2openedforread-onlyaccess
/dev/sda2wasnotcleanlyunmounted.
Doyouwantwocontinue(y/n)?y
489600inodes(489583free)
977956blocksof4096bytes(941677free)
lastmounted
onFriDec2816:21:502007

readinglogfile:openinglogfile:Nosuchfileordirectory
noentries
for/dev/sda2inlogfile
searching
fordeletedinodeson/dev/sda2:
|
==================================================|
489600inodesscanned,26deletedfilesfound

inodesizedeletedatname
-----------------------------------------------------------
1335840Dec1917:432007*ASCIItext
1410485760Dec1917:432007*ASCIItext
Selectaninodelistedaboveorpressentertogoback:13
35840byteswrittento/tmp/recover//inode-13-ASCII_text
Selectaninodelistedaboveorpressentertogoback:

username|1<12h|2<48h|3<7d|4<30d|5<1y|6older
-------------
+---------+---------+---------+---------+---------+--------
root|
0|0|0|2|0|0
phost|
24|0|0|0|0|0
Selectusernamefromtableorpressentertoexit:
#

e2undel 是一个交互式的命令,命令执行过程中需要输入的内容已经使用黑体表示出来了。从输出结果中可以看出,e2undel 一共在这个文件系统中找到了 26 个文件,其中 root 用户删除的有两个。这些文件按照删除时间的先后顺序被划分到几类中。索引节点号 13 对应的是一个 ASCII 正文的文本文件,最终被恢复到 /tmp/recover//inode-13-ASCII_text 文件中。查看一下这个文件就会发现,正是我们在本系列前两部分中删除的那个 35KB 的测试文件。

利用 libundel 库完美恢复文件

尽管 e2undel 可以非常方便地简化恢复文件的过程,但是美中不足的是,其恢复出来的文件的文件名却丢失了,其原因是文件名是保存在父目录的目录项中的,而不是保存在索引节点中的。本系列文章第 2 部分中给出了一种通过遍历父目录的目录项来查找已删除文件的文件名的方法,但是由于索引节点会被重用,因此通过这种方式恢复出来的文件名也许并不总是正确的。另外,如果目录结构的非常复杂,就很难确定某个文件的父目录究竟是哪个,因此查找正确文件名的难度就会变得很大。如果能在删除文件时记录下索引节点号和文件名之间的对应关系,这个问题就能完美地解决了。

这个问题在 e2undel 中得到了完美的解决。实际上,所有删除命令,例如 rm、unlink 都是通过一些底层的系统调用(例如 unlink(2)、rmdir(2))来实现的。基于这一点,e2undel 又利用了Linux 系统中动态链接库加载时提供的一种便利:如果设置了环境变量 LD_PRELOAD,那么在加载动态链接库时,会优先从 $LD_PRELOAD 指向的动态链接库中查找符号表,然后才会在系统使用 ldconfig 配置的动态链接库中继续查找符号表。因此,我们可以在自己编写的库函数中实现一部分系统调用,并将这个库优先于系统库加载,这样就能欺骗系统使用我们自己定义的系统调用来执行原有的操作。具体到 e2undel 上来说,就是要在调用这些系统调用删除文件时,记录下文件名和索引节点号之间的对应关系。

在编译 e2undel 源代码之后,还会生成一个库文件 libundel.so.1.0,其中包含了删除文件时所使用的一些系统调用的钩子函数。e2undel官方主页上下载的源码包中仅仅包括了对 unlink(2) 和 remove(3) 这两个系统调用的钩子函数,但是从 2.6.16 版本的内核开始,引入了一系列新的系统调用,包括 faccessat(2), fchmodat(2), fchownat(2), fstatat(2), futimesat(2), linkat(2), mkdirat(2), mknodat(2), openat(2), readlinkat(2), renameat(2), symlinkat(2), unlinkat(2), mkfifoat(3) 等,尽管这些系统调用目前还没有成为POSIX标准的一部分,但是相信这个过程不会很久了。目前诸如 Fecora Core 8 之类的系统中自带的 rm 命令(属于 coreutils)包已经使用这些新的系统调用进行了改写,另外本文下载部分中的补丁文件中已经提供了对 rmdir 和 unlinkat 的钩子函数。部分源代码如下所示:


清单5. libundel.c 代码片断

void_init()
{
f
=fopen("/var/e2undel/e2undel","a");
if(!f)
fprintf
(stderr,"libundel:can'topenlogfile,undeletiondisabled ");
}

......

int
rmdir(constchar*pathname)
{
interr
;
structstatbuf
;
charpwd[PATH_MAX]
;
int
(*rmdirp)(char*)=dlsym(RTLD_NEXT,"rmdir");
if(NULL!=pathname)
{
if(__lxstat(3,pathname,&buf))buf.st_ino=0;
if(!realpath(pathname,pwd))pwd[0]='0';
}
err
=(*rmdirp)((char*)pathname);
if(err)returnerr;/*remove()didnotsucceed*/
if(f)
{
if(!S_ISLNK(buf.st_mode))/*!!!shouldwecheckforotherfiletypes?*/
{
/*don'tlogdeletedsymlinks*/
fprintf
(f,"%ld,%ld::%ld::%s ",
(long)(buf.st_dev&0xff00)/256,
(long)buf.st_dev&0xff,
(long)buf.st_ino,pwd[0]?pwd:pathname);
fflush
(f);
}
}
/*if(f)*/
returnerr;
}
/*rmdir()*/

......

void_fini
()
{
if(f)fclose(f);
}

_init 和 _fini 这两个函数分别在打开和关闭动态链接库时执行,分别用来打开和关闭日志文件。如果某个命令(例如 rm)执行了 rmdir 系统调用,就会被这个库接管。rmdir 的处理比较简单,它先搜索到真正的 rmdir 系统调用的符号表,然后使用同样的参数来执行这个系统调用,如果成功,就将有关索引节点和文件名之类的信息记录到日志中(默认是 /var/e2undel/ e2undel)。

这个库的使用非常简单,请执行下面的命令:


清单6. libundel 的设置

#cplibundel.so.1.0/usr/local/lib
#cd/usr/local/lib
#ln-slibundel.so.1.0libundel.so.1
#ln–slibundel.so.1.0libundel.so

#ldconfig
#mkdir/var/e2undel
#chmod711/var/e2undel
#touch/var/e2undel/e2undel
#chmod622/var/e2undel/e2undel

上面的设置仅仅允许 root 用户可以恢复文件,如果希望让普通用户也能恢复文件,就需要修改对应文件的权限设置。

现在尝试以另外一个用户的身份来删除些文件:


清单7. 设置libundel之后删除文件

$exportLD_PRELOAD=/usr/local/lib/libundel.so
$rm-rfe2undel-0.82

要想记录所有用户的删除文件的操作,可以将 export LD_PRELOAD=/usr/local/lib/libundel.so 这行内容加入到 /etc/profile 文件中。

现在使用 e2undel 来恢复已删除的文件就变得简单多了,因为已经可以通过文件名来恢复文件了:


清单8. e2undel 利用 libundel 日志恢复删除文件

#./e2undel-a-t-d/dev/sda2-s/tmp/recover/
./e2undel0.82
Tryingto
recoverfileson/dev/sda2,savingthemon/tmp/recover/

/dev/sda2openedforread-onlyaccess
/dev/sda2wasnotcleanlyunmounted.
Doyouwantwocontinue(y/n)?y
489600inodes(489531free)
977956blocksof4096bytes(941559free)
lastmounted
onFriDec2820:45:052007

readinglogfile:
found
24entriesfor/dev/sda2inlogfile
searching
fordeletedinodeson/dev/sda2:
|
==================================================|
489600inodesscanned,26deletedfilesfound
checkingnamesfromlogfile
fordeletedfiles:24deletedfileswithnames

username|
1<12h|2<48h|3<7d|4<30d|5<1y|6older
-------------
+---------+---------+---------+---------+---------+--------
root|
0|0|0|2|0|0
phost|
24|0|0|0|0|0
Selectusernamefromtableorpressentertoexit:phost
Selecttimeinterval(1to6)orpressentertoexit:1

inodesizedeletedatname
-----------------------------------------------------------
3100830Dec2917:232007/tmp/test/undel/e2undel-0.82
3101132792Dec2917:232007/tmp/test/undel/e2undel-0.82/BUGS
3101153268Dec2917:232007/tmp/test/undel/e2undel-0.82/HISTORY
3101161349Dec2917:232007/tmp/test/undel/e2undel-0.82/INSTALL
3101171841Dec2917:232007/tmp/test/undel/e2undel-0.82/INSTALL.de
3101182175Dec2917:232007/tmp/test/undel/e2undel-0.82/Makefile
31011912247Dec2917:232007/tmp/test/undel/e2undel-0.82/README
3101209545Dec2917:232007/tmp/test/undel/e2undel-0.82/README.de
31012113690Dec2917:232007/tmp/test/undel/e2undel-0.82/apprentice.c
31012219665Dec2917:232007/tmp/test/undel/e2undel-0.82/ascmagic.c
310123221Dec2917:232007/tmp/test/undel/e2undel-0.82/common.h
3101241036Dec2917:232007/tmp/test/undel/e2undel-0.82/compactlog.c
31012530109Dec2917:232007/tmp/test/undel/e2undel-0.82/e2undel.c
3101272447Dec2917:232007/tmp/test/undel/e2undel-0.82/e2undel.h
3101281077Dec2917:232007/tmp/test/undel/e2undel-0.82/file.c
3101292080Dec2917:232007/tmp/test/undel/e2undel-0.82/file.h
3101304484Dec2917:232007/tmp/test/undel/e2undel-0.82/find_del.c
3101312141Dec2917:232007/tmp/test/undel/e2undel-0.82/is_tar.c
3101322373Dec2917:232007/tmp/test/undel/e2undel-0.82/libundel.c
3101337655Dec2917:232007/tmp/test/undel/e2undel-0.82/log.c
31013439600Dec2917:232007/tmp/test/undel/e2undel-0.82/magic.h
3101354591Dec2917:232007/tmp/test/undel/e2undel-0.82/names.h
31013613117Dec2917:232007/tmp/test/undel/e2undel-0.82/softmagic.c
3101375183Dec2917:232007/tmp/test/undel/e2undel-0.82/tar.h

如果对所有用户都打开这个功能,由于日志文件是单向增长的,随着时间的推移,可能会变得很大,不过 e2undel 中还提供了一个 compactlog 工具来删除日志文件中的重复项。

在学习本系列文章介绍的技术之后,利用 e2undel 之类的工具,并使用本系列文章第一部分中提供的补丁,恢复删除文件就变得非常简单了。但是在日常使用过程中,大家可能还会碰到一些意外的情况,比如文件系统发生问题,从而无法正常挂载;使用 mke2fs 之类的工具重做了文件系统;甚至磁盘上出现坏道。此时应该如何恢复系统中的文件呢,下面让我们来逐一看一下如何解决这些问题。

文件系统故障的恢复

回想一下,在超级块中保存了有关文件系统本身的一些数据,在 ext2 文件系统中,还使用块组描述符保存了有关块组的信息;另外,索引节点位图、块位图中分别保存了索引节点和磁盘上数据块的使用情况,而文件本身的索引节点信息(即文件的元数据)则保存在索引节点表中。这些数据对于文件系统来说都是至关重要的,它们是存取文件的基础。如果超级块和块组描述符的信息一旦出错,则会造成文件系统无法正常挂载的情况出现。造成这些信息出错的原因有:

  • 系统管理员操作失误。
  • 设备驱动程序或第三方软件(例如mke2fs之类的)有 bug。
  • 电源意外断电。
  • 内核有 bug。

如果出现这种问题,可能造成的后果有:

  1. 文件系统无法挂载。
  2. 操作系统挂起。
  3. 即使文件系统能够成功挂载,在系统重启时也可能会看到一些错误,或者目录列表中出现乱字符的情况等。

下面让我们来模拟一个出现这种错误的情况。我们知道,超级块信息就保存在分区中的第一个块中,现在我们来试验一下清空这个块中数据的后果:


清单9. 清空超级块信息的后果

#ddif=/dev/zeroof=/dev/sda2bs=4096count=1
#mount/dev/sda2/tmp/test-text2
mount:wrongfs
type,badoption,badsuperblockon/dev/sda2,
missing
codepageorhelperprogram,orothererror
Insomecasesusefulinfoisfoundin
syslog-try
dmesg|tailorso

由于无法从磁盘上读取到有效的超级块信息,mount 命令已经无法挂载 /dev/sda2 设备上的文件系统了。

为了防止这个问题会造成严重的后果,ext2 文件系统会在每个块组中保存一份超级块的拷贝。当然,这会造成一定的空间浪费,因此在最新的 ext2 文件系统中,只是在特定的块组中保存一份超级块的拷贝。具体来说,是在第 0、1 个块组和第 3、5、7 的整数次幂个块组中保存一份超级块的拷贝,而其他块组中的空间都可以节省出来了。下面来看一个 20GB 大小的文件系统的实际例子:


清单10. ext2 文件系统中超级块拷贝的位置

#dumpe2fs/dev/sdb6|grep-isuperblock
dumpe2fs
1.39(29-May-2006)
Primarysuperblockat
0,Groupdescriptorsat1-2
Backupsuperblockat32768,Groupdescriptorsat32769-32770
Backupsuperblockat98304,Groupdescriptorsat98305-98306
Backupsuperblockat163840,Groupdescriptorsat163841-163842
Backupsuperblockat229376,Groupdescriptorsat229377-229378
Backupsuperblockat294912,Groupdescriptorsat294913-294914
Backupsuperblockat819200,Groupdescriptorsat819201-819202
Backupsuperblockat884736,Groupdescriptorsat884737-884738
Backupsuperblockat1605632,Groupdescriptorsat1605633-1605634
Backupsuperblockat2654208,Groupdescriptorsat2654209-2654210
Backupsuperblockat4096000,Groupdescriptorsat4096001-4096002

这是一个 20GB 大的 ext2 文件系统,每个块组的大小是 32768 个块,超级块一共有 11 个拷贝,分别存储在第 0、1、3、5、7、9、25、27、49、81 和 125 个块组中。默认情况下,内核只会使用第一个超级块中的信息来对磁盘进行操作。在出现故障的情况下,就可以使用这些超级块的备份来恢复数据了。具体说来,有两种方法:首先 mount 命令可以使用 sb 选项指定备用超级块信息来挂载文件系统:


清单11. 使用超级块拷贝挂载文件系统

#mount-osb=131072/dev/sda2/tmp/test-text2

需要注意的是,mount 命令中块大小是以 1024 字节为单位计算的,而这个文件系统则采用的是 4096 字节为单位的块,因此 sb 的值应该是 32768*4=131072。

尽管 mount 命令可以使用备用超级块来挂载文件系统,但却无法修复主超级块的问题,这需要使用 e2fsck 这个工具来完成:


清单12. 利用 e2fsck 工具修复 ext2 文件系统中主超级块的问题

#e2fsck/dev/sda2
e2fsck
1.40.2(12-Jul-2007)
Couldn't
findext2superblock,tryingbackupblocks...
/dev/sda2wasnotcleanlyunmounted,checkforced.
Pass
1:Checkinginodes,blocks,andsizes
Pass
2:Checkingdirectorystructure
Pass
3:Checkingdirectoryconnectivity
Pass
4:Checkingreferencecounts
Pass
5:Checkinggroupsummaryinformation

/dev/sda2:*****FILESYSTEMWASMODIFIED*****
/dev/sda2:11/489600files(9.1%non-contiguous),17286/977956blocks

#mount/dev/sda2/tmp/test-text2

e2fsck 工具可以检查出主超级块的问题,然后从其他超级块拷贝中读取数据,并使用它来恢复主超级块中的数据(在 ext2 文件系统中,超级块信息保存在一个 ext2_super_block 的数据结构中,详细信息请参考内核源代码)。修复主超级块的问题之后,mount 命令就可以成功挂载原来的文件系统了。

重建文件系统的解决办法

在日常使用过程中,可能碰到的另外一个问题是管理员可能错误地执行了某些命令,例如使用mke2fs 重建了文件系统,从而造成数据的丢失。实际上,在 mke2fs 创建文件系统的过程中,并不会真正去清空原有文件系统中存储的文件的数据,但却会重新生成超级块、块组描述符之类的信息,并清空索引节点位图和块位图中的数据,最为关键的是,它还会清空索引节点表中的数据。因此尽管文件数据依然存储在磁盘上,但是由于索引节点中存储的文件元数据已经丢失了,要想完整地恢复原有文件,已经变得非常困难了。

然而,这个问题也并非完全无法解决。在 e2fsprogs 包中还提供了一个名为 e2image 的工具,可以用来将 ext2 文件系统中的元数据保存到一个文件中,下面是一个例子:


清单13. 使用超级块拷贝挂载文件系统

#e2image-r/dev/sda2sda2.e2image

这会生成一个与文件系统大小相同的文件,其中包含了文件系统的元数据,包括索引节点中的间接块数据以及目录数据。另外,其中所有数据的位置均与磁盘上存储的位置完全相同,因此可以使用 debugfs、dumpe2fs 之类的工具直接查看:


清单14. 使用 debugfs 查看 e2image 映像文件的信息

#debugfssda2.e2image.raw
debugfs
1.40.2(12-Jul-2007)
debugfs:ls-l
240755(2)00409631-Dec-200715:56.
240755(2)00409631-Dec-200715:56..
1140700(2)001638431-Dec-200715:54lost+found
12100644(1)001048576031-Dec-200715:56testfile.10M
13100644(1)003584031-Dec-200715:56testfile.35K

为了节省空间,这些映像文件以稀疏文件的形式保存在磁盘上,在一个 4GB 的文件系统中,如果 55 万个索引节点中已经使用了 1 万 5 千个,使用 bizp2 压缩后的文件大概只有 3MB左右。

当然,这些映像文件中并没有包含实际文件的数据,不过文件数据依然保存在磁盘上,因此只要及时备份相关信息,在发生意外的情况下是有可能恢复大部分数据的。

磁盘坏道情况的处理

随着磁盘使用的时间越来越长,难免会出现磁盘上出现一些物理故障,比如产生物理坏道。根据物理损坏的严重程度,可能会造成文件丢失、文件系统无法加载甚至整个磁盘都无法识别的情况出现。因此要想将损失控制在最小范围内,除了经常备份数据,在发现问题的第一时间采取及时地应对措施也非常重要。

物理故障一旦出现,极有可能会有加剧趋势,因此应该在恢复数据的同时,尽量减少对磁盘的使用,dd 命令可以用来创建磁盘的完美映像。应该使用的命令如下:


清单15. 使用 dd 命令创建磁盘映像

#ddif=/dev/sdbof=/images/sdb.imagebs=4096conv=noerror,sync

noerror 参数告诉 dd 在碰到读写错(可能是由于坏道引起的)时继续向下操作,而不是停止退出。sync 参数说明对于从源设备无法正常读取的块,就使用NULL填充。默认情况下,dd 使用 512 字节作为一个块的单位来读写 I/O 设备,指定 bs 为 4096 字节可以在一定程度上加速 I/O 操作,但同时也会造成一个问题:如果所读取的这个 4096 字节为单位的数据块中某一部分出现问题,则整个 4096 字节的就全部被清空了,这样会造成数据的丢失。为了解决这种问题,我们可以使用 dd_rescue 这个工具(可以从 http://www.garloff.de/kurt/linux/ddrescue/ 上下载),其用法如下:


清单16. 使用 dd_rescue 命令创建磁盘映像

#dd_rescue/dev/sdb/images/sdb.image–b65536–B512

与 dd 相比,dd_rescue 强大之处在于在碰到错误时,可以以更小的数据块为单位重新读取这段数据,从而确保能够读出尽量多的数据。上面命令中的参数指明正常操作时以 64KB 为单位读取磁盘数据,一旦出错,则以 512 字节为单位重新读取这段数据,直至整个硬盘被完整读出为止。

获得磁盘映像之后,就可以将其当作普通磁盘一样进行操作了。应用本系列文章中介绍的技术,应该能从中恢复出尽可能多的数据。当然,对于那些刚好处于坏道位置的数据,那就实在回天乏力了。

恢复文件策略

截至到现在,本系列文章中介绍的都是在删除文件或出现意外情况之后如何恢复文件,实际上,对于保证数据可用性的目的来讲,这些方法都无非是亡羊补牢而已。制定恰当地数据备份策略,并及时备份重要数据才是真正的解决之道。

不过即使有良好的数据备份策略,也难免会出现有部分数据没有备份的情况。因此,一旦出现误删文件的情况,应该立即执行相应的对策,防止文件数据被覆盖:

  • 断开所有对文件系统的访问。fuser 命令可以用来帮助查看和杀死相关进程,详细用法请参看 fuser 的手册。
  • 如果业务无法停顿,就将文件系统以只读方式重新加载,命令格式为:mount -r -n -o remount mountpoint
  • 应用本系列文章介绍的技术恢复文件。

当然,在进行数据备份的同时,也需要考虑本文中介绍的一些技术本身的要求,例如 e2image映像文件、e2undel 的日志文件等,都非常重要,值得及时备份。

小结

本文介绍了一个功能非常强大的工具 e2undel,可以用来方便地恢复已删除的文件。然后讨论了文件系统故障、文件系统重建、磁盘物理损坏等情况下应该如何恢复数据。随着文件系统的不断发展,Linux 上常用的文件系统也越来越多,例如 ext3/ext4/reiserfs/jfs 等,这些文件系统上删除的文件能否成功恢复呢?有哪些工具可以用来辅助恢复文件呢?本系列后续文章将继续探讨这个问题。

下载

描述 名字 大小 下载方法 修正 e2undel 源码问题的补丁
e2undel-0.82.patch 5KB HTTP
关于下载方法的信息


参考资料

分享到:
评论

相关推荐

    精品删除文件恢复软件(反删除工具) v4.1.zip

    可以恢复硬盘/U盘/SD卡/内存卡上被误删除的文件、直接Shift del删除的文件、清空回收站、剪切的目录、卸载软件删除的文件、第三方加密软件快速隐藏加密的目录、盘符根目录消失但空间还在占用着等各种文件丢失的情况...

    e2undel-开源

    e2undel是一个交互式控制台工具,可在Linux下恢复ext2文件系统上已删除文件的数据。 它不需要任何其他工具,并且在不了解ext2 interna的情况下应该可以使用。

    smartundel

    undel Smart Undelete 为一款数据恢复软件,你可以找回被删除的文件,使用简单,它能巧妙的恢复被删除的文件,甚至那些你认为是无法挽回的损失。它还提供了很多功能选项,仅需一个点击——恢复文件从来没有像这么...

    sysinternal工具及源码

    早期的sysinternals网站的工具及源代码,很多源码现在都已经下载不到,比如ntfsdos(readonly),filemon,regmon,sdel,undel,defrag,vcmon,vxdmon等等的源代码

    高校学生选课系统项目源码资源

    项目名称: 高校学生选课系统 内容概要: 高校学生选课系统是为了方便高校学生进行选课管理而设计的系统。该系统提供了学生选课、查看课程信息、管理个人课程表等功能,同时也为教师提供了课程发布和管理功能,以及管理员对整个选课系统的管理功能。 适用人群: 学生: 高校本科生和研究生,用于选课、查看课程信息、管理个人课程表等。 教师: 高校教师,用于发布课程、管理课程信息和学生选课情况等。 管理员: 系统管理员,用于管理整个选课系统,包括用户管理、课程管理、权限管理等。 使用场景及目标: 学生选课场景: 学生登录系统后可以浏览课程列表,根据自己的专业和兴趣选择适合自己的课程,并进行选课操作。系统会实时更新学生的选课信息,并生成个人课程表。 教师发布课程场景: 教师登录系统后可以发布新的课程信息,包括课程名称、课程描述、上课时间、上课地点等。发布后的课程将出现在课程列表中供学生选择。 管理员管理场景: 管理员可以管理系统的用户信息,包括学生、教师和管理员账号的添加、删除和修改;管理课程信息,包括课程的添加、删除和修改;管理系统的权限控制,包括用户权限的分配和管理。 目标: 为高校学生提

    TC-125 230V 50HZ 圆锯

    TC-125 230V 50HZ 圆锯

    影音娱乐北雨影音系统 v1.0.1-bymov101.rar

    北雨影音系统 v1.0.1_bymov101.rar 是一个计算机专业的 JSP 源码资料包,它为用户提供了一个强大而灵活的在线影音娱乐平台。该系统集成了多种功能,包括视频上传、播放、分享和评论等,旨在为用户提供一个全面而便捷的在线视频观看体验。首先,北雨影音系统具有强大的视频上传功能。用户可以轻松地将本地的视频文件上传到系统中,并与其他人分享。系统支持多种视频格式,包括常见的 MP4、AVI、FLV 等,确保用户能够方便地上传和观看各种类型的视频。其次,该系统提供了丰富的视频播放功能。用户可以选择不同的视频进行观看,并且可以调整视频的清晰度、音量等参数,以适应不同的观看需求。系统还支持自动播放下一个视频的功能,让用户可以连续观看多个视频,无需手动切换。此外,北雨影音系统还提供了一个社交互动的平台。用户可以在视频下方发表评论,与其他观众进行交流和讨论。这为用户之间的互动提供了便利,增加了观看视频的乐趣和参与感。最后,该系统还具备良好的用户体验和界面设计。界面简洁明了,操作直观易用,让用户可以快速上手并使用各项功能。同时,系统还提供了个性化的推荐功能,根据用户的观看历史和兴趣,为用户推荐

    Tripp Trapp 儿童椅用户指南 STOKKE

    Tripp Trapp 儿童椅用户指南

    node-v8.13.0-linux-armv6l.tar.gz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    谷歌浏览器 64位-89.0.4389.128.exe

    Windows版本64位谷歌浏览器,是由Google谷歌公司开发的一款电脑版网络浏览器,可以运行在Windows 10/8.1/8/7 64位的操作系统上。该浏览器是基于其它开放原始码软件所撰写,包括WebKit和Mozilla,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。软件的特点是简洁、快速。并且支持多标签浏览,每个标签页面都在独立的“沙箱”内运行,在提高安全性的同时,一个标签页面的崩溃也不会导致其他标签页面被关闭。此外,谷歌浏览器(Google Chrome)基于更强大的JavaScript V8引擎,这是当前Web浏览器所无法实现的。

    适用于鲲鹏麒麟的OpenJDK1.8

    适用于鲲鹏麒麟的OpenJDK1.8

    毕业设计-基于SSH的任务调度系统的设计与实现

    任务调度试系统,基本功能包括:用户的注册、用户的登录、发起项目、项目详细及搜索等。本系统结构如下: (1)用户的注册登录: 注册模块:完成用户注册功能; 登录模块:完成用户登录功能; (2)发起项目: 发起项目模块:完成了项目及项目下一个或者多个任务的添加; 项目详细:点击项目名称,可以看到项目及任务详细信息; 搜索项目:完成对项目名称的模糊搜索功能 任务调度试系统,基本功能包括:用户的注册、用户的登录、发起项目、项目详细及搜索等。本系统结构如下: (1)用户的注册登录: 注册模块:完成用户注册功能; 登录模块:完成用户登录功能; (2)发起项目: 发起项目模块:完成了项目及项目下一个或者多个任务的添加; 项目详细:点击项目名称,可以看到项目及任务详细信息; 搜索项目:完成对项目名称的模糊搜索功能

    30个炫酷的数据可视化大屏(含源码)

    大屏数据可视化是以大屏为主要展示载体的数据可视化设计,30个可视化大屏包含源码,直接运行文件夹中的index.html,即可看到大屏。 内含:数据可视化页面设计;数据可视化演示系统;大数据可视化监管平台;智能看板;翼兴消防监控;南方软件视频平台;全国图书零售监测数据;晋城高速综合管控大数据;无线网络大数据平台;设备大数据;游戏数据大屏;厅店营业效能分析;车辆综合管控平台;政务大数据共享交换平台;智慧社区;物流云数据看板平台;风机可视化大屏等。

    基于yolov5识别算法实现的DNF自动脚本源码.zip

    优秀源码设计,详情请查看资源源码内容

    毕业设计:基于SSM的mysql-在线网上书店(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_在线网上书店(源码 + 数据库 + 说明文档) 2.系统分析与设计 3 2.1系统分析 3 2.1.1需求分析 3 2.1.2必要性分析 3 2.2系统概要设计 3 2.2.1 项目规划 3 2.2.2系统功能结构图 4 2.3开发及运行环境 4 2.4逻辑结构设计 5 2.4.1 数据库概要说明 5 2.4.2 主要数据表结构 6 2.5文件夹架构 9 2.6编写JAVA BEAN 9 3.网站前台主要功能模块设计 10 3.1前台首页架构设计 10 3.2网站前台首页设计 11 3.3新书上市模块设计 12 3.4特价书籍模块设计 13 3.5书籍分类模块设计 14 3.6会员管理模块设计 15 3.7购物车模块设计 17 3.8收银台设计模块 19 3.9畅销书籍模块设计 20 4.网站后台主要功能模块设计 21 4.1网站后台文件夹架构设计 21 4.2后台主页面设计 21 4.3书籍管理模块设计 22 4.4会员管理模块设计 25 4.5订单管理模块设计 26 4.6公告管理模块设计 28 4.7退出系统页面设计 29 5.网站制作中遇到的问

    python 开发 python爬虫数据可视化分析项目源码加课题报告,源码注解清晰一看就懂,适合新手.zip

    python 开发 python爬虫数据可视化分析项目源码加课题报告,源码注解清晰一看就懂,适合新手

    node-v8.0.0-linux-armv7l.tar.gz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    使用FPGA发送一个经过曼彻斯特编码的伪随机序列

    rtl中存放的是设计文件 sim中存放的是仿真文件

    基于Java的班级管理系统课程设计源码

    附件是基于 Java的班级管理系统课程设计源码,包含程序说明和运行环境要求,文件绿色安全,仅供学习交流使用,欢迎大家下载学习交流!

    最新获取QQ微信头像橘头像阁PHP源码下载.rar

    最新获取QQ微信头像橘头像阁PHP源码下载.rar最新获取QQ微信头像橘头像阁PHP源码下载.rar

Global site tag (gtag.js) - Google Analytics