linux kdump 分析工具,kdump简介

分析操作系统crash或hang的原因,需要用到kernel dump。Linux系统用来捕捉kernel dump的工具是kdump。

kdump的原理是启动一个特殊的dump-capture kernel把系统内存里的数据保存到文件里,为什么需要一个特殊的dump-capture kernel呢?因为原来的kernel已经出问题了,发生crash或hang了。

Dump-capture kernel 既可以是独立的,也可以与系统内核集成在一起–这需要硬件支持relocatable kernel才行。在X86_64系统上RHEL6/7和SLES11/12缺省都是与系统内核集成在一起的。

kdump工作的过程如下:

系统内核启动的时候,要给dump-capture kernel预留一块内存空间;

内核启动完成后,kdump service执行 kexec -p 命令把dump-capture kernel载入预留的内存里;

然后,如果系统发生crash,会自动reboot进入dump-capture kernel,dump-capture kernel只使用自己的预留内存,确保其余的内存数据不会被改动,它的任务是把系统内存里的数据写入到dump文件,比如/var/crash/vmcore,为了减小文件的大小,它会通过makedumpfile(8)命令对内存数据进行挑选和压缩;

dump文件写完之后,dump-capture kernel自动reboot。

预留内存

配置kdump的一个关键环节是预留内存。预留的内存是有特殊要求的,它必须是连续的,在老的系统上比如SLES11还要求内存物理地址低于4GB(SLES12无此要求,因为新kernel允许使用高位内存)。可供预留的内存取决于硬件配置,BIOS/firmware占用的内存是不能预留的,EFI经常占用很多内存,I/O卡也要占用内存,在引导过程中都能看到:

BIOS占用的:

<6>[ 0.000000] BIOS-e820: 0000000000000000 - 0000000000092000 (usable)

<6>[ 0.000000] BIOS-e820: 0000000000092000 - 0000000000094000 (reserved)

<6>[ 0.000000] BIOS-e820: 0000000000094000 - 00000000000a0000 (usable)

<6>[ 0.000000] BIOS-e820: 0000000000100000 - 000000006bbfd000 (usable)

<6>[ 0.000000] BIOS-e820: 000000006bbfd000 - 000000006cbfd000 (reserved)

<6>[ 0.000000] BIOS-e820: 000000006cbfd000 - 000000006cbfe000 (usable)

<6>[ 0.000000] BIOS-e820: 000000006cbfe000 - 000000006cc7f000 (reserved)

<6>[ 0.000000] BIOS-e820: 000000006cc7f000 - 00000000718ff000 (usable)

<6>[ 0.000000] BIOS-e820: 00000000718ff000 - 00000000725ff000 (reserved)

<6>[ 0.000000] BIOS-e820: 00000000725ff000 - 00000000735ff000 (ACPI NVS)

<6>[ 0.000000] BIOS-e820: 00000000735ff000 - 00000000737ff000 (ACPI data)

<6>[ 0.000000] BIOS-e820: 00000000737ff000 - 000000007b800000 (usable)

<6>[ 0.000000] BIOS-e820: 0000000080000000 - 0000000090000000 (reserved)

<6>[ 0.000000] BIOS-e820: 0000000100000000 - 0000018080000000 (usable)

EFI占用的:

<6>[ 0.000000] EFI: mem04: type=7, attr=0xf, range=[0x0000000000100000-0x0000000001000000) (15MB)

<6>[ 0.000000] EFI: mem05: type=2, attr=0xf, range=[0x0000000001000000-0x0000000002364000) (19MB)

<6>[ 0.000000] EFI: mem06: type=7, attr=0xf, range=[0x0000000002364000-0x0000000010000000) (220MB)

<6>[ 0.000000] EFI: mem07: type=3, attr=0xf, range=[0x0000000010000000-0x000000001006b000) (0MB)

<6>[ 0.000000] EFI: mem08: type=7, attr=0xf, range=[0x000000001006b000-0x0000000024f57000) (334MB)

<6>[ 0.000000] EFI: mem09: type=2, attr=0xf, range=[0x0000000024f57000-0x0000000040100000) (433MB)

<6>[ 0.000000] EFI: mem10: type=4, attr=0xf, range=[0x0000000040100000-0x0000000040180000) (0MB)

<6>[ 0.000000] EFI: mem11: type=7, attr=0xf, range=[0x0000000040180000-0x0000000069352000) (657MB)

<6>[ 0.000000] EFI: mem12: type=4, attr=0xf, range=[0x0000000069352000-0x00000000693d4000) (0MB)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

BIOS占用的:

<6>[0.000000]BIOS-e820:0000000000000000-0000000000092000(usable)

<6>[0.000000]BIOS-e820:0000000000092000-0000000000094000(reserved)

<6>[0.000000]BIOS-e820:0000000000094000-00000000000a0000(usable)

<6>[0.000000]BIOS-e820:0000000000100000-000000006bbfd000(usable)

<6>[0.000000]BIOS-e820:000000006bbfd000-000000006cbfd000(reserved)

<6>[0.000000]BIOS-e820:000000006cbfd000-000000006cbfe000(usable)

