Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
適用先 openSUSE Leap 15.7

18 Kexec と Kdump Edit source

Kexec は現在動作中のカーネルから他のカーネルを高速に起動するための仕組みです。これにより、ハードウエアの初期化を行わず、高速にシステムを再起動することができます。必要であれば、システムがクラッシュした際、もう 1 つのカーネルを起動することもできます。

18.1 概要 Edit source

Kexec を使用することで、ハードウエアによる再起動を行うことなく、別のカーネルを起動することができるようになります。このツールは、下記のような用途で使用されます:

  • 高速な再起動

    システムを頻繁に再起動する必要があるような場合、 Kexec は時間をかなり削減できるようになります。

  • 不正なファームウエアやハードウエアの回避

    コンピュータのハードウエアは複雑な構造であり、システムの起動時に深刻な問題が発生する場合があります。このような場合、すぐにハードウエアを交換できればよいのですが、そうは行かない場合があります。 Kexec では、ハードウエアの初期化が完了した状態から、特定の制御環境下に移行することができます。これにより、システムの起動が失敗するようなリスクを抑えることができます。

  • カーネルがクラッシュした際のダンプの保存

    Kexec は物理メモリ内の情報を保持して動作します。そのため、 本番用 のカーネルに何らかの障害が発生した場合、 情報採取用 のカーネル (限られたメモリ範囲内だけで動作する追加のカーネル) を起動することで、障害情報を保存することができるようになります。保存されたイメージは、後から解析用に使用することができます。

  • GRUB 2 の設定を使用しない起動

    Kexec 経由でカーネルを起動した場合、ブートローダの段階は省略されます。通常はブートローダの設定が誤っていると、起動の処理を行うことができなくなりますが、 Kexec を使用することで、ブートローダの設定に依存せずに起動することができるようになります。

18.2 必要なパッケージ Edit source

openSUSE® Leap で Kexec を使用すると、再起動を高速化したり潜在的なハードウエア問題を回避したりすることができます。 Kexec を使用するには、 kexec-tools パッケージをインストールしてください。このパッケージには kexec-bootloader というスクリプトが含まれていますが、これはブートローダの設定からカーネルのコマンドラインオプションを読み出し、そのコマンドラインオプションを利用して新しいカーネルを起動することができます。

カーネルのクラッシュ時にデバッグ情報を取得する環境を設定したい場合は、 makedumpfile パッケージをインストールしておいてください。

openSUSE Leap での Kdump の使用方法は、 YaST の Kdump モジュールで設定することができます。 YaST モジュールを使用する場合は、 yast2-kdump パッケージをインストールしておいてください。

18.3 Kexec の内部構造 Edit source

Kexec で最も重要なコンポーネントは /sbin/kexec です。 Kexec でカーネルを読み込む際、 2 種類の方法で行うことができます:

  • 通常の再起動と同様に、本番用のカーネルのアドレス領域にカーネルを読み込む方法:

    # kexec -l カーネルイメージ

    読み込んだあと、そのカーネルを実行するには、 kexec -e と入力して実行します。

  • メモリ内の専用の領域にカーネルを読み込む方法:

    # kexec -p カーネルイメージ

    このカーネルは、システムがクラッシュした際に自動的に起動されます。

システムがクラッシュした際、本番用のカーネルのデータを保持したまま、もう 1 つのカーネルを起動したい場合は、システムメモリ内に専用の領域を用意する必要があります。その領域は常に空けておかなければならないものであることから、この専用領域には本番用のカーネルが読み込まれることはありません。この領域は情報採取用のカーネルが使用するもので、このような仕組みによって、本番用のカーネルのメモリページを保持させることができるようになっています。

このような領域を予約するには、本番用のカーネルの起動コマンドライン内に、 crashkernel というオプションを追加します。 crashkernel で必要な値を判断するには、 18.4項 「crashkernel 割り当てサイズの計算」 に書かれた手順に従ってください。

なお、上記のパラメータは情報採取用のカーネルのパラメータではありません。情報採取用のカーネルでは Kexec を使用しません。

情報採取用のカーネルは専用の領域に読み込まれ、カーネルがクラッシュするのを待ちます。いったんクラッシュが発生すると、 Kdump は情報採取用のカーネルに制御を移します。これは、クラッシュした時点で、元のカーネルは信頼できる状態ではなくなるためです。これはつまり、 Kdump 自身も失敗する可能性があることを示しています。

情報採取用のカーネルを読み込むには、カーネルの起動パラメータを含める必要があります。ほとんどの場合、初期 RAM ファイルシステムを起動時に使用します。初期 RAM ファイルシステムを指定するには、 --initrd = ファイル名 のようなオプションを指定します。なお、 --append = コマンドライン のように指定すると、起動するほうのカーネルのコマンドラインを設定することができます。

