进程打开了不在任何文件系统上的 inode?

进程打开了不在任何文件系统上的 inode?

所以我试图找出stderr某个进程是否已被重定向到某个不寻常的地方(它是一个 java 进程,我想要一个线程转储,但它是通过一组启动脚本启动的)。

我使用 找到我的进程pgrep,并用它pfiles来查看其中的内容:

4366:/foo/bar/platform/solaris2/jre_1.5.0/bin/java -Xmx2048m -Xms10
当前 rlimit:65536 个文件描述符
 0:S_IFCHR 模式:0666 dev:302,0 ino:6815752 uid:0 gid:3 rdev:13,2
    O_RDONLY|O_LARGEFILE
    /设备/伪/mm@0:null
 1:S_IFREG 模式:0640 dev:85,56 ino:26471 uid:0 gid:0 大小:10485812
    O_WRONLY|O_LARGEFILE
 2:S_IFREG 模式:0640 dev:85,56 ino:26471 uid:0 gid:0 大小:10485812
    O_WRONLY|O_LARGEFILE
 3:S_IFCHR 模式:0666 dev:302,0 ino:6815772 uid:0 gid:3 rdev:13,12

所以我可以看到和stdoutstderr文件描述符 1 和 2)指向同一个位置;我认为它们在启动脚本中被重定向到同一个文件,所以这是相符的。

但是当我查找 inode 号为 26471 的文件时,我看到的是:

# 查找 / -inum 26471
/usr/share/man/man3mlib/mlib_MatrixScale_S16_U8_Sat.3mlib
/proc/4366/fd/1
/proc/4366/fd/2
/proc/4366/fd/83

第一个命中(我确定)是不同文件系统上的文件。 中的三个条目/proc是我的进程打开的 fds。

纵观整个过程/proc/4366,我找不到比从中获得更多的信息pfiles

# ls -li 0 1 2 3
   6815752 c--------- 1 root sys 13, 2 一月 20 14:10 0
     26471 --w------- 0 root root 10485812 1月20日 13:42 1
     26471 --w------- 0 root root 10485812 1月20日 13:42 2
   6815772 c--------- 1 root sys 13, 12 2009 年 6 月 7 日 3
# 文件 0 1 2 3
0:字符特殊(13/2)
1:ASCII 文本
2:ASCII 文本
3:角色特别 (13/12)

(我可以跟踪其中一个 fds 并找出它来自哪个文件。我之所以问这个问题,是因为我显然不太深入地了解 fds 和 inode 之间的关系)。

所以我的写作过程是某物(在某些设备上,inode 为 26471)然后数据进入具有不同 inode 编号的文件中。有人能告诉我这可能是什么吗(或者让我知道我到目前为止的推理是否完全错误)?

答案1

据我所知,find搜索文件系统的目录。如果该文件已被删除但由于打开而仍然存在(unix 上的常见技巧),则它将无法找到find

我还没有在 Solaris 上尝试过,但是这里是关于如何使用lsof来识别此类“已删除但打开”的文件,并通过cat /proc/<procid>/fd/<fdid> > /tmp/xxxx

编辑

看来你已经确定是这种情况,但仍然想知道这是怎么可能的。这里有一个简短的解释:

在 POSIX 文件系统上,文件由其处理inode,目录只不过是“路径 => inode”映射。您可以有多个路径“指向”同一个 inode(这称为硬链接),并且 inode 会记录它有多少个链接。该rm命令只是调用unlink()此路径,这会减少链接数并“可能”删除文件本身。

但是目录树上的路径并不是对 inode 的唯一可能引用,fd正在运行的进程的打开也算数,并且“已删除”文件直到它变为 0 时才会真正被删除。

正如我上面顺便提到的,这是一个常见的伎俩:如果您有一个临时文件,在进程运行结束后您不想保留它,只需打开它并立即“删除”它。打开的句柄将可靠地工作,当您的进程结束时(正常、终止或崩溃),系统将删除句柄并干净地删除临时文件。

日志文件不太可能成为这种“隐藏的自动删除”文件;但意外删除并不难。

由于您删除的日志文件仍然存在并且正在收集数据,因此简单地复制内容似乎没有多大帮助。因此,请尝试创建一个指向 /proc//fd/ 文件的新硬链接,类似于ln /proc/4366/fd/1 /tmp/xxxx。请注意,没有-s标志,因此ln应该创建一个具有与原始文件相同 inode 的新硬链接,而不是符号链接(它只不过是一个指向现有路径的指针,而不是您想要的)。

编辑

ln /proc/... /tmp/...命令无法工作,因为 /proc 和 /tmp 位于不同的文件系统中。不幸的是,我不知道如何为现有 inode 创建路径名。有人希望系统link()调用采用 inode 编号和路径,但它采用源路径和目标路径。

相关内容