进程已打开inode不在任何文件系统?

所以我试图找出一个进程stderr是否被redirect到一些不寻常的(这是一个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
     /装置/伪/毫米@ 0:空
  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)指向相同的地方; 我认为他们被redirect到启动脚本中的同一个文件,所以这个logging。

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

 #find / -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根系统13,2月20日14:10 0
      26471  -  w ------- 0 root root 10485812 Jan 20 13:42 1
      26471  -  w ------- 0 root root 10485812 Jan 20 13:42 2
    6815772 c --------- 1根系sys 13,2009年6月12日3
 #文件0 1 2 3
 0:特殊字符(13/2)
 1:ascii文本
 2:ascii文本
 3:字符特殊(13/12)

(我可以找出这些文件中的一个,并找出它是哪个文件,因为我明显不明白fds和inode之间的关系是否足够深入)。

所以我的过程正在写入某些东西 (在某些设备上,使用inode 26471),然后数据将进入具有不同inode编号的文件。 任何人都可以给我一个这东西可能是什么的想法(或者甚至让我知道,如果我的推理到目前为止是完全破碎)?

AFAIK, findsearch文件系统的目录。 如果该文件被删除,但仍然存在,因为它是开放的(一个普通的技巧在Unix上),它不会被find

我还没有尝试在Solaris中,但是这里有一个关于使用lsof来标识这样的'已删除但是打开'的文件,并通过cat /proc/<procid>/fd/<fdid> > /tmp/xxxx

编辑

似乎你已经确定了这种情况,但仍然想知道如何可能。 这里是一个简短的解释:

在POSIX文件系统上,文件由它的inode来处理,而这些目录只是一个“path => inode”映射。 你可以有多个path指向同一个inode(它被称为硬链接),inode保持它有多less链接的计数。 rm命令简单地在这个path上调用unlink() ,这会减less链接数量,并且可能会删除文件本身。

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

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

日志文件不是这样一个“隐藏自动删除”文件的可能的候选人; 但不小心却不难

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

编辑

ln /proc/... /tmp/...命令无法工作,因为/ proc和/ tmp位于不同的文件系统中。 不幸的是,我不知道为现有的inode创build一个path名。 人们会希望link()系统调用会占用一个inode编号和一个path,但是它需要源path和目标path。