なお、本番用のカーネルで指定していたコマンドラインを含めておく必要があります。このような場合は、 --append = "$(cat /proc/cmdline)" のように入力して実行することで、既存のコマンドラインをそのまま受け渡すことができます。また、オプションを追加したい場合は、 --append = "$(cat /proc/cmdline) オプション" のようにして追加のオプションを指定してもかまいません。

たとえば、 /boot/vmlinuz-6.4.0-150600.9-default というカーネルイメージファイルに対して、現在動作中のカーネルに指定しているものと同じ /boot/initrd ファイルを使用するように指定したい場合は、下記のようなコマンドになります:

#  kexec -l /boot/vmlinuz-6.4.0-150600.9-default \
 --append="$(cat /proc/cmdline)" --initrd=/boot/initrd

読み込んでおいたカーネルはいつでも解放することができます。 -l オプションで読み込んでおいたカーネルを解放したい場合は、 kexec -u コマンドを実行してください。また、 -p オプションで読み込んでおいたカーネルの場合は、 kexec -p -u コマンドを実行してください。

18.4 crashkernel 割り当てサイズの計算 Edit source

Kexec で情報採取用のカーネルを起動する 場合、このカーネル用のメモリ領域を割り当てておく必要があります。割り当てるべきサイズはコンピュータのハードウエア設定によって異なりますので、あらかじめ指定しておく必要があります。

割り当てるべきサイズは、お使いのコンピュータのハードウエアアーキテクチャによっても異なります。それぞれ下記の手順をお読みのうえ、必要なサイズを判断してください。

手順 18.1: AMD64/Intel 64 でのサイズの割り当て
  1. コンピュータに対する基礎値を得るには、端末内で下記のコマンドを入力し実行します:

    # kdumptool calibrate
    Total: 49074
    Low: 72
    High: 180
    MinLow: 72
    MaxLow: 3085
    MinHigh: 0
    MaxHigh: 45824

    それぞれの値はメガバイト単位です。

  2. 上記の Low および High の値を記録しておきます。

    注記
    注記: LowHigh の値の意味について

    AMD64/Intel 64 コンピュータの場合、 High は利用可能な全てのメモリを予約する意味になり、 Low は DMA32 ゾーン内のメモリ (つまり 4 GB 以下の領域) を予約する意味になります。

    SIZE_LOW は 32 ビットのみに対応したデバイスで必要なメモリ量を表します。カーネルは DMA32 のバウンスバッファに対して 64M を割り当てますが、お使いのサーバ内に 32 ビットのみに対応したデバイスが存在しない場合は、 SIZE_LOW の値は既定の 72M で問題なく動作するはずです。ただし、 NUMA マシンの場合は例外で、より多くの Low が必要となる場合があります。そのため、通常のカーネルの割り当てで Low メモリを使用しないようにするため、 Kdump カーネルのパラメータに numa=off を設定してもかまいません。

  3. 上記の手順の High の値に、お使いのコンピュータに接続されている LUN カーネルパス (ストレージデバイスのパス数) を元にした値を足します。具体的には、メガバイト単位で下記のような計算を行います:

    SIZE_HIGH = 推奨値 + (LUN_数 / 2)

    上記の数式に当てはめるべき値は下記のとおりです:

    • SIZE_HIGH: High の計算結果です。

    • RECOMMENDATION: kdumptool calibrate で表示された High の値です。

    • LUNs: お使いのコンピュータで作成する予定の LUN カーネルパス数の最大値を指定します。マルチパスデバイスについては無視されるため、数から除外してください。お使いのシステムで利用可能な 現在の LUN 数を取得するには、下記のようなコマンドを入力して実行します:

      >  cat /proc/scsi/scsi | grep Lun | wc -l
  4. お使いのデバイスに対応するドライバが DMA32 ゾーン内に多数の予約領域を作成する場合は、 Low の値も調整する必要があります。しかしながら、この値は簡単に計算できるものではありません。正しい値を得るには、試行錯誤を繰り返す必要があります。

    まずは Low の値を kdumptool calibrate で出力された値から試してみてください。

  5. あとは値を正しい場所に設定します。

    カーネルのコマンドラインを直接変更する場合:

    お使いのブートローダの設定で、カーネルオプションに下記を追加してください:

    crashkernel=SIZE_HIGH,high crashkernel=SIZE_LOW,low

    SIZE_HIGHSIZE_LOW の値は、それぞれ上記の手順で算出もしくは試行錯誤した結果を入力してください。また、末尾には M (メガバイトの意味です) を付与してください。

    たとえば下記のようになります:

    crashkernel=36M,high crashkernel=72M,low
    YaST GUI を使用している場合:

    Kdump の低メモリLow の値を入力してください。

    Kdump の高メモリHigh の値を入力してください。

    YaST のコマンドラインインターフェイスを使用している場合:

    下記のコマンドを入力して実行してください:

    # yast kdump startup enable alloc_mem=LOW,HIGH

    ここで、 LOW には Low の値を、 HIGH には High の値をそれぞれ入力してください。

