如何恢复 Linux 上删除的文件 (3)

http://tech.ddvip.com   2008年01月22日    社区交流

内容摘要:恢复系统中删除的文件是一个非常繁琐的过程,而 e2undel 这个工具可以用来方便地恢复文件系统中已删除的文件。本文将首先讨论 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't open log file, undeletion disabled
");
}
  
......
  
int rmdir(const char *pathname)
{
 int err;
 struct stat buf;
 char pwd[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] = '';
 }
 err = (*rmdirp)((char *) pathname);
 if (err) return err;   /* remove() did not succeed */
 if (f)
 {
  if (!S_ISLNK(buf.st_mode)) /* !!! should we check for other file types? */
  {             /* don't log deleted symlinks */
   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) */
  return err;
}  /* rmdir() */
  
......
  
void _fini()
{
 if (f) fclose(f);
}

来源:ibm    作者:冯锐 王磊    责编:豆豆技术应用

正在加载评论...