kexecを使うとlinuxの再起動が速くなる

過去に書いていそうで書いていなかったので kexec の小ネタを。

サーバの構築や新しいハードウェアでの構成管理を検証している場合など、とにかく何度も何度もOSを再起動しないといけないことがある。

そういうとき素直に再起動していると大変時間がかかる。
少し前まで使っていたシングルSSDのサーバはよそ見している間に再起動してOSのログインプロンプトが表示される程度に速かったが
ちゃんとRAIDコントローラが載っていてメモリもたくさん積んでなんかNICもたくさん刺さっているようなサーバだとまぁまぁ時間がかかる。

そんなとき便利なのが kexec だ。

理屈の前に先に使い方を書こう。

1
2
3
4
5
. <(/sbin/grubby --info $(/sbin/grubby --default-kernel) | grep -e ^args -e ^root -e ^initrd -e ^kernel)
/sbin/kexec -u
/sbin/kexec -l "$kernel" --initrd="$initrd" --command-line="root=${root} ${args}"

shutdown -r now

普段の再起動と同じように各種のプロセスがシャットダウンされて行くところまでは同じ。

違うのはプロセスが全部落ちた後。BIOSやRAIDコントローラなどのメッセージを全部すっ飛ばしておもむろにlinux kernelの起動が始まる。

kexecコマンドは何者なのか?

1
2
3
result = kexec_load(info.entry,
info.nr_segments, info.segment,
info.kexec_flags);

https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/tree/kexec/kexec.c?h=v2.0.24#n823

すごく大雑把に言うならkexecコマンドの引数で指定された情報で、kexec_load システムコールを呼んでいるだけである。

kexec_load(2) のmanにはこう書いてある
“kexec_load, kexec_file_load - load a new kernel for later execution”
https://man7.org/linux/man-pages/man2/kexec_load.2.html

reboot(2) システムコールに実行させるためのカーネルをメモリにロードしているのだ。

ちなみに kexec コマンドには --exec という、いかにも新しいカーネルを実行してくれそうなオプションがある。

1
reboot(LINUX_REBOOT_CMD_KEXEC);

https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/tree/kexec/kexec.c?h=v2.0.24#n927

結局やっていることは同じ。
kexec_load のあとで reboot までやってくれるのが --exec の正体なのであった。

便利な kexec 。Linux環境ではだいたいどこでも使えるはずなのでぜひバンバン使ってバンバン再起動して欲しい。