ヒント
ヒント: IBM Z における未使用および無効化された CCW デバイスの除外について

利用可能なデバイスの数にもよりますが、 crashkernel カーネルパラメータで指定したメモリ量が不足する場合があります。不足した場合は、メモリを増やす代わりに、カーネル側で見えるデバイスの量を制限することができます。これにより、 crashkernel の設定で必要なメモリ量を減らすことができます。

  1. デバイスを無視したい場合は、 cio_ignore ツールを利用することで、現時点で有効化されているデバイスや使用しているデバイスを除き、それ以外の全てのデバイスを無視する設定を生成することができます。

    > sudo cio_ignore -u -k
    cio_ignore=all,!da5d,!f500-f502

    cio_ignore -u -k と入力して実行すると、ブラックリスト設定が即時に有効化され、既存のブラックリストを置き換えるようになります。未使用のデバイスが消えることはなく、チャネルサブシステム内で変わらず現れるようになります。ただし、新しいチャネルデバイスを追加 (z/VM 下での CP ATTACH か、 LPAR での動的な I/O 設定変更) すると、それらはブラックリストとして扱われます。この動作をしないようにするには、まず既存の設定を sudo cio_ignore -l を実行して保存し、 cio_ignore -u -k コマンドの実行後にその状態に戻すようにしてください。それ以外の方法としては、生成された設定を通常のカーネルパラメータに追加する方法もあります。

  2. この方法の場合は、 /etc/sysconfig/kdump 内にある KDUMP_CMDLINE_APPEND の値の中に、 cio_ignore パラメータを追加してください。たとえば下記のようになります:

    KDUMP_COMMANDLINE_APPEND="cio_ignore=all,!da5d,!f500-f502"
  3. 設定を反映させるには、 kdump を再起動します:

    systemctl restart kdump.service

18.5 基本的な Kexec の使用方法 Edit source

Kexec を使用するには、まず対応するサービスを有効化し、動作させる必要があります:

  • Kexec のサービスをシステムの起動時に開始するようにするには、下記のように入力して実行します:

    > sudo systemctl enable kexec-load.service
  • Kexec サービスを開始するには、下記のように入力して実行します:

    > sudo systemctl start kexec-load.service

お使いの Kexec 環境が正しく動作していることを確認するには、 Kexec を利用して新しいカーネルを起動してください。ただし、お使いのシステム内には誰もログインしていない状態で、重要なサービスを動作させていない状態であることを確認しておいてください。あとは下記のコマンドを入力して実行します:

systemctl kexec

これにより、あらかじめ読み込んでおいた新しいカーネルが古いカーネルを置き換えて、制御を行うようになります。制御が始まると、通常の起動メッセージが表示されます。新しいカーネルが起動しても、ハードウエアやファームウエアのチェックは省略されます。このとき、何も警告メッセージが表示されないことを確認してください。

ヒント
ヒント: reboot コマンドでの Kexec の使用について

reboot コマンドで通常の再起動を行わず、 Kexec を使用するように設定したい場合は、下記のように入力して実行します:

ln -s /usr/lib/systemd/system/kexec.target /etc/systemd/system/reboot.target

なお、 etc/systemd/system/reboot.target ファイルを削除することで、元の再起動に戻すことができます。

18.6 日々の再起動に対する Kexec の設定方法 Edit source

Kexec は定期的な再起動処理でも使用することができます。たとえばハードウエア検出ルーチンに長い時間がかかるような環境や、起動時の信頼性があまり高くないシステムなどで有用です。

ただし、 Kexec でシステムを再起動する際は、ファームウエアやブートローダを使用しないことに注意してください。ブートローダ側で設定を変更していても、物理的な (Kexec を使用しない) 再起動を行うまで、それらは反映されません。

18.7 基本的な Kexec の設定 Edit source

Kdump を使用することで、カーネルのダンプ情報を保存することができます。これは、カーネルがクラッシュしてしまった場合、その時点のメモリ内容をファイルシステムに保存する機能です。この仕組みにより、カーネルがクラッシュした時点で何が起こっていたのかを調べることができるようになります。これを コアダンプ と呼びます。

Kdump は Kexec と同じ仕組みで動作するものです (詳しくは 第18章 「Kexec と Kdump をお読みください) 。この場合、本番用のカーネルがクラッシュした際に、情報採取用のカーネルを起動します。ただし、 Kexec では本番用のカーネルをそのまま置き換えて動作するのに対して、 Kdump ではクラッシュした本番用のカーネルのメモリを保持し続ける点が異なります。これにより、 Kdump カーネルの環境内から、クラッシュしたカーネルのメモリ領域を保存できることになります。

