重新链接已删除的文件

有时候,人们删除他们不应该的文件,一个长时间运行的进程仍然打开文件,通过捕获/proc/<pid>/fd/N恢复数据就不够了。 真棒,如果你可以通过运行一些魔法选项来“撤销”删除,这将允许你重新链接到inode号码(通过lsof恢复)。

我找不到任何Linux工具来做到这一点,至less粗略谷歌search。

你有什么,serverfault?

编辑1:从/proc/<pid>/fd/N捕获文件的原因不够好,因为仍然有文件打开的进程仍在写入。 删除操作将从文件系统名称空间中删除对inode的引用。 我想要的是重新创build参考的方法。

EDIT2:'debugfs ln'起作用,但是由于原始的文件系统数据,风险太高。 恢复的文件也疯狂不一致。 链接计数为零,我不能添加链接。 因为我可以使用/proc/<pid>/fd/N来访问数据而不会破坏我的fs,所以我更糟糕。

这听起来像你已经了解了很多,所以我不会过多的细节。 有几种方法可以findinode,通常可以通过cat和stdoutredirect。 你可以使用debugfs 。 在以下运行此命令:

ln <$INODE> FILENAME

确保你有文件系统的备份。 之后你可能需要运行一个fsck。 我用一个仍然写入的inode成功地testing了它,它确实能够创build一个到已解除引用的inode的新硬链接。

如果文件与ext3中的未打开文件未链接,数据将丢失。 我不确定这是多么一贯的真实,但我的大部分数据恢复体验是与ext2。 从ext3 FAQ:

问:如何从ext3分区恢复(取消删除)已删除的文件? 其实,你不能! 这就是开发者之一Andreas Dilger所说的:

为了确保ext3在崩溃之后可以安全地恢复一个unlink,它实际上将inode中的块指针清零,而ext2只是将这些块标记为块位图中未使用,并将inode标记为“已删除”,并将块指针单独。

你唯一的希望就是“grep”你的文件已被删除的部分,希望最好。

这个问题也有相关的信息:

我在linux服务器上用空白文件覆盖了一个大文件。 我可以恢复现有的文件吗?

真棒,如果你可以通过运行一些魔法选项来“撤销”删除,这将允许你重新链接到inode号码(通过lsof恢复)。

这个令人敬畏的内容被引入到了v8.0 (GNU / coreutils)中的ln -L|--logical选项,导致ln先取消引用/proc/<pid>/fd/<handle> 。 所以一个简单的

 ln -L /proc/<pid>/fd/<handle> /path/to/deleted/file 

足以重新链接已删除的文件。

你所看到的debugging方式并不能真正起作用,最好是在重启后你的文件会被自动删除(因为日志),最坏的情况是你可能会丢失文件系统导致“重启死机”。 正确的解决scheme(TM)是执行在VFS级别的撤消删除(这也有实际上所有当前的Linux文件系统工作的额外好处)。 系统调用方式(flink)每次出现在LKML中都被击落,所以最好的方式是通过一个模块+ ioctl。

一个实现这个方法的项目,有相当小而干净的代码是fdlink( https://github.com/pkt/fdlink.git,对于使用Ubuntu maverick内核testing的版本)。 有了它,插入模块(sudo insmod flink_dev.ko)后,你可以做“./flinkapp / proc // fd / X / my / link / path”,它会按照你的意思去做。

你也可以使用vfs-undelete.sourceforge.net的转发端口版本,也可以自动重新链接到原来的名字,但是fdlink的代码更简单,而且工作起来也是一样,所以这是我的首选。

我不知道如何去做你想要的,但我要做的是:

  • 从另一个进程打开文件RO
  • 等待原始进程退出
  • 将数据从打开的FD复制到一个文件

不理想,显然,但可能。 另一种select是使用debugfs(使用link命令),但是在生产机器上有点吓人!

今天遇到同样的问题。 我能想到的最好的就是跑步

 % tail -n +0 -f /proc/<pid>/fd/<fd> /path/to/deleted_file 

在tmux / screen会话中,直到过程结束。

有趣的问题。 面试官在面试中对我提出了同样的问题。 我告诉他的是,要做到这一点并不容易,一般来说不值得花费时间和精力。 我问他,他认为这个问题的解决scheme是…

  1. 使用lsof在磁盘上查找该进程的inode编号,因为即使该文件已被删除,它仍然会出现…关键是它仍然是打开的。
  2. 通过文件系统debugging器从文件系统中提取信息。

使用Sleuthkit icat。

 sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file 

快速的解决scheme,为我工作,没有吓倒工具:

1)直接在/ proc中查找process + fd:

 ls -al /proc/*/fd/* 2>/dev/null | grep {filename} 

2)然后一个类似的技术@ nickray的,与pv抛出:

 tail -c +0 -f /proc/{procnum}/fd/{fdnum} | pv -s {expectedsize} > {recovery_filename} 

ls /proc/{procnum}/fd/{fdnum}会告诉你该文件不存在)),但是如果你知道确切的大小(以字节为单位),你可以使用pv -S计数到达时退出。