Ubuntu Weekly Recipe

第673回 カーネルのクラッシュ情報を取得する

この記事を読むのに必要な時間:およそ 4 分

Ubuntuにおいてクラッシュダンプシステムとして必要なパッケージ・設定は「linux-crashdump」パッケージにまとまっています。そこでまずはこれをインストールしましょう。

$ sudo apt install linux-crashdump

このインストールの際に,2件ほど質問が表示されます。

図1 kexec-toolsで再起動処理を行うかどうか

図1

最初は「kexec-tools」の設定で,⁠kexec-toolsで再起動処理を行いますか?」というものです。これは通常の再起動処理を行う際,UEFI/BIOSからの再起動(PCだとACPIリブート)を実施せず,kexecでロードしたメモリー上のカーネルを起動するかどうかを確認しています。再起動時間は短くなるものの,ハードウェアの初期化等はスキップされます。一般的なPCにおいて「再起動したい」ときは,だいたい「クリーンな状態から起動し直したい」ケースが多いので,ここは「いいえ」を選んでおくと良いでしょう。サーバー等でカーネル更新によるダウンタイムを短くしたいときには有効な設定です。なお,インストール後も/etc/default/kexecLOAD_KEXECtrueにして再起動すれば,設定を「はい」にしたときと同じ状態にできます。

図2 クラッシュダンプシステムを有効化するかどうか

図1

次が「kdump-tools」の設定で,クラッシュ発生時にクラッシュダンプシステムを起動するかどうかを問い合わせています。今回はこちらを利用するため「はい」を選んでおいてください。メッセージにもあるように,有効化するためには一度再起動が必要になります。この設定も/etc/default/kdump-toolsUSE_KDUMPを0か1にすることで設定の変更が可能です。

ちなみに上記において,おおよそ追加でインストールされるファイルは次のとおりです。

  • kexec-tools
  • kdump-tools
  • makedumpfile
  • crash

前述したようにkexec-toolsがkexec用にカーネル・initramfsをメモリー上に展開するツールです。kdump-toolsは,このkexec-toolsを利用してクラッシュダンプシステムを起動するために必要な設定・サービスを提供しています。具体的にはブートローダーから,クラッシュシステム用のカーネルパラメーターを設定したり,起動処理の途中でクラッシュシステムをメモリー上にロードしたりする作業です。

makedumpfileは,クラッシュシステム上でクラッシュ前のカーネルメモリー/proc/vmcoreを保存するためのコマンドを提供しています。/proc/vmcoreはとても大きなファイルなので,障害情報として有用なものだけに限定して取り出したほうが良いことが多々あります。そのあたりの処理を担ってくれるのがmakedumpfileです。最後のcrashは,障害情報の内容を確認するためのデバッガーです。もし障害情報の精査を他のマシンで行うなら,インストールしなくてもかまいません。

linux-crashdumpをインストールしたあとは,一度再起動しておく必要があります。次回起動時から,クラッシュダンプシステム用のカーネルメモリーが確保され,そこにシステムがロードされるからです。

実際に再起動したあとは次のコマンドを実行してみましょう。

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-5.11.0-22-generic root=UUID=afa22713-4378-4e8d-b662-496ef2b318d0 ro quiet splash crashkernel=512M-:192M vt.handoff=7

ここでcrashkernel=512M-:192Mがクラッシュシステム用に確保される領域です。

  • メモリーサイズが512MiB以下ならクラッシュシステムはロードしない
  • メモリーサイズが512MiB以上なら,512MiB以降の領域に192MiB予約する

予約した領域は通常のカーネルから利用されることはありません。クラッシュシステムのカーネルとinitramfsがロードされ,クラッシュシステムが起動したときにこの領域が利用されます。

無事にクラッシュシステムの準備が整ったので,次のコマンドを実行して,意図的にpanicさせてみましょう。念のため,アプリケーションは一通り終了させておいてください。

$ echo "c" | sudo tee /proc/sysrq-trigger