ヒント
ヒント: ネットワーク経由でのダンプについて

ローカルストレージのサイズが少ないシステムでは、カーネルダンプをネットワーク経由で採取したいこともあります。 Kdump では、 initrd を介してネットワークインターフェイスの設定を行い、それを動作状態に移行させることができます。また、通常の LAN だけでなく VLAN にも対応しています。設定作業は YaST を使用して行うか、 /etc/sysconfig/kdump ファイル内にある KDUMP_NETCONFIG 変数を設定してください。

重要
重要: Kdump での保存先ファイルシステムは設定の時点でマウントしておかなければならない問題について

Kdump を設定する際、採取したダンプイメージの保存先の場所を指定することができます (既定値: /var/crash) 。この保存先は Kdump の設定時点でマウントしておかなければなりません。設定時点でマウントを行っていないと、設定が失敗します。

18.7.1 手作業での Kdump の設定 Edit source

Kdump では設定を /etc/sysconfig/kdump ファイルから読み込みます。お使いのシステムで Kdump を動作させるにあたって、事前の設定は特に必要ありません。 Kdump を既定の設定値のままで動作させたい場合は、下記の手順を実施してください:

  1. 18.4項 「crashkernel 割り当てサイズの計算」 の手順に従って、 Kdump で必要なメモリ量を決定します。決定後、 crashkernel のカーネルパラメータを設定します。

  2. コンピュータを再起動します。

  3. Kdump サービスを有効化します:

    # systemctl enable kdump
  4. 必要であれば /etc/sysconfig/kdump ファイルを編集します。それぞれのオプションの意味について、詳しくはファイル内のコメント (英語) をお読みください。

  5. sudo systemctl start kdump を実行するか、システムを再起動して準備用のスクリプトを実行します。

既定値で Kdump の設定を行ったら、あとは期待通りに動作するかどうかを確認します。まずはお使いのシステム内に誰もログインしていないことと、システム内で重要なサービスを動作させていないことを確認して、下記の手順を実施します:

  1. systemctl isolate rescue.target と入力して実行し、レスキューモードのターゲットに切り替えます。

  2. Kdump サービスを再起動します:

    # systemctl start kdump
  3. 下記のコマンドを入力して実行し、ルートファイルシステム以外の全てのマウントを解除します:

    # umount -a
  4. ルートファイルシステムを読み込み専用モードで再マウントします:

    # mount -o remount,ro /
  5. procfs インターフェイス内の Magic SysRq キー機能を利用して、 カーネルパニック を動作させます:

    # echo c > /proc/sysrq-trigger
重要
重要: カーネルダンプのサイズについて

KDUMP_KEEP_OLD_DUMPS オプションは、カーネルダンプの保存数 (既定値: 5) を指定するためのものです。圧縮を行わない場合、ダンプのサイズは最大で物理メモリ (RAM) のサイズそのものになります。そのため、 /var のパーティションに対しては、十分な空き領域を用意しておいてください。

情報採取用のカーネルが起動して、クラッシュしたほうのカーネルのメモリ状態をファイルシステムに保存します。保存先は KDUMP_SAVEDIR オプションで設定します (既定値: /var/crash) 。 KDUMP_IMMEDIATE_REBOOTyes に設定していると、本番用のカーネルを利用してシステムを自動的に再起動します。再起動が終わったらログインを行い、 /var/crash 内にダンプファイルが作成されていることを確認してください。

18.7.2 YaST での設定 Edit source

YaST で Kdump を設定するには、まず yast2-kdump パッケージをインストールする必要があります。インストール後は rootYaST コントロールセンター 内の システム カテゴリにある カーネル Kdump を起動するか、もしくはコマンドラインで yast2 kdump と入力して実行します。

YaST Kdump モジュールのスクリーンショット
図 18.1: YaST Kdump モジュール: 最初のページ

まずは 起動 ウインドウ内で Kdump の有効化 を選択します。

ウインドウを始めた開いたタイミングで、 Kdump メモリ の値が自動的に設定されます。しかしながら、環境によっては自動生成の値では不十分な場合があります。正しい値を設定するには、 18.4項 「crashkernel 割り当てサイズの計算」 の手順に従って判断を行い、値を入力してください。

重要
重要: ハードウエア変更後の Kdump メモリ の再設定について

コンピュータ内で Kdump を設定し、後からメモリ量や利用可能なハードディスクを変更した場合、 YaST では古い環境での値を表示し続けてしまいます。

この問題を回避するには、 18.4項 「crashkernel 割り当てサイズの計算」 で書かれている手順に従って必要なメモリ量を判断して、 YaST で設定をやり直してください。

