ぶていのログでぶログ

思い出したが吉日

Ubuntuで使用するカーネルを変更する / grub-set-defaultを有効化する

Ubuntuに限らないが、Linuxディストリビューション(以下、ディストリ)ではLinuxカーネル(以下、カーネル)を起動時に指定して変更することができる。 基本的にはディストリが標準で提供しているカーネルを使えば良いと思うが、カスタムカーネルを入れたい場面やバージョンダウンして使いたいということが稀に発生する。 カーネルの選択は起動時にgrubのブートメニューから選択できるが、メニューが表示される時間が短かったり、毎回変更するのがめんどくさいということが起きる。 そういった場合 /etc/default/grub のGRUB_DEFAULTを書き換えてupdate_grubを実行すれば、起動してくるカーネルを変更できるがこれも少し手間だ。 そこで、grubにはgrub-set-defaultというコマンドが提供されていて、これを使うことでGRUB_DEFAULTを変更せずともブートされるカーネルを変更できるのだが、Ubuntuでは有効にならなかったので調べてみた。

GRUB Environment Block

grub-set-defaultは/boot/grub/grubenvに設定を書き込むという挙動になっている。 grub-set-defaultコマンドを実行した後に/boot/grub/grubenvを見てみると以下のようになっている。

$ cat /boot/grub/grubenv
# GRUB Environment Block
# WARNING: Do not edit this file by tools other than grub-editenv!!!
saved_entry=Advanced options for Ubuntu>Ubuntu, with Linux 5.15.0-25-generic
#####################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################

saved_entryという項目に起動したいカーネルのバージョン*1が設定されている。 コメントにも書かれているがこの機能はGRUB Environment Blockと呼ばれているらしい。

www.gnu.org

GRUB_DEFAULT=saved

grubenvをブート時に読み込ませるようにするには、/etc/default/grubにGRUB_DEFAULT=savedを設定しupdate-grub(grub-mkconfig)を実行する必要がある。 Ubuntuの場合(grubの標準機能?)では/etc/default/grub.d配下にファイルを置くことでそのファイルも読み込むようになる。 構成管理ツールを使っている場合はこちらにファイルを配置するほうが便利だと思う。 以下は設定例。

$ cat /etc/default/grub.d/99-use-saved-entry.cfg
GRUB_DEFAULT=saved

ファイルを配置したらupdate-grubすれば次回の起動からgrub-set-defaultの設定が有効になる。

$ sudo update-grub

grub-set-defaultの引数の注意点

grub-set-defaultの引数にはブートさせたいカーネルに紐付いたgrubのメニュー名を設定する必要がある。 便利なことにbashの補完機能が効くのでTABを数回押すと設定する内容がサジェストされるのだが、これに罠がある。 例えば手元の環境でサジェストを出すと以下のような出力になる。

$ sudo grub-set-default
--id                                                  Ubuntu, with Linux 5.15.0-25-generic                  Ubuntu, with Linux 5.15.0-40-generic (recovery mode)
Advanced options for Ubuntu                           Ubuntu, with Linux 5.15.0-25-generic (recovery mode)
Ubuntu                                                Ubuntu, with Linux 5.15.0-40-generic

ここで、5.15-0-25-genericなカーネルでブートさせたいと思ったら sudo grub-set-default "Ubuntu, with Linux 5.15.0-25-generic" とやってしまいそうになるのだが、これは間違っている。 なにか致命的な不具合やエラーになるわけじゃないが、次回起動時に意図したカーネルで起動してこない。 sudo grub-set-default "Advanced options for Ubuntu>Ubuntu, with Linux 5.15.0-25-generic" っとするのが正解である。 これは罠すぎる…これがわからなくて時間を溶かした…。 なぜこのように指定する必要があるかというと、UbuntuではAdvanced options for Ubuntu がメインメニューになっていて、その下にUbuntu, with Linux 5.15.0-25-generic がサブメニューとして設定されているからのようだ。 > で接続することで、Advanced options for Ubuntuの配下のUbuntu, with Linux 5.15.0-25-genericを選択するという挙動のようだ。

ちなみに、なぜこれに気がついたかというとupdate-grubしたときにWARNINGが出たのでそれで気がついたのであった*2

$ sudo update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/50-cloudimg-settings.cfg'
Sourcing file `/etc/default/grub.d/99-use-saved-entry.cfg'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.15.0-40-generic
Found initrd image: /boot/initrd.img-5.15.0-40-generic
Found linux image: /boot/vmlinuz-5.15.0-25-generic
Found initrd image: /boot/initrd.img-5.15.0-25-generic
Warning: Please don't use old title `Ubuntu, with Linux 5.15.0-25-generic' for GRUB_DEFAULT, use `Advanced options for Ubuntu>Ubuntu, with Linux 5.15.0-25-generic' (for versions before 2.00) or `gnulinux-advanced-63a35cf8-4d22-4a79-a93d-eb178abc8c07>gnulinux-5.15.0-25-generic-advanced-63a35cf8-4d22-4a79-a93d-eb178abc8c07' (for 2.00 or later) 👈 これ
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
done

カーネルアップデートしたときに反映されるのだろうか?

という疑問をこの記事を書いているときに思いついたのであとで検証しておこう。

*1:正確にはgrubのブートメニュー

*2:本来grub-set-default実行後にupdate-grubを実行する必要はないのだが、色々試しているときにupdate-grubを実行していたときに気がついたのであった