找出永久阻塞 I/O 的原因(进程处于不间断睡眠状态)

Gil*_*il' 6 linux process debugging io

在 Linux 下,我有一个进程在不间断睡眠(状态 D)中被阻塞。我怎样才能调查是什么导致了这种情况?

我正在运行一个“普通”内核(Debian 构建),没有任何特殊的调试功能。

没有相关的日志条目——事实上,从进程开始到我注意到它之间没有记录任何内容。

strace甚至无法附加到该过程,因为它处于不间断的睡眠状态。即使我知道系统调用被称为什么,那也不一定对我有帮助。我需要知道内核内部发生了什么。

具体来说,该sync命令进入不间断睡眠:( 所以我一定在某个地方遇到了 I/O 问题,但我所有的文件系统似乎都在正常工作。很可能有一个关于 I/O 错误的旧日志条目,但我找不到它(这台机器好久没有重启了,那是很多日志条目)我至少可以知道哪个子系统正在阻塞sync?例如,获取与特定 PID/TID 对应的内核线程的内核回溯?

(我确信重新启动会解决这个问题或显示错误,但我问的是如何调查这个,而不是如何盲目按下按钮。)

小智 4

虽然有点晚了,但对其他人可能会有帮助。

我做了什么:

  1. cat /proc/PID/stack以获得一些方向。就我而言,它与inode和文件系统连接:
[<ffffffff83bbd6f1>] wait_on_page_bit+0x81/0xa0            
[<ffffffff83bced9b>] truncate_inode_pages_range+0x42b/0x750
[<ffffffff83bcf12f>] truncate_inode_pages_final+0x4f/0x60  
[<ffffffff83c6b78c>] evict+0x16c/0x180                     
[<ffffffff83c6bafc>] iput+0xfc/0x190                       
[<ffffffff83c66498>] __dentry_kill+0x158/0x1d0             
[<ffffffff83c66b35>] dput+0xb5/0x1a0                       
[<ffffffff83c4f53d>] __fput+0x18d/0x230                    
[<ffffffff83c4f6ce>] ____fput+0xe/0x10                     
[<ffffffff83ac31cb>] task_work_run+0xbb/0xe0               
[<ffffffff83a2cc65>] do_notify_resume+0xa5/0xc0            
[<ffffffff8419322f>] int_signal+0x12/0x17                  
[<ffffffffffffffff>] 0xffffffffffffffff                    
Run Code Online (Sandbox Code Playgroud)
  1. cat /proc/PID/syscall获取当前系统调用:
3 0x6 0x1ae4bc6d 0x1 0x559320c 0x801df5 0x60161c4e 0x7ffccee38ae0 0x7fcf1a1547bd
Run Code Online (Sandbox Code Playgroud)

3 代表关闭系统调用,6 是文件描述符(系统调用的第一个参数)。它正试图打电话close(6)。

  1. lsof -p PID,但没有我的描述符。
  2. 如果您很幸运并且您的文件在应用程序启动时的某个位置打开,您可以启动它的另一个实例并通过检查该文件lsof。这是我的情况。

祝你好运