左のペイン内で ダンプフィルタリング を選択して、ダンプ内に含めるべきページを選択します。カーネルの問題をデバッグするだけであれば、これらのページは必要ではありません:

  • ゼロ充填のページ

  • キャッシュページ

  • ユーザデータページ

  • フリーページ

ダンプ先 ウインドウでは、ダンプの保存先の種類を選択したあと、保存先の場所を指定します。 FTP や SSH などのネットワークプロトコルを指定した場合は、必要なアクセス情報についても指定する必要があります。

ヒント
ヒント: 他のアプリケーションとのダンプディレクトリ共有について

Kdump のダンプの保存先と他のアプリケーションのダンプ保存先を同じパスに設定することもできます。この場合、古いダンプファイルの削除処理では、他のアプリケーションのダンプが除外され、削除は行われません。

Kdump に対して、そのイベントが発生した際に電子メールで通知を行いたい場合は、 電子メール通知 のウインドウ内で設定を行います。また、必要であれば 熟練者向け設定 で必要な設定を行います。設定が完了したら OK を押すことで、設定が完了します。

18.7.3 SSH 経由での Kdump Edit source

ダンプファイルには不用意に開示してはならない様々な機密情報が含まれています。このような機密情報を含むデータを信頼できないネットワーク経由で送信できるようにするため、 Kdump には、 SSH プロトコルを介してリモートのマシンにダンプファイルを送信できる機能が用意されています。

  1. 送信先のホストの識別情報は、あらかじめ Kdump 側で既知のものでなければなりません。これは、機密情報を含むデータを誤った (場合によっては悪意を持って偽装された) ホストに送信しないための仕組みです。 Kdump が新しい initrd を生成する際、送信先のホストの識別情報を問い合わせるために ssh-keygen -F 宛先ホスト を実行しますが、それは 宛先ホスト の公開鍵が既知である必要があるためです。公開鍵を既知のものにしておくための最も簡単な方法は、 root宛先ホスト に接続してみることです。

  2. また、 Kdump は送信先のホストとの間で認証できなければなりません。現時点では公開鍵認証にのみ対応しています。既定では Kdump は root の機密鍵を使用して接続しようとしますが、通常は Kdump 用に個別の鍵を用意しておくことが望ましい設定です。個別の鍵は ssh-keygen を利用して、下記のように実行することで作成することができます:

    1. # ssh-keygen -f ~/.ssh/kdump_key
    2. なお、パスフレーズの入力を求められた際には、何も入力せずに Enter を押してください (これでパスフレーズを使用せずに鍵を作成する意味になります) 。

    3. あとは /etc/sysconfig/kdump ファイルを開いて、 KDUMP_SSH_IDENTITY の値を kdump_key に設定します。なお、 ~/.ssh 以外のディレクトリに配置している場合は、フルパスで指定してください。

  3. 次に、生成した Kdump の SSH 鍵を送信先のホストに送信して認証できるようにします。

    # ssh-copy-id -i ~/.ssh/kdump_key TARGET_HOST
  4. KDUMP_SAVEDIR を設定します。これには 2 つの方法があります:

    Secure File Transfer Protocol (SFTP)

    SFTP は SSH 経由でファイルを送信するための推奨される方法です。ただし、接続先のホストで SFTP サブシステムが有効化されていなければなりません (openSUSE Leap では既定で有効化されています) 。具体的には、下記のように指定します:

    KDUMP_SAVEDIR=sftp://宛先ホスト/ダンプファイルの保存先パス
    Secure Shell Protocol (SSH)

    ディストリビューションによっては、接続先のホストで SSH 経由でコマンドを実行しなければならないものもあります。 openSUSE Leap では、この方法にも対応しています。この場合、接続先のホストでの Kdump のユーザには、ログインシェルが設定されていなければならず、 mkdir , dd , mv の各コマンドを実行できなければなりません。具体的には下記のように指定します:

    KDUMP_SAVEDIR=ssh://宛先ホストダンプファイルの保存先パス
  5. 新しい設定を適用するには、 Kdump のサービスを再起動してください。

18.8 クラッシュダンプの解析 Edit source

ダンプファイルを保存することができたら、あとは解析するだけです。解析方法にはいくつかあります。

ダンプを解析する際に使用する最も基本的なツールは GDB です。このツールは最新の環境でも使用することができますが、いくつかの欠点や制限が存在しています:

  • GDB はカーネルのダンプを解析するための専用ツールではないこと。

  • GDB では 32 ビットプラットフォームで ELF64 バイナリ形式に対応していないこと。

  • GDB では ELF ダンプ以外の形式 (圧縮ダンプを含む) に対応していないこと。

