处理一次系统假死工作纪实

系统
最近碰到客户反馈一个问题,系统hang了,ssh登录不上,但是可以ping通,通过串口登录进去之后,敲有些命令会卡住,查看cpu负载内存都很正常,手动触发kdump之后看不出死锁/softlockup/hardlockup等异常状态.而且重要的是已经影响到客户几十亿的业务了。

[[338497]]

本文转载自微信公众号「相遇Linux」,作者JeffXie 。转载本文请联系相遇Linux公众号。   

最近碰到客户反馈一个问题,系统hang了,ssh登录不上,但是可以ping通,通过串口登录进去之后,敲有些命令会卡住,查看cpu负载内存都很正常,手动触发kdump之后看不出死锁/softlockup/hardlockup等异常状态.而且重要的是已经影响到客户几十亿的业务了。

我能拿到的只有客户提供的vmcore,为了生活而奔波的人儿赶紧分析起来:

系统(SUSE 11SP1)

#crash ./vmcore ./vmlinux-2.6.32.59-0.19-default

./vmlinux-2.6.32.59-0.19-default.gz

crash>foreach IN bt > inbt

任意找到一个IN(可中断睡眠)的进程 12813 查看堆栈:

  1. crash>  bt 12813 
  2.  
  3. PID:12813  TASK: ffff880262eda140  CPU: 8  COMMAND: "sshd" 
  4.  #0 [ffff880f98e1ba58] schedule atffffffff8139d2a4 
  5.  #1 [ffff880f98e1bb10] schedule_timeout atffffffff8139d935 
  6.  #2 [ffff880f98e1bba0] unix_wait_for_peer atffffffff81376e27 
  7.  #3 [ffff880f98e1bc00] unix_dgram_sendmsg atffffffff813785c2 
  8.  #4 [ffff880f98e1bcb0] sock_sendmsg atffffffff812e8ddc 
  9.  #5 [ffff880f98e1be50] sys_sendto atffffffff812e9318 
  10.  #6 [ffff880f98e1bf80] system_call_fastpath atffffffff81002f7b 

汇编unix_dgram_sendmsg()

  1. crash>dis unix_dgram_sendmsg 
  2. ... 
  3. 2410xffffffff813785b7 <unix_dgram_sendmsg+1143>:   mov   %r13,%rsi 
  4. 2420xffffffff813785ba <unix_dgram_sendmsg+1146>:   mov   %rbp,%rdi  (key1) 
  5.  rdi代表unix_wait_for_peer函数的第一个参数 
  6. 2430xffffffff813785bd <unix_dgram_sendmsg+1149>:   callq 0xffffffff81376da0 <unix_wait_for_peer> 

进程12813 unix_wait_for_peer() 函数的堆栈数据:

  1. crash>rd -SS ffff880f98e1bba0 -e ffff880f98e1bc00 
  2. ffff880f98e1bba0:  unix_wait_for_peer+135 0000000000000001 
  3. ffff880f98e1bbb0:  [ffff880262eda140:task_struct]autoremove_wake_function 
  4. ffff880f98e1bbc0:  ffff88021ea8bbc0 ffff880238315bc0 
  5. ffff880f98e1bbd0:  memcpy_fromiovec+87 [ffff880238514980:UNIX] 
  6. ffff880f98e1bbe0:  [ffff880238514c30:UNIX] [ffff880238514980:UNIX] 
  7. ffff880f98e1bbf0:  [ffff880ff708b630:UNIX] 7fffffffffffffff 

