打开的文件句柄死后去哪儿了?

amp*_*ine 15 filesystems open-files

在文件句柄对它们打开时被删除的文件会发生什么?

自从我发现我可以在MPlayer中播放视频文件时删除它并且它仍然可以播放到最后,我一直想知道这一点。它从哪里提取数据?它仍然来自硬盘驱动器吗?一旦我删除了文件,它是否被复制到 RAM 中?

如果它仍在硬盘驱动器上,如果我在程序运行时从实质上未分配的空间中读取文件系统而填满了文件系统,会发生什么?如果它在 RAM 中缓冲,如果我刷新缓冲区会发生什么?

如果文件位于 NFS 共享上会发生什么情况——它是否存储在服务器上?(这难道不是一个安全风险——被大量打开的远程文件句柄引起的 DoS?)

做一个lsof -n |grep '(deleted)'有时会产生有趣的结果;如果我正在升级交换共享库文件的包,那么运行已经使用这些库的程序仍然可以使用它们,就好像没有任何改变一样。

额外问题:在这种情况下,有什么方法可以从死者身上取回数据吗?

Ign*_*ams 14

尽管不存在指向 inode 的更多硬链接,但 inode 仍保留在磁盘上。当文件描述符关闭时,它们将被删除。在此之前,该文件可以正常修改,除非需要文件名/硬链接的操作。

debugfs 可以使用类似的工具来恢复 inode 的内容。

  • 这是正确的,但是如果文件仍然打开,您可以通过转到 /proc/<PID>/fd 来取回它,其中 PID 是文件仍然打开的程序的 pid。该目录包含程序的所有打开文件描述符,您可以像访问普通文件一样访问它们,因此您可以创建一个硬链接来“恢复”文件。 (10认同)
  • 我只需要补充一点,这太棒了。 (2认同)

Bil*_*hor 5

内核对索引节点的引用进行引用计数。请参阅我对close() 文件描述符时会发生什么的回答.

删除打开的文件可能并不比打开文件更有效。在ulimit上打开的文件提供了对这个DOS尝试一些保护。它适用于所有打开的文件,无论是否删除。


Gil*_*il' 5

一个文件只有在每次对它的引用消失后才会在文件系统上被擦除。名称和打开的句柄都算作引用。只要文件在程序中打开,它就不会被删除,尽管大多数系统不允许您为其重新创建名称。

数据仍在驱动器上,但文件被标记为链接计数为 0。如果系统崩溃,下次重新启动时 fsck 知道它必须删除数据。与未删除的文件一样,这不会导致拒绝服务。

据我所知,您无法在股票 Linux 系统上重新创建指向该文件的链接(缺少使用debugfs或类似方法绕过文件系统驱动程序),但您可以轻松恢复内容:cat /proc/12345/fd/42其中 12345 是打开文件的进程 ID 42 是文件描述符编号。

通过 NFS,当您删除在某些客户端中仍处于打开状态的文件时,NFS 服务器会重命名服务器上的文件,但在所有客户端都释放该文件之前不会删除它。根据我的经验,新名称是.nfs…,但我不知道该名称是否在所有 NFS 实现中都相同。