打开的文件句柄死后会去哪里?

打开的文件句柄死后会去哪里?

当文件句柄打开时被删除的文件会发生什么情况?

自从我发现我可以在播放视频文件时删除它,我就一直想知道这个问题播放器而且它仍然会一直播放到最后。它从哪里提取数据?它仍然来自硬盘吗?我删除文件后它是否被复制到 RAM 中?

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

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

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

额外问题:在这种情况下有没有办法让数据起死回生?

答案1

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

debugfs类似的工具可用于恢复 inode 的内容。

答案2

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

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

答案3

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

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

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

通过 NFS,当您删除某个客户端中仍打开的文件时,NFS 服务器会在服务器上重命名该文件,但直到所有客户端都释放该文件后才会将其删除。根据我的经验,新名称是.nfs…,但我不知道该名称在所有 NFS 实现中是否相同。

相关内容