汇编unix_wait_for_peer()

  1. crash>dis unix_wait_for_peer 
  2. 0xffffffff81376da0<unix_wait_for_peer>:       sub    $0x58,%rsp 
  3. 0xffffffff81376da4<unix_wait_for_peer+4>:     mov    $0x1,%edx 
  4. 0xffffffff81376da9<unix_wait_for_peer+9>:     mov    %r13,0x50(%rsp) 
  5. 0xffffffff81376dae<unix_wait_for_peer+14>:    lea    0x2b8(%rdi),%r13 
  6. 0xffffffff81376db5<unix_wait_for_peer+21>:    mov    %rbx,0x38(%rsp) 
  7. 0xffffffff81376dba<unix_wait_for_peer+26>:    mov    %gs:0xa580,%rax 
  8. 0xffffffff81376dc3<unix_wait_for_peer+35>:    mov    %rax,0x8(%rsp) 
  9. 0xffffffff81376dc8<unix_wait_for_peer+40>:    lea    0x18(%rsp),%rax 
  10. 0xffffffff81376dcd<unix_wait_for_peer+45>:    mov    %rbp,0x40(%rsp) (key2) 

rbp压入堆栈(0x58-0x40)处,正好是unix_wait_for_peer堆栈中ffff880f98e1bbe8处,即( [ffff880238514980:UNIX])

  1. 0xffffffff81376dd2<unix_wait_for_peer+50>:    mov    %rdi,%rbx 
  2. 0xffffffff81376dd5<unix_wait_for_peer+53>:    mov    %rsi,%rbp 
  3. 0xffffffff81376dd8<unix_wait_for_peer+56>:    mov    %r13,%rdi 

查看unix_wait_for_peer()函数源码:

  1. 1005static long unix_wait_for_peer(struct sock *other, long timeo) (key3) 
  2. 1006{ 
  3. 1007         struct unix_sock *u = unix_sk(other); 
  4. 1008         int sched; 
  5. 1009         DEFINE_WAIT(wait); 
  6. 1011   prepare_to_wait_exclusive(&u->peer_wait, &wait,TASK_INTERRUPTIBLE); 
  7. .. 
  8. 1019         if (sched) 
  9. 1020                 timeo =schedule_timeout(timeo); 
  10. 1021 
  11. 1022         finish_wait(&u->peer_wait,&wait); 
  12. 1023         return timeo; 
  13. 1024} 

根据s(key1)(key2)(key3)可以知道12813进程在等待unix_sock(ffff880238514980)

  1. crash>struct unix_sock ffff880238514980 | grep peer_wait -A 10 
  2.  
  3.   peer_wait = { 
  4.     lock = { 
  5.       raw_lock = { 
  6.         slock = 3369322707 
  7.       } 
  8.     }, 
  9.     task_list = { 
  10.       next = 0xffff880173427bc0, 
  11.       prev = 0xffff8801877a7bc0 
  12.     } 
  13.   } 

查询出这个unix_sock是系统中的/dev/log文件(由syslog-ng创建,系统中大量需要记录log的进程需要通过这个unix_sock与syslog-ng通信,可以参考mansyslog-ng 和/etc/syslog-ng/syslog-ng.conf 配置文件)

  1. crash>struct unix_sock ffff880238514980 
  2. ... 
  3. dentry= 0xffff880e7634b9c0, 
  4. ... 
  5. crash>struct dentry 0xffff880e7634b9c0 
  6. ... 
  7.  name = 0xffff880e7634ba60 "log" 
  8.  ...  

遍历这个unix_sock的所有等待队列,

说明有645个进程正在等待这个unix_sock(ffff880238514980/dev/log)

  1. crash>list __wait_queue.task_list  -s__wait_queue.private -H 0xffff880173427bc0 | grep -i private | wc -l 
  2. 645 

所有等待unix_sock的进程重定向到一个wait_unix_sock_process文件

  1. crash>list __wait_queue.task_list  -s__wait_queue.private -H 0xffff880173427bc0 | grep -i private  > wait_unix_sock_process 

查询所有的sshd进程

  1. crash>ps | grep sshd 
  2.   7097     1   6  ffff880244cae5c0  IN  0.0   54088   1392 sshd 
  3.   12813  7097   8  ffff880262eda140  IN  0.0   60148   2900 sshd 
  4.   19055  7097   2  ffff880ff74c4200  IN  0.0   60148   2900 sshd 
  5.   21642  7097   1  ffff880262fb4340  IN  0.0   60148   2904 sshd 
  6.   21958  7097   1  ffff880ffab501c0  IN  0.0   60148   2900 sshd 
  7.   22459   7097  6  ffff880ff1ed4100  IN  0.0  121052  10272 sshd 
  8.   22476 22459   0  ffff88022d11a500  IN  0.0  121352   4552 sshd 
  9.   23334  7097   2  ffff880174b04640  IN  0.0   60148   2900 sshd 

