Kexec
関連記事
Kexec は動作中のカーネルから他のカーネルをロード・起動するためのシステムコールです。カーネル開発者など、BIOS のブートプロセスが終わるまで待たないで素早く再起動する必要がある場合に有用です。デバイスが完全に再初期化されず、kexec が上手く動作しないこともありますが、それはとてもレアなケースです。
目次
インストール
kexec-tools パッケージをインストールしてください。
kexec で再起動
手動
kexec を手動で実行するには:
# kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline # kexec -e
手動でカーネルをロードしてから systemd でサービスのシャットダウンや kexec を処理させることも可能です:
# kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline # systemctl kexec
Systemd
systemd-boot を使っていて、前に kexec -l
を使って手動でカーネルをロードしたことがない場合、デフォルトで systemd はデフォルトのブートローダーエントリに指定されたカーネルをロードします。例えば、システムを更新した後に新しいカーネルに再起動したいときは、以下のコマンドを実行するだけで起動できます:
# systemctl kexec
複数の initrd エントリ (例えばマイクロコードのアップデートのためのエントリなど) が存在する場合は上記のコマンドは起動を拒否します。
カスタムユニットファイル
デフォルトで起動できない場合やカスタムカーネルをロードしたい場合、サービスユニットでカーネルのロードをラッピングできます。ユニットファイル kexec-load@.service
を作成して、kexec するカーネルをロードさせる必要があります:
/etc/systemd/system/kexec-load@.service
[Unit] Description=load %i kernel into the current kernel Documentation=man:kexec(8) DefaultDependencies=no Before=shutdown.target umount.target final.target [Service] Type=oneshot ExecStart=/usr/bin/kexec -l /boot/vmlinuz-%i --initrd=/boot/initramfs-%i.img --reuse-cmdline [Install] WantedBy=kexec.target
ロードしたいカーネルを指定してサービスファイルを有効化してください、例えばデフォルトカーネル linux
を使用する場合:
# systemctl enable kexec-load@linux
ln -s '/etc/systemd/system/kexec-load@.service' '/etc/systemd/system/kexec.target.wants/kexec-load@linux.service'
/etc/mkinitcpio.conf
の HOOKS
行から shutdown フックを削除して initramfs イメージにフックを含めないようにしてください。削除したら mkinitcpio -p linux
で initrd イメージを再生成します。
その後 kexec を実行します:
# systemctl kexec
別のカーネルをロードしたいときは (例: linux-lts
)、現在のカーネルのサービスを無効化してから新しいカーネルのサービスを有効化してください:
# systemctl disable kexec-load@linux # systemctl enable kexec-load@linux-lts
/boot パーティションの分割
/boot
が root ファイルシステム上にない場合、上記の systemd ユニットファイルは動作しません。kexec-load
ユニットファイルを実行する前に /boot
が systemd によってアンマウントされてしまうからです。その場合、起動時には何もせず終了時に kexec を呼び出す "hook" ユニットファイルをロードします。このユニットファイルを kexec.target
と衝突させるようにすることで、新しいカーネルを systemctl kexec
コマンドの直後に確実にロードさせることができます。上記の規定どおりに作成した /etc/systemd/system/kexec-load@.service
ファイルは以下のようになります:
[Unit] Description=hook to load vmlinuz-%i kernel upon kexec Documentation=man:kexec(8) DefaultDependencies=no Requires=sysinit.target After=sysinit.target [Service] Type=oneshot ExecStart=-/usr/bin/true RemainAfterExit=yes ExecStop=/usr/bin/kexec -l /boot/vmlinuz-%i --initrd=/boot/initramfs-%i.img --reuse-cmdline [Install] WantedBy=basic.target
Conflicts=shutdown.target
は省略してもかまいません。sysinit.target
を指定するだけで暗示的に Conflicts=
が shutdown.target
に設定されるためです。
トラブルシューティング
"kexec_core: Starting new kernel" の後にシステムがフリーズしたり再起動する
その場合、一般的なトラブルシューティング#起動時の問題の情報が問題を診断するのに役立つかもしれません。
特に、acpi=off
カーネルパラメータを追加したときに kexec が正しく動作するようになる場合、[1] で説明されているように kexec コマンドラインに acpi_rsdp
カーネルパラメータを追加することで ACPI を無効化することなく問題を解決できる可能性があります [2]。