こんにちは。サイオステクノロジー OSS サポート担当 金田です。
件数は多くないのですが、カーネルダンプを解析して障害調査をすることがあります。CentOS 系ですと、まだ CentOS5 系が現役のシステムもあり、カーネルダンプの解析のためにお問合せ元の OS バージョンにあわせて環境を作り調査、というのが一般的な流れですが、これは結構手間です。また、OS が古いと crash コマンドの機能に制限があり十分解析できないことがあります。
そこで CentOS7 の crash コマンドで古い OS のカーネルダンプが読み込ませられれば、環境作りの手間が省け、機能が豊富な新しいバージョンの crash コマンドで解析がてきるようになります。今回はその方法をご紹介します。
■kernel-debuginfo 関連のパッケージのインストール
今回は、異なるバージョンの kernel-debuginfo 関連パッケージを一つの環境に複数インストールするという点がポイントになります。ただ、kernel-debuginfo 関連パッケージを yum でインストールすると、次に新しいバージョン (またはリリース) の kernel-debuginfo 関連のパッケージをインストールする際、依存関係から古いパッケージが削除されてしまい、古いバージョン (またはリリース) ではインストールできません。そのため、rpm パッケージをダウンロードして、rpm -i –force でインストールするか、rpm2cpio ~ | cpio -idm 等でファイルを所定の場所にインストールする必要があります。ただし rpm コマンドで kernel-debuginfo 関連のパッケージをインストールした後に、yum で他のパッケージのインストールやアップデートをする際「警告: RPMDB は yum 以外で変更されました。」といった警告が出るので、これが気になる場合は rpm2cpio でインストールしたほうが良いでしょう。
では、CentOS5/6 の kernel-debuginfo 関連のパッケージをダウンロードできるように、yum レポジトリの設定をしておきます。/etc/yum.repos.d/CentOS-Debuginfo.repo に以下の設定を追加します。
[base-debuginfo6] name=CentOS-6 - Debuginfo baseurl=https://debuginfo.centos.org/6/$basearch/ gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Debug-6 enabled=0 [base-debuginfo5] name=CentOS-5 - Debuginfo baseurl=https://debuginfo.centos.org/5/$basearch/ gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Debug-5 enabled=0
今回 crash コマンドで読み込むカーネルダンプのバージョンに合わせて、CentOS5 用は以下のパッケージをダウンロードしています。
※504.el6 の部分は対応する kernel のリリース番号に合わせてください。
# yum --enablerepo=base-debuginfo5 --downloadonly --downloaddir=. install kernel-debuginfo-2.6.18-308.el5 kernel-debug-debuginfo-2.6.18-308.el5
(略)
====================================================================================================
Package アーキテクチャー
バージョン リポジトリー 容量
====================================================================================================
インストール中:
kernel-debug-debuginfo x86_64 2.6.18-308.el5 base-debuginfo5 186 M
kernel-debuginfo x86_64 2.6.18-308.el5 base-debuginfo5 180 M
依存性関連でのインストールをします:
kernel-debuginfo-common x86_64 2.6.18-308.el5 base-debuginfo5 35 M
トランザクションの要約
====================================================================================================
インストール 2 パッケージ (+1 個の依存関係のパッケージ)
総ダウンロード容量: 401 M
インストール容量: 1.3 G
Background downloading packages, then exiting:
(1/3): kernel-debuginfo-2.6.18-308.el5.x86_64.rpm | 180 MB 00:09:28
(2/3): kernel-debug-debuginfo-2.6.18-308.el5.x86_64.rpm | 186 MB 00:09:35
(3/3): kernel-debuginfo-common-2.6.18-308.el5.x86_64.rpm | 35 MB 00:02:10
----------------------------------------------------------------------------------------------------
合計 588 kB/s | 401 MB 00:11:39
exiting because "Download Only" specified
CentOS6 用は以下のパッケージをダウンロードしています。
# yum --enablerepo=base-debuginfo6 --downloadonly --downloaddir=. install kernel-debuginfo-2.6.32-504.el6 kernel-debug-debuginfo-2.6.32-504.el6 (以下省略)
■crash コマンドでの読み込み結果
ファイルは上で紹介した方法で配置したとして、実際に crash コマンドで読み込んでみます。まずは CentOS5 のクラッシュダンプから。
# crash /usr/lib/debug/lib/modules/2.6.18-308.el5/vmlinux el5/vmcore
crash 7.1.9-2.el7
(略)
GNU gdb (GDB) 7.6
(略)
KERNEL: /usr/lib/debug/lib/modules/2.6.18-308.el5/vmlinux
DUMPFILE: vmcore
CPUS: 8
DATE: Fri Dec 8 13:01:56 2017
UPTIME: 159 days, 05:17:15
LOAD AVERAGE: 1.62, 2.44, 1.96
TASKS: 1676
NODENAME: xxxxxxxx
RELEASE: 2.6.18-308.el5
VERSION: #1 SMP Fri Jan 27 17:17:51 EST 2012
MACHINE: x86_64 (3492 Mhz)
MEMORY: 31.5 GB
PANIC: "Unable to handle kernel NULL pointer dereference at 0000000000000000 RIP: "
PID: 2382
COMMAND: "yyyyy"
TASK: ffff8101ca570100 [THREAD_INFO: ffff810125e04000]
CPU: 5
STATE: TASK_TRACED (PANIC)
crash> bt
PID: 2382 TASK: ffff8101ca570100 CPU: 5 COMMAND: "xxxxx"
#0 [ffff810125e05b40] crash_kexec at ffffffff800b0938
#1 [ffff810125e05bc8] elf_core_dump at ffffffff8008a7ad
#2 [ffff810125e05c00] __die at ffffffff80065137
#3 [ffff810125e05c40] do_page_fault at ffffffff80067484
#4 [ffff810125e05d30] error_exit at ffffffff8005dde9
[exception RIP: elf_core_dump+2212]
RIP: ffffffff8008a7ad RSP: ffff810125e05de0 RFLAGS: 00010046
RAX: 0000000000000000 RBX: ffff810647062700 RCX: 0000000000000000
RDX: ffff810125e05e60 RSI: 0000000000000080 RDI: 0000000000000000
RBP: ffff810125e05ea0 R8: 0000000000000008 R9: 0000000000000038
R10: ffffffff804df3f8 R11: 0000000000008001 R12: ffff810125e05e40
R13: 0000000000000000 R14: 0000000000000001 R15: ffff810647061420
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#5 [ffff810125e05e08] do_notify at ffffffff800c58e3
#6 [ffff810125e05ee8] utrace_report_syscall at ffffffff800c564d
#7 [ffff810125e05f38] syscall_trace_leave at ffffffff8006e210
#8 [ffff810125e05f48] int_very_careful at ffffffff8005d312
RIP: 00002b3916a022e0 RSP: 00007fff8345fc28 RFLAGS: 00000246
RAX: 0000000000000008 RBX: 00007fff83460c60 RCX: ffffffffffffffff
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00002b391ca47655
RBP: 00007fff83460d98 R8: 00007fff83460c94 R9: 2e2e2e2e2e2e2e2e
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000040
R13: 000000000000012c R14: 00002b391ca452d0 R15: 00002b391ca452ba
ORIG_RAX: 0000000000000002 CS: 0033 SS: 002b
無事読み込めました。次に CentOS6 のカーネルダンプを読み込んでみます。
# crash /usr/lib/debug/lib/modules/2.6.32-504.el6.x86_64/vmlinux el6/vmcore
crash 7.1.9-2.el7
(略)
GNU gdb (GDB) 7.6
(略)
KERNEL: /usr/lib/debug/lib/modules/2.6.32-504.el6.x86_64/vmlinux
DUMPFILE: vmcore [PARTIAL DUMP]
CPUS: 8
DATE: Fri Dec 1 20:49:20 2017
UPTIME: 29 days, 11:49:39
LOAD AVERAGE: 2.15, 2.31, 2.19
TASKS: 948
NODENAME: xxxxxxx
RELEASE: 2.6.32-504.el6.x86_64
VERSION: #1 SMP Wed Oct 15 04:27:16 UTC 2014
MACHINE: x86_64 (2993 Mhz)
MEMORY: 15.8 GB
PANIC: "BUG: unable to handle kernel paging request at 00000000001118c0"
PID: 672
COMMAND: "yyyyyy"
TASK: ffff8801ae6f6aa0 [THREAD_INFO: ffff88036adac000]
CPU: 2
STATE: TASK_RUNNING (PANIC)
crash> bt
PID: 672 TASK: ffff8801ae6f6aa0 CPU: 2 COMMAND: "yyyyyy"
#0 [ffff88036adad860] machine_kexec at ffffffff8103b68b
#1 [ffff88036adad8c0] crash_kexec at ffffffff810c9852
#2 [ffff88036adad990] oops_end at ffffffff8152e070
#3 [ffff88036adad9c0] no_context at ffffffff8104c80b
#4 [ffff88036adada10] __bad_area_nosemaphore at ffffffff8104ca95
#5 [ffff88036adada60] bad_area at ffffffff8104cbbe
#6 [ffff88036adada90] __do_page_fault at ffffffff8104d36f
#7 [ffff88036adadbb0] do_page_fault at ffffffff8152ffbe
#8 [ffff88036adadbe0] page_fault at ffffffff8152d375
[exception RIP: ext4_htree_store_dirent+168]
RIP: ffffffffa00b6108 RSP: ffff88036adadc98 RFLAGS: 00010202
RAX: 00000000001118c8 RBX: 00000000316d5ea6 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff88038708404b RDI: ffff88015a111931
RBP: ffff88036adadcd8 R8: 0000000000000246 R9: ffff88015a1118c0
R10: 0000000003030303 R11: 000000003f1a38ca R12: ffff88015a1118c0
R13: ffff88015a126500 R14: ffff880387084000 R15: ffff88015a126500
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#9 [ffff88036adadce0] htree_dirblock_to_tree at ffffffffa00c4b28 [ext4]
#10 [ffff88036adadd50] ext4_htree_fill_tree at ffffffffa00c559a [ext4]
#11 [ffff88036adaddf0] ext4_readdir at ffffffffa00b63c7 [ext4]
#12 [ffff88036adadee0] vfs_readdir at ffffffff811a4c00
#13 [ffff88036adadf30] sys_getdents at ffffffff811a4d89
#14 [ffff88036adadf80] system_call_fastpath at ffffffff8100b072
RIP: 00007f458d3a5e65 RSP: 00007fff17e22a00 RFLAGS: 00010202
RAX: 000000000000004e RBX: ffffffff8100b072 RCX: 0000000000000051
RDX: 0000000000008000 RSI: 00007f458fe6dee0 RDI: 0000000000000004
RBP: ffffffffffffffa8 R8: 00007f458fe6dee0 R9: 3030303030303030
R10: 2e5a443030303030 R11: 0000000000000246 R12: 00007fff17e22bc0
R13: 00007f458fe6dee0 R14: 0000000000000002 R15: 00007f458fe6deb0
ORIG_RAX: 000000000000004e CS: 0033 SS: 002b
crash>
こちらも無事に読み込めました。
■最後に
若干トリッキーではありますが、CentOS7 の環境でバージョンの異なるカーネルダンプを読み込む方法をご紹介しました。rpm -ql で確認するとわかりますが、kernel-debuginfo 関連のパッケージは、バージョン+リリース番号でディレクトリが作られていて、各バージョン+リリース番号が共存可能な形で提供されているため実施可能な方法でした。kernel 以外の debuginfo はバージョン単位までしかディレクトリが作られていないので、リリース番号が異なる場合の共存はできないようです。crash コマンドでどのように解析するかといったお話はまた機会があればご紹介したいと思います。

