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と呼ばれているらしい。
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
カーネルアップデートしたときに反映されるのだろうか?
という疑問をこの記事を書いているときに思いついたのであとで検証しておこう。