昨天 openSUSE Tumbleweed 例行升级时更新 Linux kernel 到了 4.6.0-1.1 版本。重启时使用新内核遇到 kernel panic 而无法进入到登录界面。在 Grub 中选择使用旧版本的 4.5.4-1-default 才顺利启动并登录进入系统。这让我产生了一点危机感。
因为最近非常忙,没时间折腾,而电脑又是主要的生产力工具,经不起折腾,所以不禁瞎想一些应对之策。先临时记录,回头慢慢尝试并修改补充。
Btrfs 的 snapshot¶
暂时先放弃,没时间折腾。
openSUSE 早就开始推广 Btrfs 了。Btrfs 的 snapshot 是一个文件系统热镜像的功能,产生一个 snapshot 之后可以在遇到问题时将文件系统恢复到该镜像——有点像 RPG 游戏的存档。像是一个时间机器。如果每次大的变动前都做个这样的镜像,用几天之后没有问题再删除该镜像,有问题就恢复,应该是很方便的。
本来 Btrfs 的 snapshot 是很好的防范类似问题的工具,可惜我没有使用 Btrfs 而是选择 Ext3 作为 root 分区的文件系统。本来 Btrfs 是默认的,你说我为什么要手贱给改了呢。
Ext3 可以转换为 Btrfs,但是转换前需要先卸载要转换的分区。对于系统分区(/)来说就没那么方便了(例子)。首先需要重启系统进入恢复模式(比如用 Live 光盘启动)然后才能转换。
保留多个版本的内核¶
openSUSE 默认在升级 kernel 的时候会在启动管理器(我用的是 Grub2)中保留上一版本和上上一版本以及正在运行的 kernel 的启动项,用于应对与此类似的问题。这就是多版本内核系统。启动时选择 Advance Options for openSUSE Tumbleweed 即可。
为了防止下次不小心把正在运行的 4.5.4-1-default 也给清除了,特地指定要保留此内核的启动项。
用 root 身份编辑 /etc/zypp/zypp.conf,确认 multiversion = provides:multiversion(kernel) 没有被注释掉,然后在,
multiversion.kernels = latest,latest-1,running
后面加上 4.5.4-1-default 变成,
multiversion.kernels = latest,latest-1,running,4.5.4-1-default
保存!
如果真的不小心被自动清除了,也许还可以自行一键安装旧版本内核。没试过!
暂时默认使用旧启动项¶
先不弄了,感觉没必要,一般都是休眠而不是关机。参考资料链接留着。
关于 VirtualBox¶
经过这么一折腾,VirtualBox 无法启动虚拟机了。报错,
Kernel driver not installed (rc=-1908)
The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing
‘/sbin/rcvboxdrv setup’
as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.
where: suplibOsInit what: 3 VERR_VM_DRIVER_NOT_INSTALLED (-1908) – The support driver is not installed. On linux, open returned ENOENT.
好吧,按照提示运行,
# sudo rcvboxdrv setup
Recompiling VirtualBox kernel module, NOT. It has been packaged. done
可是结果还是无法启动任何一个虚拟机。
再接着查询 vboxdrv 服务的状态,
# sudo systemctl status vboxdrv
● vboxdrv.service - LSB: VirtualBox Linux module
Loaded: loaded (/etc/init.d/vboxdrv; bad; vendor preset: disabled)
Active: active (exited) since Sat 2016-06-04 08:49:44 BST; 3h 49min ago
Docs: man:systemd-sysv-generator(8)
Process: 1410 ExecStart=/etc/init.d/vboxdrv start (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 512)
Jun 04 08:49:43 laptop systemd[1]: Starting LSB: VirtualBox Linux module...
Jun 04 08:49:44 laptop vboxdrv[1410]: Starting VirtualBox kernel modules..failed
Jun 04 08:49:44 laptop vboxdrv[1410]: (modprobe vboxdrv failed. Please use 'dmesg' t...hy)
Jun 04 08:49:44 laptop systemd[1]: Started LSB: VirtualBox Linux module.
Hint: Some lines were ellipsized, use -l to show in full.
然后就发现下面这几个模块都不见了,
# modprobe vboxdrv
# modprobe vboxnetflt
# modprobe vboxnetadp
结果都提示,
modprobe: FATAL: Module <module> not found in directory /lib/modules/4.5.4-1-default
感觉重新安装 VirtualBox 可能有效果,
# zypper in -f virtualbox
这个 -f 就是强制重新安装已经安装的程序的意思(大概相当于 Debian 里的 dpkg-reconfigure,见这里)
但是并没有什么用!
后来发现,原来是这一次新发布了 VirtualBox 的两个组件,
virtualbox-host-kmp-default
virtualbox-guest-kmp-default
版本都是 `5.0.18_k4.6.0_1-2.3`,完完全全就是针对 kernel 4.6.0 的。而且没法通过 YaST2 从 openSUSE-Tumbleweed-Oss 源回退到之前版本。看来得解决新内核的问题才行。
然后进一步查看 openSUSE-Tumbleweed-Oss 源的内容发现有 VirtualBox 的针对 4.5.4 内核的版本:
virtualbox-5.0.18-2.1.x86_64.rpm
virtualbox-qt-5.0.18-2.1.x86_64.rpm
virtualbox-host-kmp-default-5.0.18_k4.5.4_1-2.1.x86_64.rpm
指定版本号安装一下试试看,
# sudo zypper in virtualbox-5.0.18-2.1 virtualbox-qt-5.0.18-2.1 virtualbox-host-kmp-default-5.0.18_k4.5.4_1-2.1
Package 'virtualbox-5.0.18-2.1.x86_64' not found.
Package 'virtualbox-host-kmp-default-5.0.18_k4.5.4_1-2.1.x86_64' not found.
Package 'virtualbox-qt-5.0.18-2.1.x86_64' not found.
Resolving package dependencies...
Nothing to do.
貌似不是这么装的,rpm 安装试试看,
# sudo rpm -i http://download.opensuse.org/tumbleweed/repo/oss/suse/x86_64/virtualbox-host-kmp-default-5.0.18_k4.5.4_1-2.1.x86_64.rpm http://download.opensuse.org/tumbleweed/repo/oss/suse/x86_64/virtualbox-5.0.18-2.1.x86_64.rpm http://download.opensuse.org/tumbleweed/repo/oss/suse/x86_64/virtualbox-qt-5.0.18-2.1.x86_64.rpm
可是有个什么 .so 文件不对。
最后的方法是先移除新内核,此时会同时卸载针对新内核的版本的 VirtualBox,然后再重新安装 VirtualBox 即可。感觉应该可以(因为试过的是后一个方法)直接从命令行使用 rpm 安装,但是忽略掉那个 libdevmapper.so 的依赖错误,
# sudo rpm -i --nodeps http://download.opensuse.org/tumbleweed/repo/oss/suse/x86_64/virtualbox-host-kmp-default-5.0.18_k4.5.4_1-2.1.x86_64.rpm http://download.opensuse.org/tumbleweed/repo/oss/suse/x86_64/virtualbox-5.0.18-2.1.x86_64.rpm http://download.opensuse.org/tumbleweed/repo/oss/suse/x86_64/virtualbox-qt-5.0.18-2.1.x86_64.rpm
而且实际上将其中的 virtualbox 和 virtualbox-qt 改成后缀 2.3 的版本也没问题。
我测试过的安装过程还有点讲究:
先使用 rpm 从命令行安装 virtualbox-host-kmp-default-5.0.18_k4.5.4_1-2.1.x86_64,
# sudo rpm -i http://download.opensuse.org/tumbleweed/repo/oss/suse/x86_64/virtualbox-host-kmp-default-5.0.18_k4.5.4_1-2.1.x86_64.rpm
然后在 YaST2 的软件管理中将该软件包锁定(不让它升级),
再勾选 VirtualBox 来安装(只勾这一个,剩下的会自动勾选),但是要特意将自动勾选的 virtualbox-guest-kmp-default-5.0.18_k4.6.0_1-2.3 *取消勾选*,如果有 kernel-default-base 这个,也需要取消勾选。
安装即可。
嗯,对了,完了可能还需要进行下面的操作,
sudo rcvboxdrv setup
sudo systemctl start vboxdrv
反正是终于有个能用的 VirtualBox 了。最近打算不再升级内核了,我已经将 4.5.4 版本内核的包都给加上锁了 :D
移除新内核
移除新内核相关软件包,
# zypper rm kernel-default-4.6.0-1.1 kernel-default-base-4.6.0-1.1 kernel-default-devel-4.6.0-1.1 kernel-devel-4.6.0-1.1 kernel-syms-4.6.0-1.1
The following 8 packages are going to be REMOVED:
kernel-default-4.6.0-1.1 kernel-default-devel-4.6.0-1.1 kernel-devel-4.6.0-1.1
kernel-syms-4.6.0-1.1 virtualbox virtualbox-guest-kmp-default virtualbox-host-kmp-default
virtualbox-qt
kernel-macros 虽然也是 4.6.0-1.1 版本,但是须保留,此包是给 kernel-default-4.5.4 用的。完成后重启计算机使内核变更生效即可。再启动默认就是 kernel 4.5.4 的了。
期待下次内核更新能解决 kernel 4.6.0 在我的 ThinkPad T420s 上无法工作的问题吧。
更新 2016.06.11
昨天的后继更新包含了 kernel 4.6.1。我没有更新 kernel 的那几个包,但还是更新了别的。然后就碰到了一个莫名其妙的问题:
插上 U 盘就提示没有被授权挂载该设备(you are not authorized to mount this device);
重启后无线网络无法连接,点击 SSID 并输入密码后提示 “Could not add Connection – no session found for uid 1000″。
不能加载 U 盘也就算了,可是没有网络那就不好办事了。倒腾半天无法解决之后就决定重新安装,顺便改根分区为 Btrfs 文件系统。
后来发现,上面的问题有很大的可能性都是由一个叫 pam-config 的包造成的。具体可以看这个讨论列表。解决的办法似乎也简单,我没有试过,因为是在重装系统的过程中查到的资料,
sudo pam-config --add --systemd
而如果这个不能解决问题,至少还可以配置网络(在 YaST2 -> Network setting 中)改为由 wicked 管理(而不是默认的 NetworkManager),然后编辑无线网络的属性配置连接。甚至也许还需要手动在 /etc/resolv.conf 里加入域名解析服务器。