Win7系统之家 网站地图| TAG标签| RSS订阅| 加入收藏

Linux系统内核崩溃怎么样排查?

  • 浏览:
  • |
  • 更新:

Linux内核假如奔溃,将致使Linux系统kernel崩溃,我们的电脑还好,若是企业的电脑将导致不小的损失,下面记者就给大伙介绍下Linux系统内核崩溃的排查办法,一块儿认识下吧。

1.概述

某年某月某日某项目的线上分布式文件系统服务器多台linux系统kernel崩溃,严重干扰了某项目对外提供服务的能力,在公司导致了不小影响。通过排查线上问题基本确定了是因为linux内核panic导致是什么原因,通过两个阶段的问题排查,基本上确定了linux内核panic是什么原因。排查问题的主要方法就是网上查找资料和依据内核错误日志剖析并且架构条件重现。本文档就是对自己在整个问题排查过程中的总结。

2.第一阶段

由于刚出现问题的时候大伙都比较紧急,天天加班都非常晚,也拟定了不少问题重现和定位缘由的计划。我第一阶段连续坚持了两周剖析问题缘由,因为第一阶段自己所做的功能基本上全部形成了详细的剖析文档,所以下面主要总结一下自己在第一阶段都采取了一些哪种手段与到达了什么成效。

第一阶段自己也分了几步走,当然最早想到的是重现线上的现象,所以我第一查询了线上的内核错误日志,依据日志显示主如果qmgr和master两个进程致使的内核panic(至少日志信息是这么提示的)。当然还结合当时服务器的现象,load比较高,对外不可以提供服务。所以自己第一想到的就是通过写程序模拟不断发送邮件(由于qmgr和master进程都与发送邮件有关的进程),当程序运行起来的时候,自己小小的激动了一下,就是load上去了,服务器的对外服务能力变慢了(ssh登录),当时的线上接近线上现象,但后面内核一直没panic,就算频率在快,而且内核也没什么错误信息。后面日渐的就排除去这个缘由。

由于出错的服务器都安装了分布式文件系统,大伙就怀疑是因为分布式文件系统致使了内核panic,但通过察看业务监控信息发现那个时段分布式文件系统没什么特殊的信息,而且数据流更不是非常大。不过我还是用几台虚拟机安装了分布式文件系统,并且写了一个java程序并且持续的通过分布式文件系统推广客户端写入文件到分布式文件系统集群,同时也把邮件发送程序启动,尽可能模拟线上的环境,跑了不少次很久也没出现线上的现象,所以也没什么更好的方法去重现线上的现象了。

因为重现现象失败了,所以只有依据内核的错误信息直接去剖析缘由了。剖析步骤非常简单,第一找到出错的错误代码,然后剖析上下文有关的代码,剖析的详细过程在去年的文档也体现出来了。

依据代码的剖析和网上类似的bug基本上定位就是计算cpu调度的时间溢出,致使watchdog进程抛出panic错误,内核就挂起了。依据剖析定位是什么原因,我又通过修改内核代码去架构时间溢出的条件,就是通过内核模块去修改系统调用时间的计数值,修改是成功了,可惜内核也直接死掉了。所以直接修改内核代码来重现也失败了。

后面也陆续咨询了不少公司外面熟知内核的技术职员,他们依据大家提供的信息业给出了我们的剖析,但也没非常不错的重现办法和确切的定位错误缘由,而且不一样的人给出的结论差异也比较大。

所以第一个阶段连续坚持跟踪这个问题2-3周的时间也没一个确切的结果。

3.第二阶段

新的一年开始了,第一天又开始筹备跟踪这个问题了。刚开始也拟定了简单的计划,我对我们的计划就是天天5-8点剖析定位内核问题,当然也顺便学习内核有关常识。

