为什么 /proc/$PID/fd/ 中的符号链接充当硬链接?

use*_*811 7 linux symbolic-link proc

当符号链接的目标被删除时,它指向空,并且无法获得被删除目标的内容。

中的文件/proc/$PID/fd/显示为符号链接,但它们允许您访问已删除目标的内容,如下所述:Recover Deleted Linux Files Withlsof .

这是如何运作的?如果它不作为一个链接,为什么它显示为一个符号链接?proc 文件系统的符号链接实现是否保留了对文件 inode 的引用?

Kam*_*ski 4

如果其目标被删除,则当您使用或时, 中的实体/proc/$PID/fd/会显示为损坏的符号链接,但在使用 打开时它的行为确实有所不同。ls(1)file(1)open(2)

在我的 Debian 9 上,我常常strace(1)看到当我尝试读取符号链接时会发生什么。命令是sudo strace cat "$symlink"。来自 stderr 的相关行是

(注意:我并不是说这些都是open(2)一般情况下可能出现的结果)。

结果:

               | regular symlink | /proc/$PID/fd/$N |
---------------+-----------------+------------------+
exists, valid  |       OK        |        OK        |
exists, broken |     ENOENT      |        OK        | <- the difference
doesn't exist  |     ENOENT      |      ENOENT      |
---------------+-----------------+------------------+
Run Code Online (Sandbox Code Playgroud)

我还了解到,当我跑步时,file "$symlink"它会调用lstat(2)readlink(2)stat(2)这些是基于路径而不是文件描述符的系统调用。如果符号链接存在(有效或损坏),open(2)则永远不会调用它来打开它或其目标。ENOENTfromstat(2)表示链接已损坏。

我的结论是:“断开的链接”是从某些系统调用的输出派生的属性;但是当您打开来自 的链接时/proc/$PID/fd/open(2)只知道如何处理它,而不关心其他工具会产生什么结果。

请注意,整个/proc文件系统仅伪造“正常”文件系统。一些怪癖:

  • 文件可能具有动态内容,但它们不会通过系统调用进行修改(尝试inotifywait)。
  • 对象可能会出现(消失),但它们不会通过系统调用创建或删除(再次强调)inotifywait)创建或删除。
  • 从某种意义上说,在你与对象交互之前,对象可能并不存在。运行bash并等待几分钟。调用ls -l /proc/$$/fd以查看其文件描述符。也许ctimes会显示“此时此刻”。然而,如果您每隔几秒重复一次该命令,您会发现 ctime 永远不会改变。(琐事:起初我以为我可以回答这个问题确定文件打开的时间stat和符号链接/proc/$PID/fd/,但我错了;现在你知道为什么了)。

难怪您询问的这些符号链接在某些情况下的行为与常规符号链接不同。整个/proc设计的行为有所不同。我想open(2)是故意赋予了利用它的能力。