我遇到了一个奇怪的问题,即使ps -o args -p <pid>
命令确实在所讨论的服务器上运行,命令也偶尔会找不到所讨论的进程。有问题的进程是用于启动某些Java应用程序的长期运行的包装器脚本。
该问题的“疯狂”现象似乎总是在清晨发生,因此有证据表明,该问题与所讨论的服务器上的磁盘负载有关,因为那时它们负载很重,但是通过运行ps
in在一个紧密的循环中提出问题,我最终可以重现该问题-每运行几百次,我就会收到一个错误。
通过运行以下bash脚本,我成功为失败和成功的运行生成了strace输出:
while [ $? == 0 ] ; do strace -o fail.out ps -o args -p <pid> >/dev/null ; done ; strace -o good.out ps -o args -p <pid>
输出从比较fail.out
和good.out
,我可以看到getdents
失败不知何故在运行系统调用返回比对过程系统的实际数量要少很多(与〜1100相比〜500级)
grep getdents good.out
getdents(5, /* 1174 entries */, 32768) = 32760
getdents(5, /* 31 entries */, 32768) = 992
getdents(5, /* 0 entries */, 32768) = 0
grep getdents fail.out
getdents(5, /* 673 entries */, 32768) = 16728
getdents(5, /* 0 entries */, 32768) = 0
...并且较短的列表未包含实际的pid,因此未找到。
您可以忽略本节,下面的dave_thompson的注释解释了ENOTTY错误,并且它们无关
此外,失败的运行会出现一些
ENOTTY
错误,这些错误不会出现在成功的运行中。在输出的开头附近,我看到了ioctl(1,TIOCGWINSZ,0x7fffe19db310)= -1 ENOTTY(设备不适当的ioctl)ioctl(1,TCGETS,0x7fffe19db280)= -1 ENOTTY(设备不适当的ioctl)
最后我看到一个
ioctl(1,TCGETS,0x7fffe19db0d0)= -1 ENOTTY(设备不正确的ioctl)
最后的失败
ioctl
发生在ps
返回之前,但是发生在ps
已经打印了一个空结果集之后,因此我不确定它们是否相关。我确实知道它们在我所有失败的strace输出中都是一致的,但不会出现在成功的strace输出中。
我完全不知道为什么getdents
偶尔会找不到完整的进程列表,现在我已经到了要更改整个控制脚本来检查包装程序脚本的地步ps
如果第一次失败,可以打电话第二次,但是我想知道是否有人对这里发生的事情有任何想法。
有问题的系统在CentOS 7和procps-ng版本3.3.10-17.el7_5.2.x86_64上运行内核4.16.13-1.el7.elrepo.x86_64
>/dev/null
在“失败”的调用(中环),但不是“好”调用,因此对FD 1. ENOTTY