おそらく画面が固まり,キーボードやマウスの操作はできなくなるはずです。しばらく待つとスプラッシュスクリーンが表示され,そのうちPC自体が再起動するでしょう。通常のログイン画面が表示されたら,障害情報は収集済みの状態になります。クラッシュダンプシステムは,自動的に障害情報を収集・保存したあとは,再起動するようになっています。つまりPC自体が再起動し,普通に起動したときのようにPCのロゴが表示される時点で,障害情報の収集は完了済みです。

収集された障害情報はApportと同じように,/var/crash以下に保存されています。

$ ls -R /var/crash/
/var/crash/:
202107040335  _usr_bin_seahorse.1000.crash  kdump_lock  kexec_cmd  linux-image-5.11.0-22-generic-202107040335.crash

/var/crash/202107040335:
dmesg.202107040335  dump.202107040335

ここで日付ディレクトリになっているのが,実際に収集したものです。dmesgがpanicが発生したときのカーネルログの内容で,dumpがvmcoreを保存したものです。またLaunchpadに報告できるように,Apportフォーマットのcrashファイルも生成されています。

とりあえずdmesgの中身を見てみましょう。これだけでどこで問題が起きたかはわかるはずですし,運が良ければ原因までたどり着けます。

(前略)
[ 6262.530024] sysrq: Trigger a crash
[ 6262.530033] Kernel panic - not syncing: sysrq triggered crash
[ 6262.530045] CPU: 3 PID: 111191 Comm: tee Kdump: loaded Tainted: G S       C  E     5.11.0-22-generic #23-Ubuntu
[ 6262.530049] Hardware name: Panasonic Corporation CF-AX2QEBJR/CFAX2-1L, BIOS V1.11L14 10/16/2012
[ 6262.530051] Call Trace:
[ 6262.530056]  show_stack+0x52/0x58
[ 6262.530063]  dump_stack+0x70/0x8b
[ 6262.530067]  panic+0x101/0x2e3
[ 6262.530072]  sysrq_handle_crash+0x1a/0x20
[ 6262.530077]  __handle_sysrq.cold+0x48/0x120
[ 6262.530082]  write_sysrq_trigger+0x28/0x40
[ 6262.530086]  proc_reg_write+0x5a/0x90
[ 6262.530091]  ? _cond_resched+0x1a/0x50
[ 6262.530095]  vfs_write+0xc6/0x270
[ 6262.530098]  ksys_write+0x67/0xe0
[ 6262.530101]  __x64_sys_write+0x1a/0x20
[ 6262.530104]  do_syscall_64+0x38/0x90
[ 6262.530107]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 6262.530111] RIP: 0033:0x7f3a4110cc27
[ 6262.530114] Code: 0d 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74 24
[ 6262.530118] RSP: 002b:00007ffeb514fbd8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 6262.530122] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f3a4110cc27
[ 6262.530124] RDX: 0000000000000002 RSI: 00007ffeb514fcc0 RDI: 0000000000000003
[ 6262.530126] RBP: 00007ffeb514fcc0 R08: 0000000000000002 R09: 0000000000000001
[ 6262.530127] R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000002
[ 6262.530129] R13: 00005622844eb4e0 R14: 0000000000000002 R15: 00007f3a411e68a0

今回はteeコマンドで,sysrq-triggerを利用してpanicをさせました。上記だとComm: teeでpanic時のユーザープロセスがteeであることもわかりますし,バックトレースのwrite_sysrq_triggerで,sysrq-triggerに何かを書いたことがわかります。

この収集自体は/usr/sbin/kdump-configが担っています。つまりこのシェルスクリプトの中身を見れば,おおよそ何をやっているかがわかるはずです。また,このスクリプトは通常起動時の,クラッシュカーネルのロードやKernel Oops時のpanic実行(sysctlのkernel.panic_on_oops設定)も担当しています。

次回はこの取得したクラッシュダンプを,crashコマンドとデバッグシンボル付きパッケージを用いてより詳細に解析してみます。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。