Troubleshooting - job不退出 - 如何找出誰启动了dbus-daemon(或调用了dbus-launch)

Posted 王万林 Ben

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Troubleshooting - job不退出 - 如何找出誰启动了dbus-daemon(或调用了dbus-launch)相关的知识,希望对你有一定的参考价值。

Troubleshooting - job不退出 - 如何找出誰启动了dbus-daemon(或调用了dbus-launch)



前言

dbus-daemon是什么?

请移步官网


问题描述

USER的集群job不退出——
在集群中USER提交了job,从任务的日志看已经跑完成了,但job还是显示RUN状态。管理员登录上去查看,发现USER有dbus-launch与dbus-daemon两个进程在执行机运行着。将这两个进程kill掉,job随即显示完成。

问题分析

集群如何判断job退出或完成?

一般集群(如LSF集群),会使用Control Group来控制job的资源使用,通过判断进程组下的进程状态,来决定job是否退出或完成。如果进程组里有进程在RUN,则集群判断job还在RUN。

誰启动了dbus-daemon?

问题初探

使用
ps -p <PID of dbus-launch> < PID of dbus-daemon> -f
查看,发现这两个进程的父进程都是1,这说明启动它的进程先行exit了,让这两个进程被1号进程接管了。问题陷入僵局:不知道是誰(code path)启动的这两个进程。

收集日志

通过命令
strace -ttTffy -o /tmp/$USER.log <CMD>
跟踪进程以及子进程的系统调用

分析日志

  1. 从日志文件中过滤dbus-launch
    egrep dbus-launch /tmp/$USER.log*
    找出使用exec启动dbus-launch的进程号A
  2. 随后从日志文件过滤使用clone或fork生成进程号A进程号B
egrep '= <进程号A>|= <进程号B>' /tmp/$USER.log*
  1. 然后从步骤中找到的进程号B的日志文件里,过滤exec系统调用,看运行的code path
  • 如果这个code path是非系统下的,则找到答案了;
  • 如果是系统下的,则再重复步骤2步骤3,直到找到的code path是非系统下,USER自己的程序。
  1. 该程序就是启动dbus-daemon的父+进程。

本问题中,USER的程序-> inotify-send-> dbus-launch-> dbus-daemon,这就是整个调用链。

问题解决

要想让dbus-launch与dbus-daemon随会话退出而退出,启动时有一个命令行选项--exit-with-session可以控制。但inotify-send是系统命令,它在调用dbus-launch时没有指明该选项,因此问题看似无解。
只能让USER的程序中的调用inotify-send后,程序结束前先发送kill命令给dbus-daemon与dbus-launch进程,确保程序结束时无dbus相关程序在后台运行,导致集群误判。

相关资料

开启了cgroup的环境残留的dbus-daemon 的清理脚本

以上是关于Troubleshooting - job不退出 - 如何找出誰启动了dbus-daemon(或调用了dbus-launch)的主要内容,如果未能解决你的问题,请参考以下文章

Map Reduce

jobs|ps|杀死nohup

20Job和CronJob

TroubleShooting经验总结

[python3 - TroubleShooting] UnicodeEncodeError: 'gbk' codec can't encode character '

Troubleshooting:Connect-SPOService 命令失败