如何在Linux中找到哪个进程泄漏文件句柄?

时间:2014-03-28 14:06:10

标签: file memory-leaks linux-kernel

问题事件:

我们的生产系统开始拒绝服务,并显示错误消息“系统中打开的文件过多”。大多数服务都受到影响,包括无法启动新的ssh会话,甚至从物理终端登录到虚拟控制台。幸运的是,一个root ssh会话是开放的,所以我们可以与系统交互(士气:保持一个根会话始终打开!)。作为副作用,某些服务(nameddbus-daemonrsyslogdavahi-daemon)使CPU(100%负载)饱和。系统还通过NFS向一个非常繁忙的客户端提供一个大型目录,该客户端此刻正在备份50000个小文件。重新启动各种服务和程序规范化了他们的CPU行为,但是没有解决“系统中打开的文件太多”的问题。

疑似原因

最有可能的是,某些程序正在泄漏文件句柄。可能罪魁祸首是我的tcl程序,它也使CPU饱和(不正常)。然而,杀死它并没有帮助,但是,最令人不安的是,lsof不会泄露大量的打开文件。

一些证据

我们不得不重新启动,所以无论收集到什么信息都是我们所拥有的。

root@xeon:~# cat  /proc/sys/fs/file-max
205900
root@xeon:~# lsof
COMMAND     PID    USER   FD      TYPE     DEVICE   SIZE/OFF       NODE NAME
init          1    root  cwd       DIR        8,6       4096          2 /
init          1    root  rtd       DIR        8,6       4096          2 /
init          1    root  txt       REG        8,6     124704    7979050 /sbin/init
init          1    root  mem       REG        8,6      42580    5357606 /lib/i386-linux-gnu/libnss_files-2.13.so
init          1    root  mem       REG        8,6     243400    5357572 /lib/i386-linux-gnu/libdbus-1.so.3.5.4
...
A pretty normal list, definitely not 200K files, more like two hundred.

这可能是问题出现的地方:

less /var/log/syslog

Mar 27 06:54:01 xeon CRON[16084]: (CRON) error (grandchild #16090 failed with exit status 1)
Mar 27 06:54:21 xeon kernel: [8848865.426732] VFS: file-max limit 205900 reached
Mar 27 06:54:29 xeon postfix/master[1435]: warning: master_wakeup_timer_event: service pickup(public/pickup): Too many open files in system
Mar 27 06:54:29 xeon kernel: [8848873.611491] VFS: file-max limit 205900 reached
Mar 27 06:54:32 xeon kernel: [8848876.293525] VFS: file-max limit 205900 reached

netstat也没有出现明显的异常现象。 pstop的手册页不表示显示打开文件计数的功能。可能问题会在几个月后重演(这是我们的正常运行时间)。

有关于识别打开文件可以采取哪些其他措施的想法?

更新

qehgt确定可能的原因之后,这个问题改变了意义。

除了NFS v4代码中的错误之外,我怀疑Linux中存在设计限制,内核泄漏文件句柄可以 NOT 识别。因此,原始问题转变为: “谁负责Linux内核中的文件句柄?”和“我在哪里发布这个问题?”。第一个答案很有帮助,但我愿意接受更好的答案。

1 个答案:

答案 0 :(得分:1)

可能根本原因是NFSv4实施中的错误:https://stackoverflow.com/a/5205459/280758

他们有类似的症状。