上記のような理由から、 crash ユーティリティが作成されました。このユーティリティはクラッシュダンプを解析するだけでなく、動作中のシステムもデバッグすることができます。また、 Linux カーネルのデバッグ専用の機能が用意され、高度なデバッグを行いたい場合に最適な仕組みです。

Linux カーネルをデバッグするには、まずデバッグ情報パッケージをもインストールしておく必要があります。お使いのシステムにインストールされているかどうかを確認するには、下記のコマンドを入力して実行します:

> zypper se kernel | grep debug
重要
重要: デバッグ情報パッケージのリポジトリについて

openSUSE Leap 15.7 のシステムでオンライン更新を受け取るように設定している場合、 *-Debuginfo-Updates という名前のオンラインリポジトリ内に debuginfo パッケージが存在しています。 YaST を利用するなどしてリポジトリを有効化してください。

ダンプを生成したマシンと同じマシンで crash コマンドを実行し、採取したダンプを開きたい場合は、下記のようなコマンドを入力して実行します:

crash /boot/vmlinux-6.4.0-150600.9-default.gz \
/var/crash/2024-04-23-11\:17/vmcore

ここで、最初のパラメータはカーネルイメージのパスを表しています。 2 つめのパラメータには、 Kdump で採取したダンプファイルを指定します。既定では、 /var/crash ディレクトリ内に存在しています。

ヒント
ヒント: カーネルクラッシュダンプからの基本情報の取得について

openSUSE Leap には kdumpid と呼ばれるユーティリティ (同名のパッケージに含まれています) が存在し、これによって未知のカーネルダンプの情報を表示することができます。このユーティリティは、アーキテクチャやカーネルリリースなど、基本的な情報を抽出することができます。また、このユーティリティは lkcd, diskdump, Kdump, ELF ダンプの各形式に対応しているほか、 -v オプションを付けて実行すると、マシンの種類やカーネルのバナー文字列、カーネルの設定フレーバーなども表示することができます。

18.8.1 カーネルのバイナリ形式 Edit source

Linux カーネルは Executable and Linkable Format (ELF) 形式で提供されます。このファイルは通常 vmlinux と呼ばれ、コンパイル処理時に直接生成されます。ただし、特に AMD64/Intel 64 アーキテクチャで顕著ではありますが、全てのブートローダが ELF 形式に対応しているというわけではありません。 openSUSE® Leap で対応しているアーキテクチャごとに、下記のような仕組みになっています。

18.8.1.1 AMD64/Intel 64 Edit source

SUSE が提供する AMD64/Intel 64 向けのカーネルパッケージには、 vmlinuzvmlinux.gz という 2 つのファイルが含まれています。

  • vmlinuz: ブートローダから直接実行するほうのファイルです。

    Linux カーネルは 2 種類のパーツから構成されています。 1 つはカーネルそれ自身 ( vmlinux ) 、もう 1 つはブートローダが実行するセットアップコードです。これら 2 つのパーツを 1 つにまとめて vmlinuz というファイルに仕立て上げています (末尾が x ではなく z であることに注意してください) 。

    カーネルのソースツリー内では、このファイルは bzImage と呼ぶこともあります。

  • vmlinux.gz: こちらは crash や GDB が使用するファイルで、圧縮された ELF イメージの形態になっています。 ELF イメージは AMD64/Intel 64 のブートローダから使用されることがありませんので、圧縮されたファイルのみを提供しています。

18.8.1.2 POWER Edit source

POWER 上で動作する yaboot ブートローダは ELF イメージの読み込みに対応していますが、圧縮されたファイルには対応していません。そのため、 POWER アーキテクチャ向けのカーネルパッケージには、 vmlinux という ELF 形式の Linux カーネルファイルが含まれています。 crash を動作させる前提で考えると、最も単純なアーキテクチャであると言えます。

なお、他のマシンでダンプを解析する場合は、コンピュータのアーキテクチャとデバッグに必要なファイルの両方を確認しなければならないことに注意してください。

他のコンピュータでダンプを解析する場合は、同じアーキテクチャの Linux マシンのみを使用することができます。アーキテクチャを確認したい場合は、 uname -i と入力して実行し、出力された内容を比較してください。

このほか、他のコンピュータでダンプを解析しようとしている場合は、 kernel パッケージと kernel debug パッケージが提供するファイルが必要となります。

  1. まずはカーネルダンプと /boot にあるカーネルイメージ、そしてそれに対応し、 /usr/lib/debug/boot 内にあるデバッグ情報ファイルを、 1 つのディレクトリ内にコピーしてまとめます。

  2. また、 /lib/modules/$(uname -r)/kernel/ にあるカーネルモジュールと /usr/lib/debug/lib/modules/$(uname -r)/kernel/ にあるカーネルモジュール用のデバッグ情報ファイルを、 modules サブディレクトリ内にコピーします。

  3. ダンプファイルとカーネルイメージ、デバッグ情報ファイルを 1 つのディレクトリにまとめ、 modules サブディレクトリ以下にカーネルモジュールとデバッグ情報ファイルを配置したら、あとは crash ユーティリティを実行します:

    > crash VMLINUX-バージョン vmcore

