【Linux】Failed to start Load Kernel Modules

最近, 例行升级系统后(Manjaro), bootup console 总是出现一行 Error Log: Failed to start Load Kernel Modules.
由于 grub 设置到 Kernel 参数是 quiet, 没有上下文输出, 不清楚什么原因.

查找日志

首先看了自己的 Kernel 信息:

➜  mhwd-kernel --listinstalled 
Currently running: 5.4.221-1-MANJARO (linux54)
The following kernels are installed in your system:
* linux54

➜ sudo ls /boot
[sudo] password for niko:
grub intel-ucode.img vmlinuz-5.4-x86_64
initramfs-5.4-x86_64-fallback.img linux54-x86_64.kver
initramfs-5.4-x86_64.img memtest86+

➜ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-5.4-x86_64 root=UUID=2e877c04-0bbe-405f-9c54-20d013ac9957 rw quiet apparmor=1 security=apparmor resume=UUID=7bd887aa-7673-4bfd-8413-44b494036b33 udev.log_priority=3

dmesg 查询 bootup 时的上下文日志:

[    5.607002] systemd[1]: First Boot Wizard was skipped because of a failed condition check (ConditionFirstBoot=yes).
[ 5.608832] systemd[1]: Rebuild Hardware Database was skipped because of a failed condition check (ConditionNeedsUpdate=/etc).
[ 5.611219] systemd[1]: Starting Load/Save Random Seed...
[ 5.611850] systemd[1]: Create System Users was skipped because of a failed condition check (ConditionNeedsUpdate=/etc).
[ 5.622399] systemd[1]: Starting Create Static Device Nodes in /dev...
[ 5.624198] systemd[1]: systemd-modules-load.service: Main process exited, code=exited, status=1/FAILURE
[ 5.624489] systemd[1]: systemd-modules-load.service: Failed with result 'exit-code'.
[ 5.624773] systemd[1]: Failed to start Load Kernel Modules.

由上可知, 是 systemd-modules-load.service 打印的 error 日志.

检查 systemd-modules-load.service 的状态:

➜   systemctl status systemd-modules-load.service 
× systemd-modules-load.service - Load Kernel Modules
Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
Active: failed (Result: exit-code) since Thu 2023-01-12 08:12:47 HKT; 9h ago
Docs: man:systemd-modules-load.service(8)
man:modules-load.d(5)
Process: 307 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=1/FAILURE)
Main PID: 307 (code=exited, status=1/FAILURE)
CPU: 37ms

Notice: journal has been rotated since unit was started, output may be incomplete.

可以通过 journalctl 查看日志, 但由于 journal has been rotated, 日志可能补全, 不过可以通过 restart service 来尝试复现.

➜  journalctl -u systemd-modules-load.service
Jan 12 17:28:16 manjaro-v systemd[1]: Starting Load Kernel Modules...
Jan 12 17:28:16 manjaro-v systemd-modules-load[3964]: Failed to insert module 'vboxsf': Exec format error
Jan 12 17:28:16 manjaro-v systemd[1]: systemd-modules-load.service: Main process exited, code=exited, status=1/FAILURE
Jan 12 17:28:16 manjaro-v systemd[1]: systemd-modules-load.service: Failed with result 'exit-code'.
Jan 12 17:28:16 manjaro-v systemd[1]: Failed to start Load Kernel Modules.

由上, journalctl 检查日志发现: Failed to insert module 'vboxsf', 由于我并未使用 vbox, 也省去了一些功夫, 直接不加载即可.

寻找配置

查询 manual, 寻找 systemd-modules-load.service 的配置文件:

➜ man systemd-modules-load.service

NAME
systemd-modules-load.service, systemd-modules-load - Load kernel modules at boot

SYNOPSIS
systemd-modules-load.service

/usr/lib/systemd/systemd-modules-load

DESCRIPTION
systemd-modules-load.service is an early boot service that loads kernel modules. It reads static configuration from files in /usr/ and /etc/, but also runtime configuration from /run/ and the kernel command line (see below).

See modules-load.d(5) for information about the configuration format of this service and paths where configuration files can be created.

由上, See modules-load.d(5) , 可以得到 the configuration format of this service and paths where configuration files, 我们继续 man 查找:

➜  man modules-load.d

MODULES-LOAD.D(5) modules-load.d MODULES-LOAD.D(5)

NAME
modules-load.d - Configure kernel modules to load at boot

SYNOPSIS
/etc/modules-load.d/*.conf

/run/modules-load.d/*.conf

/usr/lib/modules-load.d/*.conf

DESCRIPTION
systemd-modules-load.service(8) reads files from the above directories which contain kernel modules to load during boot in a static
list. Each configuration file is named in the style of /etc/modules-load.d/program.conf. Note that it is usually a better idea to rely
on the automatic module loading by PCI IDs, USB IDs, DMI IDs or similar triggers encoded in the kernel modules themselves instead of
static configuration like this. In fact, most modern kernel modules are prepared for automatic loading already.

现在得知 /etc/modules-load.d/*.conf 这个位置就是它的配置文件, 在其中 linux54-virtualbox-guest-modules.conf 找到了我们想要的:

➜  vim /etc/modules-load.d/linux54-virtualbox-guest-modules.conf
# niko canceled, 20230112 (vboxsf)
# vboxsf

注释掉 vboxsf, reboot, 发现没有错误日志了, Arch 和文档真好.

参考