<6>[0.000000]BIOS-e820:000000006cbfe000-000000006cc7f000(reserved)

<6>[0.000000]BIOS-e820:000000006cc7f000-00000000718ff000(usable)

<6>[0.000000]BIOS-e820:00000000718ff000-00000000725ff000(reserved)

<6>[0.000000]BIOS-e820:00000000725ff000-00000000735ff000(ACPINVS)

<6>[0.000000]BIOS-e820:00000000735ff000-00000000737ff000(ACPIdata)

<6>[0.000000]BIOS-e820:00000000737ff000-000000007b800000(usable)

<6>[0.000000]BIOS-e820:0000000080000000-0000000090000000(reserved)

<6>[0.000000]BIOS-e820:0000000100000000-0000018080000000(usable)

EFI占用的:

<6>[0.000000]EFI:mem04:type=7,attr=0xf,range=[0x0000000000100000-0x0000000001000000)(15MB)

<6>[0.000000]EFI:mem05:type=2,attr=0xf,range=[0x0000000001000000-0x0000000002364000)(19MB)

<6>[0.000000]EFI:mem06:type=7,attr=0xf,range=[0x0000000002364000-0x0000000010000000)(220MB)

<6>[0.000000]EFI:mem07:type=3,attr=0xf,range=[0x0000000010000000-0x000000001006b000)(0MB)

<6>[0.000000]EFI:mem08:type=7,attr=0xf,range=[0x000000001006b000-0x0000000024f57000)(334MB)

<6>[0.000000]EFI:mem09:type=2,attr=0xf,range=[0x0000000024f57000-0x0000000040100000)(433MB)

<6>[0.000000]EFI:mem10:type=4,attr=0xf,range=[0x0000000040100000-0x0000000040180000)(0MB)

<6>[0.000000]EFI:mem11:type=7,attr=0xf,range=[0x0000000040180000-0x0000000069352000)(657MB)

<6>[0.000000]EFI:mem12:type=4,attr=0xf,range=[0x0000000069352000-0x00000000693d4000)(0MB)

为dump-capture kernel预留内存的方法是在kernel command line中加入如下参数:

crashkernel=size[@offset]

需要预留多少内存呢?

RHEL从6.2开始可以使用”crashkernel=auto”,让内核自行计算,如果有问题才手工指定。

SLES12则可以用”kdumptool calibrate”命令计算推荐值,具体方法参见SUSE DOC: Calculating crashkernel Allocation Size 。

更老的系统上需要根据系统总内存手工计算预留内存的大小,参考值请自行搜索。

不幸的是,确实有些系统存在无法预留足够内存的情况,如果dump-capture kernel需要的内存比较多,而硬件配置又比较复杂导致可用的连续内存不足,就有可能发生。这在老内核上更常见,而新内核允许使用高位内存就好多了。

通常RHEL 6.X最大建议768MB,实际上代码中最大的限制是896MB,但实际经验中800M以上就会有各种问题。

reserve_crashkernel()

...

0585 if (crash_size >= KEXEC_RESERVE_UPPER_LIMIT) {

0586 pr_info("crashkernel reservation failed. "

0587 "specified size is too big.\n");

0588 return;

0589 }

#define KEXEC_RESERVE_UPPER_LIMIT (896 * 1024 * 1024)

1

2

3

4

5

6

7

8

9

reserve_crashkernel()

...

0585if(crash_size>=KEXEC_RESERVE_UPPER_LIMIT){

0586pr_info("crashkernel reservation failed. "

0587"specified size is too big.\n");

0588return;

0589}

#define KEXEC_RESERVE_UPPER_LIMIT (896 * 1024 * 1024)

kdump的性能

计算机的内存越来越大,kernel dump也越来越大,保存dump文件的时间也越来越长,为了提高速度,kdump的配置可以进行调整。

1,多CPU

缺省情况下dump-capture kernel只使用一个CPU,有时使用多个CPU会有帮助。这可以通过修改dump-capture kernel 的参数 nr_cpus=1 来实现,怎样修改dump-capture kernel的参数呢?不是在grub中,那里是普通kernel的参数,而是在 /etc/sysconfig/kdump 中,如下所示:

KDUMP_COMMANDLINE_APPEND=”irqpoll nr_cpus=4 …”

2,压缩算法

makedumpfile(8)默认的”-c”参数使用zlib,虽然压缩比很高但是速度很慢,通常低于30MB/s。可以选用速度更快的LZO,虽然压缩比稍微低一点但是速度可达800MB/s,把/etc/kdump.conf中的makedumpfile(8)的”-c”参数换成”-l”即可。

3,排除不需要的内存页

makedumpfile(8)的”-d”参数指定dump level,dump level是一个5-bit的编码,每个bit表示一种可以排除的内存页:

1 : Exclude the pages filled with zero.2 : Exclude the non-private cache pages.4 : Exclude all cache pages.8 : Exclude the user process data pages.16 : Exclude the free pages.

一般默认dump level是31,即排除以上所有类型的内存页。

参考资料:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值