【解決】Linuxのカーネルモジュール(ドライバー等)を入れ替えても再起動すると元に戻る

症状

ハードウェアドライバーなどのカーネルモジュールを入れ替えて適用しても、再起動すると元に戻る。

原因

前のカーネルモジュールが initramfs に組み込まれたドライバである可能性があります。

Linux 起動シーケンス中にハードウェアドライバがロードされるタイミングは2箇所あります。1か所目が initrd root filesystem による初期セットアップ時で、これは主に HDD のドライバ等が呼び出されますが、最近はネットワークブートも流行っており、NICドライバの呼び出しもできます。2か所目が real root filesystem への切り替え後です。

例えば NIC のドライバが initramfs に組み込まれていない場合は、real root filesystem への切り替え後に udev が、PCI(e) 等経由で取得したベンダーIDを元に、/lib/modules/`uname -r`/kernel/drivers/net/ethernet にあるベンダーディレクトリから適切なモジュールを引っ張って適用してくれます。

ですがもし initramfs に組み込まれている場合、initrd root filesystem による初期セットアップ時に NIC ドライバをロードし、その後は Switch Root により /sys/ 配下に呼び出したドライバをそのまま real root filesystem に引き継いでしまいます。

https://linux.die.net/man/8/switch_root

initramfs にドライバが組み込まれているかどうかは、lsinitrd コマンドで確認することができます。例えば e1000 が入っているかどうかは以下のように確認します。

lsinitrd | grep e1000

対処法

ドライバ適用後に initramfs を作り直します。例えば RedHat/CentOS/Fedora の場合は dracut コマンドで作成できます。

まずは現状の initramfs を mv (リネーム) してバックアップしておき、

dracut

と打つだけです。もし対象のドライバーを狙って外したいときは

drauct --omit-drivers=e1000

といったオプションも使えます。