这一次刚开始自己便换了一个角度去考虑问题,去年是基于单台服务器去剖析内核日志错误信息,已经没什么好的方法了。所以筹备同时剖析所有出错服务器的日志(幸好以前找运维要了所有出错服务器的内核日志并且保存下来了,不然如何死的都不了解),找出他们的一同点。第一他们的一同点就是出现了trace子系统打印的警告信息Delta way too big!。。的信息,但依据有关信息,这个是不会致使linux系统挂起的。而且确实大家线上的服务器并非全部都ssh不上去,不过还是在RedHat官方网站找到类似的bug(url:

https: //access.redhat.com/knowledge/solutions/70051),并且给出知道决策略。bug信息和解决方法如下:

why kernel is throwing Delta way too big out with

WARNING: at kernel trace ring_buffer,c:1988 rb_reserve_next_event+0x2ce/0370 messages

0 Issue kernel is throwing Delta way too big out with kernel oops on server

Environment(环境)

Red Hat Enterprise Linux 6 service pack 1

Resolution(解决方法)

The warning Delta way too big warning might appear on a system with unstable shed clock right after the system is resumed and tracingwas enabled during the suspend.

Since its not realy bug, and the unstable sched clock is working fast and reliable otherwise, We suggested to keep using the sched clock in any case and just to make note in the warning itself.or disables tracing by #echo 0 》 /sys/kernel/debug/tracing/tracing_on

Root Cause(根本缘由) this case was ftrace involved ftrace due to teh call to ftrace_raw_event_power_end (debugfs is mounted and ftrace loaded in this case), they are to do with problems calculating a time stamp for a ring buffer entry.

Message comes from here and appears to be indicating problems with time stability.

1966 static int

1967 rb_add_time_stamp(struct ring_buffer_per_cpu *cpu_buffer,

1968 u64 *ts, u64 *delta)

1969 {

1970 struct ring_buffer_event *event;

1971 static int once;

1972 int ret;

1973

1974 if (unlikely(*delta 》 (1ULL 《《 59) !once++)) {

1975 int local_clock_stable = 1;

1976 #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK

1977 local_clock_stable = sched_clock_stable;

1978 #endif

1979 printk(KERN_WARNING Delta way too big! %llu

1980 ts=%llu write stamp = %llu\n%s,

1981 (unsigned long long)*delta,

1982 (unsigned long long)*ts,

1983 (unsigned long long)cpu_buffer-》write_stamp,

1984 local_clock_stable ? :

1985 If you just came from a suspend/resume,\n

1986 please switch to the trace global clock:\n

1987 echo global 》 /sys/kernel/debug/tracing/trace_clock\n);

1988 WARN_ON(1);

This called from rb_reserve_next_event() here.

2122 /*

2123 * Only the first commit can update the timestamp.

2124 * Yes there is a race here. If an interrupt comes in

2125 * just after the conditional and it traces too, then it

2126 * will also check the deltas. More than one timestamp may

2127 * also be made. But only the entry that did the actual

2128 * commit will be something other than zero.

2129 */

2130 if (likely(cpu_buffer-》tail_page == cpu_buffer-》commit_page

2131 rb_page_write(cpu_buffer-》tail_page) ==

2132 rb_commit_index(cpu_buffer))) {

2133 u64 diff;

2134

2135 diff = ts - cpu_buffer-》write_stamp;

2136

2137 /* make sure this diff is calculated here */

2138 barrier();

2139

2140 /* Did the write stamp get updated already? */

2141if (unlikely(ts 《 cpu_buffer-》write_stamp))

2142 goto get_event;

2143

2144 delta = diff;

2145 if (unlikely(test_time_stamp(delta))) {

2146

2147 commit = rb_add_time_stamp(cpu_buffer, ts, delta); 《- HERE

This has to do with time stamping for ring buffer entries.

通过上面的信息可以看出,其实和我去年剖析的代码和方法完全相同,只不过判断缘由方面我不敢确定,毕竟重现不了,只能是推断。

相关推荐