ダンプを解析しているコンピュータに関わらず、 crash ユーティリティは下記のような出力を生成するはずです:

> crash /boot/vmlinux-6.4.0-150600.9-default.gz \
/var/crash/2024-04-23-11\:17/vmcore
crash 7.2.1
Copyright (C) 2002-2017  Red Hat, Inc.
Copyright (C) 2004, 2005, 2006, 2010  IBM Corporation
Copyright (C) 1999-2006  Hewlett-Packard Co
Copyright (C) 2005, 2006, 2011, 2012  Fujitsu Limited
Copyright (C) 2006, 2007  VA Linux Systems Japan K.K.
Copyright (C) 2005, 2011  NEC Corporation
Copyright (C) 1999, 2002, 2007  Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002  Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions.  Enter "help copying" to see the conditions.
This program has absolutely no warranty.  Enter "help warranty" for details.

GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".

      KERNEL: /boot/vmlinux-6.4.0-150600.9-default.gz
   DEBUGINFO: /usr/lib/debug/boot/vmlinux-6.4.0-150600.9-default.debug
    DUMPFILE: /var/crash/2024-04-23-11:17/vmcore
        CPUS: 2
        DATE: Thu Apr 23 13:17:01 2024
      UPTIME: 00:10:41
LOAD AVERAGE: 0.01, 0.09, 0.09
       TASKS: 42
    NODENAME: eros
     RELEASE: 6.4.0-150600.9-default
     VERSION: #1 SMP 2024-03-31 14:50:44 +0200
     MACHINE: x86_64  (2999 Mhz)
      MEMORY: 16 GB
       PANIC: "SysRq : Trigger a crashdump"
         PID: 9446
     COMMAND: "bash"
        TASK: ffff88003a57c3c0  [THREAD_INFO: ffff880037168000]
         CPU: 1
       STATE: TASK_RUNNING (SYSRQ)
crash> 

このコマンドは最初に、有益なデータを出力します。上記の例では、カーネルがクラッシュした時点で 42 個のタスクが動作していて、クラッシュの原因は PID 9446 のタスクから送信された SysRq トリガー、そしてそのプロセスは bash である (bash 内蔵コマンドである echo コマンドでクラッシュを発生させたため) ことを示しています。

crash ユーティリティは GDB を利用して動作する仕組みであるため、様々な追加コマンドも用意されています。たとえば bt コマンドを何もパラメータを指定せずに実行すると、クラッシュが発生した時点での、そのタスクのバックトレースを表示することができます:

crash> bt
PID: 9446   TASK: ffff88003a57c3c0  CPU: 1   COMMAND: "bash"
 #0 [ffff880037169db0] crash_kexec at ffffffff80268fd6
 #1 [ffff880037169e80] __handle_sysrq at ffffffff803d50ed
 #2 [ffff880037169ec0] write_sysrq_trigger at ffffffff802f6fc5
 #3 [ffff880037169ed0] proc_reg_write at ffffffff802f068b
 #4 [ffff880037169f10] vfs_write at ffffffff802b1aba
 #5 [ffff880037169f40] sys_write at ffffffff802b1c1f
 #6 [ffff880037169f80] system_call_fastpath at ffffffff8020bfbb
    RIP: 00007fa958991f60  RSP: 00007fff61330390  RFLAGS: 00010246
    RAX: 0000000000000001  RBX: ffffffff8020bfbb  RCX: 0000000000000001
    RDX: 0000000000000002  RSI: 00007fa959284000  RDI: 0000000000000001
    RBP: 0000000000000002   R8: 00007fa9592516f0   R9: 00007fa958c209c0
    R10: 00007fa958c209c0  R11: 0000000000000246  R12: 00007fa958c1f780
    R13: 00007fa959284000  R14: 0000000000000002  R15: 00000000595569d0
    ORIG_RAX: 0000000000000001  CS: 0033  SS: 002b
crash> 

これで何が起こったのかを知ることができます。 bash シェルの内蔵コマンドである echo が、 /proc/sysrq-trigger に文字を送信したために、クラッシュが発生していることになります。その文字に対応するハンドラが検出されると、 crash_kexec() を実行しています。この関数は panic() と呼ばれ、ここで Kdump がダンプを保存しています。

