「Kexec」の版間の差分
(同期) |
Kusanaginoturugi (トーク | 投稿記録) (→参照: add TranslationStatus.) |
||
(4人の利用者による、間の8版が非表示) | |||
5行目: | 5行目: | ||
{{Related|Systemd}} |
{{Related|Systemd}} |
||
{{Related articles end}} |
{{Related articles end}} |
||
− | + | [[Wikipedia:ja:Kexec|Kexec]] は動作中のカーネルから他のカーネルをロード・起動するためのシステムコールです。カーネル開発者など、BIOS のブートプロセスが終わるまで待たないで素早く再起動する必要がある場合に有用です。デバイスが完全に再初期化されず、kexec が上手く動作しないこともありますが、それはとてもレアなケースです。 |
|
== インストール == |
== インストール == |
||
− | + | {{pkg|kexec-tools}} パッケージをインストールしてください。 |
|
== kexec で再起動 == |
== kexec で再起動 == |
||
+ | |||
+ | === 手動 === |
||
+ | |||
+ | kexec を手動で実行するには: |
||
+ | |||
+ | # kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline |
||
+ | # kexec -e |
||
+ | |||
+ | {{Warning|{{ic|kexec -e}} を直接実行するとアクティブなファイルシステムがアンマウントされません。また、実行中のサービスが安全に終了されません。}} |
||
+ | |||
+ | 手動でカーネルをロードしてから systemd でサービスのシャットダウンや kexec を処理させることも可能です: |
||
+ | |||
+ | # kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline |
||
+ | # systemctl kexec |
||
=== Systemd === |
=== Systemd === |
||
+ | [[systemd-boot]] を使っていて、前に {{ic|kexec -l}} を使って手動でカーネルをロードしたことがない場合、デフォルトで systemd はデフォルトのブートローダーエントリに指定されたカーネルをロードします。例えば、システムを更新した後に新しいカーネルに再起動したいときは、以下のコマンドを実行するだけで起動できます: |
||
− | ユニットファイル {{ic|kexec-load@.service}} を作成して、kexec するカーネルをロードさせる必要があります: |
||
+ | |||
+ | # systemctl kexec |
||
+ | |||
+ | 複数の initrd エントリ (例えば[[マイクロコード]]のアップデートのためのエントリなど) が存在する場合は上記のコマンドは起動を拒否します。 |
||
+ | |||
+ | ==== カスタムユニットファイル ==== |
||
+ | |||
+ | デフォルトで起動できない場合やカスタムカーネルをロードしたい場合、サービスユニットでカーネルのロードをラッピングできます。ユニットファイル {{ic|kexec-load@.service}} を作成して、kexec するカーネルをロードさせる必要があります: |
||
{{hc|/etc/systemd/system/kexec-load@.service|2= |
{{hc|/etc/systemd/system/kexec-load@.service|2= |
||
31行目: | 53行目: | ||
WantedBy=kexec.target}} |
WantedBy=kexec.target}} |
||
− | ロードしたいカーネル |
+ | 次に、ロードしたいカーネルのサービスファイルを [[有効化]] します (例:{{ic|linux}} の場合は {{ic|kexec-load@linux.service}} になります) |
+ | {{ic|/etc/mkinitcpio.conf}} の {{ic|HOOKS}} 配列からシャットダウンフックを削除して、シャットダウンフックが initramfs イメージの一部でないことを確認します。存在する場合は、それを削除し、[[mkinitcpio#イメージ作成とアクティベーション|initramfs を再生成]] します。 |
||
− | {{hc|# systemctl enable kexec-load@linux| |
||
− | ln -s '/etc/systemd/system/kexec-load@.service' '/etc/systemd/system/kexec.target.wants/kexec-load@linux.service'}} |
||
+ | 次に kexec へ |
||
− | {{ic|/etc/mkinitcpio.conf}} の {{ic|HOOKS}} 行から shutdown フックを削除して initramfs イメージにフックを含めないようにしてください。削除したら {{ic|mkinitcpio -p linux}} で initrd イメージを再生成します。 |
||
− | |||
− | その後 kexec を実行します: |
||
# systemctl kexec |
# systemctl kexec |
||
− | 別のカーネルをロードしたい |
+ | 次の kexec 用に別のカーネルをロードしたい場合は、{{ic|linux-lts}} のように、現在のカーネルのサービスを [[無効化]] して、新しいカーネルのサービスを [[有効化]] します。 |
− | |||
− | # systemctl disable kexec-load@linux |
||
− | # systemctl enable kexec-load@linux-lts |
||
==== /boot パーティションの分割 ==== |
==== /boot パーティションの分割 ==== |
||
56行目: | 72行目: | ||
Documentation=man:kexec(8) |
Documentation=man:kexec(8) |
||
DefaultDependencies=no |
DefaultDependencies=no |
||
+ | Requires=sysinit.target |
||
− | RequiresMountsFor=/boot/vmlinuz-%i |
||
− | + | After=sysinit.target |
|
[Service] |
[Service] |
||
69行目: | 85行目: | ||
}} |
}} |
||
+ | {{ic|1=Conflicts=shutdown.target}} は省略してもかまいません。{{ic|sysinit.target}} を指定するだけで暗示的に {{ic|1=Conflicts=}} が {{ic|shutdown.target}} に設定されるためです。 |
||
− | 残念ながら、上記のファイルは問題なく動作することもありますが、マシンによっては ExecStop コマンドが動作しないことがあります。従って、今のところ、全てのマシンで {{ic|systemctl kexec}} を確実に動作させることができる方法はありません。 |
||
+ | == トラブルシューティング == |
||
− | sysinit による順番を使用する方法 (アンマウントが行われる前にサービスが確実にシャットダウンされます): |
||
+ | === "kexec_core: Starting new kernel" の後にシステムがフリーズしたり再起動する === |
||
− | {{bc|1= |
||
− | [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 |
||
+ | 場合によっては、システムのハングは acpi 関連の問題である可能性があり、次のようにその場で確認できます。 |
||
− | [Install] |
||
+ | |||
− | WantedBy=basic.target |
||
+ | {{bc|1= |
||
+ | # cmdline=$(cat /proc/cmdline) |
||
+ | # cmdline="$cmdline acpi_rsdp=$(grep -m1 ^ACPI /sys/firmware/efi/systab {{!}} cut -f2- -d=)" |
||
+ | # echo $cmdline |
||
+ | # ls -al /boot/ |
||
+ | # kexec -l /boot/vmlinuz-linux-lts --initrd=/boot/initramfs-linux-lts.img --append="$cmdline" |
||
+ | # systemctl kexec |
||
}} |
}} |
||
+ | {{ic|ls -al /boot/}} の出力に従って、initramfs イメージとカーネルの名前を調整してください。 |
||
− | {{ic|1=Conflicts=shutdown.target}} は省略してもかまいません。{{ic|systinit.target}} を指定するだけで暗示的に {{ic|1=Conflicts=}} が {{ic|shutdown.target}} に設定されるためです。 |
||
+ | 特に、{{ic|1=acpi=off}} カーネルパラメータを追加したときに kexec が正しく動作するようになる場合、[https://github.com/coreos/bugs/issues/167] で説明されているように kexec コマンドラインに {{ic|1=acpi_rsdp}} カーネルパラメータを追加することで ACPI を無効化することなく [https://bbs.archlinux.org/viewtopic.php?id=219878 場合によっては、] 問題を解決できる可能性があります。 |
||
− | === 手動 === |
||
+ | === カーネルモードを設定しない (Nvidia) === |
||
− | kexec を手動で実行することもできます: |
||
+ | kexec の前にグラフィックスドライバーをアンロードする必要があります。そうしないと、次のカーネルがデバイスの排他制御を取得できなくなります。GPU の排他制御が必要なプログラム (Xorg、ディスプレイマネージャー) が実行されていてはいけないため、これを手動で実現するのは困難です。以下は、kexec の直前に KMS ドライバーをアンロードする [[systemd#ユニットファイルを置換する|systemd service]] の例です。これには、{{ic|systemctl kexec}} を使用する必要があります。 |
||
− | # kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline |
||
− | # kexec -e |
||
+ | {{hc|/etc/systemd/system/unmodeset.service|2= |
||
− | {{Warning|{{ic|kexec -e}} を直接実行するとアクティブなファイルシステムがアンマウントされません。また、実行中のサービスが安全に終了されません。}} |
||
+ | [Unit] |
||
+ | Description=Unload nvidia modesetting modules from kernel |
||
+ | Documentation=man:modprobe(8) |
||
+ | DefaultDependencies=no |
||
+ | After=umount.target |
||
+ | Before=kexec.target |
||
+ | [Service] |
||
− | 手動でカーネルをロードしてから systemd でサービスのシャットダウンや kexec を処理させることも可能です: |
||
+ | Type=oneshot |
||
+ | ExecStart=modprobe -r nvidia_drm |
||
+ | [Install] |
||
− | # kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline |
||
+ | WantedBy=kexec.target |
||
− | # systemctl kexec |
||
+ | }} |
||
+ | |||
+ | その後、{{ic|unmodeset.service}} を [[有効化]] します。 |
||
== 参照 == |
== 参照 == |
||
− | * [ |
+ | * [https://lists.freedesktop.org/archives/systemd-devel/2012-March/004760.html <nowiki>[systemd-devel]</nowiki> Right way to do kexec] |
− | * [ |
+ | * [https://lse.sourceforge.net/kdump/ kdump: a kexec based crash dumping mechanim for Linux] |
− | * [https://web.archive.org/web/20090505132901/ |
+ | * [https://web.archive.org/web/20090505132901/https://www.ibm.com/developerworks/linux/library/l-kexec.html Reboot Linux faster using kexec] |
+ | |||
+ | {{TranslationStatus|Kexec|2024-08-28|801963}} |
2024年8月28日 (水) 18:47時点における最新版
関連記事
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
の場合は kexec-load@linux.service
になります)
/etc/mkinitcpio.conf
の HOOKS
配列からシャットダウンフックを削除して、シャットダウンフックが initramfs イメージの一部でないことを確認します。存在する場合は、それを削除し、initramfs を再生成 します。
次に kexec へ
# systemctl kexec
次の kexec 用に別のカーネルをロードしたい場合は、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 関連の問題である可能性があり、次のようにその場で確認できます。
# cmdline=$(cat /proc/cmdline) # cmdline="$cmdline acpi_rsdp=$(grep -m1 ^ACPI /sys/firmware/efi/systab | cut -f2- -d=)" # echo $cmdline # ls -al /boot/ # kexec -l /boot/vmlinuz-linux-lts --initrd=/boot/initramfs-linux-lts.img --append="$cmdline" # systemctl kexec
ls -al /boot/
の出力に従って、initramfs イメージとカーネルの名前を調整してください。
特に、acpi=off
カーネルパラメータを追加したときに kexec が正しく動作するようになる場合、[1] で説明されているように kexec コマンドラインに acpi_rsdp
カーネルパラメータを追加することで ACPI を無効化することなく 場合によっては、 問題を解決できる可能性があります。
カーネルモードを設定しない (Nvidia)
kexec の前にグラフィックスドライバーをアンロードする必要があります。そうしないと、次のカーネルがデバイスの排他制御を取得できなくなります。GPU の排他制御が必要なプログラム (Xorg、ディスプレイマネージャー) が実行されていてはいけないため、これを手動で実現するのは困難です。以下は、kexec の直前に KMS ドライバーをアンロードする systemd service の例です。これには、systemctl kexec
を使用する必要があります。
/etc/systemd/system/unmodeset.service
[Unit] Description=Unload nvidia modesetting modules from kernel Documentation=man:modprobe(8) DefaultDependencies=no After=umount.target Before=kexec.target [Service] Type=oneshot ExecStart=modprobe -r nvidia_drm [Install] WantedBy=kexec.target
その後、unmodeset.service
を 有効化 します。