网管小贾 / sysadm.cc
前几天偶然碰到了 Linux 系统无法正常引导的问题,一台之前还好端端服务器就这样趴窝了。
我对系统引导这块可以说是一穷二白,因此自然产生了毫无悬念的结局,我被这个问题搞得晕头转向、七荤八素,完全找不着北。
Linux 系统通常是用作服务器,一般情况下很少重启或关机,可是一旦重启失败,那必将是一场灾难。
为了避免以后再遭遇无法修复引导的尴尬场面,于是乎我下定决心,重新捋一遍系统引导修复的功课。
由于 Linux 系统都大同小异,其引导原理也差不太多,这里暂且以 Rocky Linux 为例,RedHat/CentOS 系可直接参照,而 Debian/Ubuntu 等系也万变不离其宗。
我们就以实际运用为主,先解决问题,有时间再来细究理论与原理吧,走起!
事先安装好一套 Rocky Linux 系统,确保能正常启动和使用。
然后将 /boot 目录下的所有文件和目录统统删除(删库跑路的可以在这儿找点感觉哈)。
rm -rf /boot/*
/boot/efi 这个目录有可能是因为直接建立在 /dev/sda1 电脑 上了,所以可能无法被删除,不过其目录中也会被清空。
删除过后我们重启系统,就会发现无法正常启动了。
由于本系统(和 CentOS 8 一样)是使用的 EFI 的启动方式,所以启动画面直接进入了 EFI Shell 。
好,准备工作差不多了,接下来我们开始尝试修复它。
注意,本文有别于传统的修复非 EFI 方式的系统引导哦,我们直接整 EFI 的!
找来原始安装光盘,用这个光盘启动,选择进入救援模式。
注意,光盘系统版本应该与当前系统版本一致疗效最佳。
启动后选择 Troubleshooting --> 。
再选择 Rescue a Rocky Linux system 。
进入救援前的提示信息,在这儿我选 1 继续,其他选项好像只给看看不让你动手啊!
为了修复原系统,我们必须切换(挂载)到原系统上才能再进行后续的修复操作。
我们选择继续救援模式后,它会接着自动帮我们找到当前系统的根目录,然后提示我们可以通过以下命令挂载根目录。
这时我们只要回车,然后执行命令即可进入我们需要修复的当前系统了。
chroot /mnt/sysroot
这里我要插播一条踩坑消息,有时救援系统未必能成功找到当前系统的根目录。
如果是这样就比较电脑麻烦了,甚至像我这种小白可能就修复不了了。
这种情况下,有一种可能是,当前系统分区使用了 LVM 逻辑卷组的原因。
那么我们就应该先尝试激活后再挂载它。
如果你成功看到了提示,让你直接 chroot ,那么恭喜你,你可以直接进行修复作业了。
像我平时用于测试,偷懒安装 Linux 时,会选择让安装程序自动分区,这样往往就会导致分区变成了 LVM 的样子。
当然,还有一些特殊场合,比如有些人希望以后能有机会动态增加分区容量等,那么就会事先采用 LVM 的形式。
不论是哪种情况,如果的确用了 LVM ,那么只能先把它找出来,然后再对它进一步操作。
这里有一个友情提示,即使是使用了 LVM ,通常救援系统也能很好地识别,所以只有在不正常识别的情况下才需要我们手动去将它找回来。
如果系统提示可 chroot 挂载,请忽略本节直接进入下一节即可。
lvdisplay
从输出结果中可以看到,有两个逻辑卷,一个是交换分区,一个是根分区。
此外我们也可以看到卷组的名字叫作 rl ,这个是我默认安装时系统自动起的名字,暂且记住它,一会有用。
lvm vgscan
和前面查看的信息一致,卷组就叫 rl 。
# lvm vgchange -ay 卷组名称lvm vgchange -ay rl
注意,命令最后要写上前面查看到的卷组的名字,本例中刚才我们获取到的是 rl 。
从输出结果中我们得知卷组 rl 中有两个逻辑卷被激活,这两个就是前面我们查看过的 swap 和 root 两个分区。
是不是真的被激活了呢?
我们可以在执行此命令之前,先查看一下 /dev 下的设备名称。
如图示,前后对比之下,很容易发现的确多出来一个叫作 rl 的家伙,不用多说,就是那个谁了。
# mount /dev/卷组名称/root 挂载点mount /dev/rl/root /mnt/sysimage/
挂载前 /mnt/sysimage/ 下啥都木有,挂载后原系统上的文件都粗线了!
chroot /mnt/sysimage/
注意啦!自动识别挂载路径是 /mnt/sysroot ,和我们手动识别挂载路径 mnt/sysimage ,意思是一样的。
成功进入当前系统后,我们还需要网络的加持,因为等会还需要通过网络来修复安装一些必要的组件。
虽然使用光盘来安装一些组件也是可行的,但是太麻烦了,谁会放着方便不用呢,用光盘来装的都是有钱有闲的二代哈,我可不是哦!
手动设定网卡,以保证能访问网络。
# 查看当前网卡信息ip addr show
我们可以从图中看到,网卡设备名称是 enp0s3 ,实际以你查看到的为准,另外状态是 UP 启动状态。
# 确保启用了网卡,本例网卡名称为 enp0s3ip link set dev enp0s3 up
如果网卡状态是 DOWN 禁用状态,那么就用这条命令启用它。
当然了,通常接上网线的话网卡应该是启用状态,所以别忘记接网线哦!
# 设定IP地址,最后的网卡名称按实际情况修正# 本例IP地址为 192.168.1.123/24 ,网卡名称为 enp0s3ip addr add 192.168.1.123/24 dev enp0s3# 设定网关,本例为 192.168.1.1ip route add default via 192.168.1.1
命令完成后,尝试 ping 一下确认网络是否连接正常。
如果有一些传输文件之类的工作要做的话,可以开启 sshd 。
不过这并不是必选项,视实际需求来吧。
/usr/sbin/sshd -D &
安装 grub2-efi 将会在 usr/lib/grub/ 下生成一些所需的库文件,比如 x86_64-efi 。
而 shim 则是 shimx64.efi ,用于安全启动,否则使用 grubx64.efi 。
dnf reinstall grub2-efi shim
完全可以安装指定版本的 kernel ,只要在后面加上版本号就行了。
你可以手打版本号,也可以用 $(uname -r) 来指定。
# 查看内核版本号# 比如输出:4.18.0-305.3.1.el8_4.x86_64uname -r# 列出可安装的内核版本# 比如有两个版本:一个是 4.18.0-305.3.1.el8_4,另一个是 4.18.0-305.12.1.el8_4dnf list kernel# 安装指定版本的内核dnf reinstall "kernel-*-$(uname -r)"# 或者分别安装dnf reinstall "kernel-headers-$(uname -r)"dnf reinstall "kernel-core-$(uname -r)"dnf reinstall "kernel-modules-$(uname -r)"
我测试的结果是,我只安装了 kernel-core 就成功修复了。
如果你嫌麻烦,也不计较当前系统里会装太过多的东西,那么像下面这样来个简单粗暴的也行。
dnf reinstall kernel*
安装完成后,我们立马就可以看到 /boot 目录下的几个久违的子目录都回来了。
但是要注意哈,我们也能看出来,关键的 grub.cfg 并没有粗线,所以先不要激动,还得继续努力哈!
发行版名称是指当前系统的 Release ,比如 redhat 或 centos 等等。
# grub2-mkconfig -o 输出目录/grub.cfg# grub2-mkconfig -o /boot/efi/EFI/发行版名称/grub.cfggrub2-mkconfig -o /boot/efi/EFI/rocky/grub.cfg
如果没有报什么错误的话,你就可以大大方方地重新启动了,不出意外的话,启动菜单项就都回来了!
如果你安装有不同版本的 kernel 的话,那么启动项会变得多出几项,不过也不影响启动系统啦。
前面的内容可以简单压缩成三个步骤:
设定网络,保证可以使用 YUM 或 DNF 或 APT 等。安装 grub2-efi 和 shim 。安装 kernel 及其组件。小伙伴们,你们测试成功了没?
虽然我们可以通过这些相对固定的操作来修复引导,但是个人感觉还是要掌握好系统引导的原理才来得实在些,所以今后我会将原理这块完善起来。
另外我想说的是,通常 Linux 的引导系统不会无缘无故的损坏,可是一旦故障,带来的麻烦可就不是闹着玩的了。
而故障发生后,首先做的不是去考虑如何修复它,而应该及时备份或将系统中数据尽快转移至他处,修复系统总是有风险的,我们得给自己留条退路。
我个人的感觉是,往往出现此类故障,要将它修复成功,就要有接受修复失败的心理准备。
就像我之前修复过的一个带有 LVM 的系统,它无法直接识别并挂载系统,然后我手动挂载后又各种缺目录缺文件,可以说是痛苦至极,最后也没给搞定。
希望小伙伴们有空就以本文为参考,先练习一下如何修复引导,以后也好有备无患。
好了,啰嗦太多时间了,老板叫我去准备一下换套服装,在机房摆个香案,每日三炷香,祈求神明保我服务器风调雨顺、平安无事。
嗯,你们猜猜看,我穿的衣服是无量天尊,还是阿弥陀佛?!
网管小贾 / sysadm.cc
电脑