GDB の基本的なコマンドと bt の拡張版に加えて、 crash ユーティリティには Linux カーネルの構造に関連したその他のコマンドも用意されています。これらのコマンドは Linux カーネルの内部データ構造を理解し、それを人間にとって読みやすい形式で表示します。たとえばクラッシュが発生した時点でのタスクの一覧は、 ps で表示することができます。また sym コマンドは、全てのカーネルシンボルの一覧とアドレスを表示したり、指定したシンボルに対して値を取得したりすることもできます。さらに files コマンドでは、プロセスが開いている全てのファイルディスクリプタを表示することができます。 kmem では、カーネルのメモリ使用率に関する詳細を表示することができます。 vm では、個別のページマッピングのレベルに至るまで、プロセスの仮想メモリを調査することができます。分かりやすいコマンドの一覧は多く用意されているほか、様々なオプションを受け付けるようになっています。

上述のコマンドは、一般的な Linux コマンドである pslsof の機能に対応しているものです。なお、デバッガでイベントの正確な順序を確認したい場合は、 GDB の使用方法について知る必要があるほか、強固なデバッグスキルを必要とします。この種類の話題は本文書の範疇外にあたるものであるため、本書では説明していません。これに加えて、 Linux カーネルそのものの知識も必要となります。こちらについては、本文書の末尾にある参照情報をご確認ください。

18.9 高度な Kdump の設定 Edit source

Kdump の設定は /etc/sysconfig/kdump 内に保存されています。設定は YaST を利用しても行うことができます。 Kdump の設定オプションは、 YaST コントロールセンター 内の システム › カーネル Kdump 内に存在しています。下記の Kdump オプションが用意されています。

カーネルダンプの保存先は、 KDUMP_SAVEDIR オプションで指定します。ただし、カーネルダンプのサイズは大きくなることに注意してください。ディスクの空き容量から予想されるダンプファイルのサイズを引いた値が、 KDUMP_FREE_DISK_SIZE よりも少ない場合、 Kdump はダンプの保存を行わなくなります。また、 KDUMP_SAVEDIR では、 URL 形式にも対応しています。 URL 形式は プロトコル://仕様 の形式で指定し、 プロトコルfile , ftp , sftp , nfs , cifs のいずれかを指定します。 仕様 はそれぞれのプロトコルに従った値を指定します。たとえばカーネルダンプを FTP サーバ内に保存したい場合は、 ftp://ユーザ名:パスワード@ftp.example.com:123/var/crash のように指定します。

カーネルダンプは巨大なものであり、解析には必要のない多数のページをも含んでしまっています。 KDUMP_DUMPLEVEL オプションを指定することで、これらの不要なページを省略することができます。設定可能な値は 0 から 31 までで、 0 を指定すると最も巨大なダンプファイルに、 31 を指定すると最も小さなダンプファイルになります。設定可能な値について、詳しくは kdump のマニュアルページ ( man 7 kdump ) をお読みください。

場合によっては、カーネルダンプのサイズを小さくしておいたほうが都合のよい場合があります。たとえばネットワーク経由でダンプを転送するような場合や、ダンプディレクトリのディスク領域を節約したい場合などがそれにあたります。この場合は、 KDUMP_DUMPFORMAT の値を compressed に設定してください。なお、 crash ユーティリティでは、圧縮されたダンプを動的に展開して使用することができます。

重要
重要: Kdump の設定ファイルの変更について

/etc/sysconfig/kdump ファイルを変更した場合は、その変更点を反映させるため、必ず systemctl restart kdump.service を実行する必要があります。実行しておかないと、次にシステムを再起動するまで、変更が反映されなくなってしまいます。

18.10 さらなる情報 Edit source

Kexec や Kdump の使用方法については、 1 箇所にまとまった情報源が存在していないのが現状です。下記にさまざまな側面で使用できる情報源 (いずれも英語のみ) を示します:

crash ダンプ解析ユーティリティやデバッグツールについての詳細は、それぞれ下記 (いずれも英語) をお読みください:

  • GDB の info ページ ( info gdb ) に加えて、印刷可能なガイド https://sourceware.org/gdb/documentation/ も提供されています。

  • crash ユーティリティには幅広い分野に対応したオンラインヘルプが用意されています。 help コマンド のように入力すると、 コマンド に対するオンラインヘルプを表示することができます。

  • Perl の知識をお持ちであれば、 Alicia を利用してより簡単にデバッグを行うことができます。これは Perl ベースの crash ユーティリティ向けフロントエンドです。詳しくは https://alicia.sourceforge.net/ をお読みください。

  • Python をご利用になりたい場合は、 Pykdump をインストールして使用することをお勧めします。このパッケージは Python スクリプト経由で GDB を制御することができるものです。

  • Linux カーネルの内部情報に関する幅広い情報については、 Daniel P. Bovet 氏および Marco Cesati 氏による Understanding the Linux Kernel (ISBN 978-0-596-00565-8) をお読みください。

このページを印刷