Linux系统优化与调试之一 - 是谁杀死了比尔

Posted by 云谷计算 on January 16, 2018

最近碰到一个棘手的问题,一台CentOS云主机的ip地址在运行一段时间后,总是莫名奇妙的消失,导致主机无法登录和访问,只能通过vnc控制台恢复,经过调查后发现,该主机的dhclient服务被杀掉,进一步研究ifup-eth代码发现,如果不设置PERSISTENT_DHCLIENT参数,那么dhclient服务启动的时候会默认采用-1参数,导致dhclient服务被杀死后,ip地址也随后被释放。


if [ -n "${DYNCONFIG}" ] && [ -x /sbin/dhclient ]; then
    if is_true "${PERSISTENT_DHCLIENT}"; then
        ONESHOT="";
    else
        ONESHOT="-1";
    fi;
    generate_config_file_name
    generate_lease_file_name
 
    # Initialize the dhclient args and obtain the hostname options if needed:
    DHCLIENTARGS="${DHCLIENTARGS} ${ONESHOT} -q ${DHCLIENTCONF} -lf ${LEASEFILE} -pf /var/run/dhclient-${DEVICE}.pid"

为了解决这个问题,我们修改了ifcfg-eth0文件,添加了PERSISTENT_DHCLIENT参数。同时,我一直很好奇到底dhclient是如何被杀死的,但是却一直找不到简单有效的工具来跟踪系统信号,特别是SIGKILL。

killsnoop

killsnoop是Netflix大神Brendan Gregg写的perf-tools工具中的一个子工具,可以用来trace系统中的各种kill事件,对低版本的Linux支持也比较好,使用起来也非常简单。

安装

wget https://raw.githubusercontent.com/brendangregg/perf-tools/master/killsnoop
chmod +x killsnoop

试用

打开终端1,执行killsnoop, 默认它会跟踪系统所有的kill事件:

./killsnoop

打开终端2,执行一个长任务,比如sleep

sleep 120

打开终端3, 用SIGKILL杀死终端2上的 sleep

[root@hluo ~]# ps -ef|grep sleep
root     15318 15284  0 23:20 pts/1    00:00:00 sleep 120
root     15358 15328  0 23:20 pts/2    00:00:00 grep --color=auto sleep
 
[root@hluo ~]# kill -9 15318

然后我们在killsnoop所在的终端1上会看到如下输出,说明sleep进程被bash进程15328杀死了。

[root@hluo ~]# ./killsnoop
Tracing kill()s. Ctrl-C to end.
COMM             PID    TPID     SIGNAL     RETURN
bash             15328  15318    9          0

把killsnoop跑在后台,用-p参数指定需要跟踪的进程,比如dhclient, 用-t指定显示时间戳,就可以知道到底是谁在什么时候杀死了dhclient了。

killsnoop -t -p pidof(dhclient)