sshd进程大部分都在wait_unix_sock_process文件中,所以ssh登录之后会卡住

查看syslog-ng进程堆栈

  1. crash>bt 15232 
  2. PID:15232  TASK: ffff8801aba90680  CPU: 6  COMMAND: "syslog-ng" 
  3.  #0 [ffff88021ea8ba58] schedule atffffffff8139d2a4 
  4.  #1 [ffff88021ea8bb10] schedule_timeout atffffffff8139d935 
  5.  #2 [ffff88021ea8bba0] unix_wait_for_peer atffffffff81376e27 
  6.  #3 [ffff88021ea8bc00] unix_dgram_sendmsg atffffffff813785c2 
  7.  #4 [ffff88021ea8bcb0] sock_sendmsg atffffffff812e8ddc 
  8.  #5 [ffff88021ea8be50] sys_sendto atffffffff812e9318 
  9.  #6 [ffff88021ea8bf80] system_call_fastpath atffffffff81002f7b 

查看 unix_wait_for_peer()堆栈数据:

  1. crash>rd -SS ffff88021ea8bba0 -e ffff88021ea8bc00 
  2. ffff88021ea8bba0:  unix_wait_for_peer+135 0000000000000001 
  3. ffff88021ea8bbb0:  [ffff8801aba90680:task_struct]autoremove_wake_function 
  4. ffff88021ea8bbc0:  ffff880fce8dfbc0 ffff880f98e1bbc0 
  5. ffff88021ea8bbd0:  memcpy_fromiovec+87 [ffff880238514980:UNIX] 
  6. ffff88021ea8bbe0:  [ffff880238514c30:UNIX][ffff880238514980:UNIX] (key4) 
  7. ffff88021ea8bbf0:  [ffff88104c1c3930:UNIX] 7fffffffffffffff 

由(key4)可知syslog-ng也是在等待ffff880238514980 unix_sock

所以系统中大量的进程,包括sshd cron等其他的645个进程都在等待unix_sock(/dev/log)(/dev/log由syslog-ng创建),syslog-ng卡住在等这个unix_sock之后,系统中大量的进程都会卡住,包括sshd cron进程等. 但是syslog-ng为什么卡住从vmcore根本看不出来,很可能进程在用户层锁住了.

通过查看客户系统中最近安装的软件发现,他们最近安装了两个定制软件,卸载之后系统恢复正常。

  1. # /bin/rpm -qa --last 
  2. CARKpam-11.01-1.19                    Tue Jun  9 22:49:22 2020 
  3. CARKaim-11.01-1.5                       Tue Jun  9 22:38:48 2020 

 

责任编辑:武晓燕 来源: 相遇Linux
相关推荐

2022-01-10 10:26:30

Kubernetes抓包环境

2023-11-06 07:45:42

单据图片处理

2017-06-12 11:09:56

计数架构数据库

2021-03-18 23:47:18

MySQLselect索引

2021-02-01 09:00:34

Ceph octopu集群运维

2011-06-28 10:41:50

DBA

2019-09-12 09:40:34

秒杀系统高并发

2023-06-07 07:31:04

PC端app脱壳技巧

2021-12-27 10:08:16

Python编程语言

2020-10-24 13:50:59

Python编程语言

2022-09-03 18:29:49

开发技术

2010-09-07 15:31:20

SQL语句事务

2009-11-06 10:49:53

2022-01-10 09:31:17

Jetty异步处理seriesbaid

2017-08-14 13:10:26

2014-08-01 14:06:45

2021-12-06 17:21:05

异常报错故障

2020-10-18 12:53:29

黑科技网站软件

2020-03-10 07:51:35

面试讽刺标准

2017-01-23 12:40:45

设计演讲报表数据
点赞
收藏

51CTO技术栈公众号