Linux系统启动流程之(3)系统故障修复之二

通过上一篇可以了解如何来重新安装grub从而修复grub引导,那么如果损坏的不仅仅为grub引导,如果还出现了其它更为严重的问题呢。下面几个案例来说明:

 

案例一:

通常系统服务运行之前会运行init程序来开启第一个进程,那么如果init被删除呢?

#删除或者移动init程序到别处

[root@mzf ~]# which init
/sbin/init
[root@mzf ~]# mv /sbin/init /testdir/
[root@mzf ~]# which init
/usr/bin/which: no init in (/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/apache2:/root/bin)

#然后重启系统,进入grub菜单选择一个进入系统的引导项,直接按c进行交互式grub设置在kernel内核参数后面设置init=/bin/bash表示以bash进程来当作第一个进程:

wKioL1ffdeKDu6JBAAAZqJrTHf0687.png 

解析:grub交互界面虽然只能修复bootloader及第一阶段,但是里面却提供了很多命令来帮助修复,比如使用find可以对猜测有boot引导文件的分区进行查找,这里查找此目录下有vmlinuz虚拟根文件系统和initramfs内核加载及切换器,可以判断(hd0,0)极有可能就是需要恢复的boot分区,当然如果有多个也就逐一排查。

#进入指定的启动进程/bin/bash,然后将刚才移动到其他分区的init程序移回来

1、挂载刚才移动到init程序的目标分区

mount -n -o rw /dev/sda5 /testdir/

2、重新以指定方式挂载根

mount -o remount,rw /

3、拷贝此文件到原来的路径

cp /testdir/init /sbin/

4、查看init命令是否在/sbin/init下

which init

注意:这里是通过grub命令行模式下指定的内核参数进入到的/bin/bash,因此也只挂载了内核参数中root根分区,所有要进行重新挂载对应的其它分区,然后将文件还原就行了。

 

 

案例二:

假设/boot分区下的所有文件丢失,也就没有grub引导加载的所有阶段了。

#查看当前/boot已经是否被挂载

[root@mzf ~]# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda2       10190136 2803944   6861904  30% /
tmpfs             502068       0    502068   0% /dev/shm
/dev/sda1         194241   34109    149892  19% /boot
/dev/sda5        7922096   18280   7494728   1% /testdir

#直接删除/boot里的所有文件

[root@mzf ~]# rm -rf /boot/
rm: cannot remove `/boot': Device or resource busy#因为此文件夹还是挂载点,所有提示

#查看/boot目录下,发现已经没有任何文件了

[root@mzf ~]# ls /boot/

#卸载此目录

[root@mzf ~]# umount /boot/

#然后重启

[root@mzf ~]# reboot

 

具体修复过程:

1、使用光盘引导启动救援模式

进入救援模式提供的shell后入后先安装grub-install

 wKiom1ffduvDpECUAABEnqrKQ7k076.png

解析:

1、df查看当前分区是否已经挂载成功

2、挂载光盘的镜像,使用其中工具

3、切换到要安装grub的分区,也就是/dev/sda所挂载的/mnt/sysp_w_picpath目录

4、直接指定磁盘使用grub-install对/dev/sda完全安装grub

5、查看/boot/grub是否生成各个阶段文件

 

2、然后恢复vmlinuz

#输入exit退会到救援模式shell进程,然后查看刚刚挂载的光盘镜像文件目录

wKiom1ffdwSyhudqAAAaM49kqrU775.png 

解析:这时发现,在光盘的isolinux文件中已经提供了vmlinuz和initrd.img文件,甚至还有splash.jpg就是grub菜单文件已经grub.conf模板文件等,当然只需要绿框中指定的就行。

#拷贝vmlinuz到指定的目录下,就boot分区对应的目录

wKiom1ffdw_jWRtFAAAPuRsm9Pc558.png 

解析:因为刚才已经挂载了光盘,所有会得到很多命令工具,因此使用findmnt查看第一个分区及boot分区所在挂载点,当然也可以通过df查看;然后将光盘里保存的vmlinuz拷贝到指定挂载点/mnt/sysp_w_picpath/boot下即可。

 

3、然后恢复initramfs.img文件

#重新切换到boot挂载点,并使用mkinitrd根据当前kernnel信息来生成对应版本号的initrd文件

wKioL1ffdx6wgt9CAAAMz3Plvfg093.png 

解析:这里不去光盘里自身isolinux目录下去拷贝initrd.img。因为系统kernel里保存了内部版本信息,所有可以直接切回到boot分区挂载点来安装对应的版本,如果kernel升级过,使用此命令生成的也是对于版本的initramfs.img。

 

4、重新建立grub.conf配置文件

#虽然所选的各种文件都会恢复文件,但是grub.conf文件并未自动根据当前环境而自动生成,因此还需要根据当前环境进行手动编辑。

wKiom1ffdy2QVPTyAAAKmBc7Aaw502.png 

说明:因为vmlinuz从光盘镜像挂载点下的isolinux目录里命令就是vmlinuz而不带版本号,所有这里保持一致,直接路径即可。

#当然initramfs-`uname -r`.img这个文件名很长不好记忆,那么使用末行模式读入即可

wKioL1ffdzyCC4zxAAADh0vwbuU545.png 

#将指定需要的文件基名放到指定位置,并在kernel添加指定root分区的参数

wKiom1ffd0bTCAfhAAAKmBc7Aaw664.png 

注意:这里必须要指定root所在分区,kernel和initrd指定的参数必须和/boot目录下的文件名及路径所对应。

#下面重启系统。

reboot

#进入系统修复过程

wKioL1ffd1XSwPDcAAAM1gbObLM551.png 

然后等待系统修复完毕自动重启即可

 

 

案例三:

删除/boot下所有文件和/etc/fstab文件,并强制卸载当前kernel。然后通过救援模式来进行逐个恢复使系统正常使用。

 

逐一破坏过程:

#删除/boot下的所有文件

[root@mzf ~]# rm -rf /boot/*

#查看文件/boot下文件已经被清空

[root@mzf ~]# ls /boot/

#卸载boot分区

[root@mzf ~]# umount /boot/

#删除/etc/fstab文件

[root@mzf ~]# rm -f /etc/fstab

#忽律依赖关系直接卸载内核文件

[root@mzf ~]# rpm -e kernel --nodeps

#重启坏掉的系统

[root@mzf ~]# reboot

解析:以上的操作以及让主板无法找到boot分区,没有内核也就无法知道其内核版本,没有了/etc/fstab文件,即使是救援模式也无法检查其硬盘下挂载关系。

 

修复过程:

1、重启从光盘引导进入救援模式,修复分区表及文件系统探测

#安装以往的操作一种到救援模式自动检测分区的界面

wKiom1ffd8eQp7BtAAALYoEvUS0525.png 

解析:因为没有了/etc/fstab文件,救援模式下也无法知道对应的挂载关系。

#然后回车选择shell界面,df查看当前挂载情况

wKiom1ffd-fCgDsbAAAM_Voh3Tc779.png 

说明:此时已经确定救援模式也需要靠/etc/fstab文件来操作对应的分区以及其挂载关系。当然此文件被删除。

#为了检查分区的信息,这里挂载光盘镜像,来获取更多的命令工具

mkdir /mnt/cdrom  &&  mount /dev/cdrom /mnt/cdrom

wKioL1ffeCmSWPqNAAAGvrHtm6o296.png 

#使用blkid命令来查看当前磁盘的命令及对应UUID已经文件系统类型

blkid

wKioL1ffeD_g-ywtAAATo3EyJtY651.png 

解析:这里就发现了1个磁盘/dev/sda,已经4个分区,/dev/sda5可以猜测为逻辑分区,而一般系统会在主分区下,那么现在排除掉为交换分区的/dev/sda3,考虑的有/dev/sda{1,2,5}。

#下面进一步查看,使用parted工具来查看更详细的分区信息

wKiom1ffeEmzvVBNAAAa3EKvvlw811.png 

解析:通过parted命令打印出/dev/sda的详细文件系统类型以及其对应的特殊标记,从上面可以看出,只有2个主分区; 再次这可以发现Number列为1,及第一个分区的大小只有210MB,而Number列为2及第二个分区大小为11G左右,由此可以猜测boot所在第一个分区,且其对应的文件系统都为ext4,而/分区为第二个分区,为了确定,下面也可以使用fsdisk命令查看详细大小。

#进一步查看分区信息来推断,使用fdisk 命令

wKioL1ffeFOTOPvsAAAoOG8ApTQ382.png 

解析:因为检查到了boot为一个独立的分区,所有说要要救援模式下的系统来识别当前系统下的分区及挂载关系,那么至少需要填写两个挂载关系,及boot分区和根分区。

#根据以上信息来挂载boot分区和/根分区

wKioL1ffeL6CK5A5AAAYzS7vKYo947.png 

解析:只有对刚才猜测的分区提供了挂载点进行访问,那么下面才能通过查看其对应挂载点

下的文件列表来进一步推段。

#查看两个分区下的挂载点目录下文件列表

wKioL1ffeMiyLV3mAAAKLzYN6fM720.png 

解析:这里root分区可以断定是/dev/sda2了,但是/mnt/boot挂载点下并没有任何东西,

可能是因为此分区下文件已经被清除。于是编写/etc/fstab文件。

#在编写/etc/fstab文件,提供根分区和boot分区的对应挂载关系

wKiom1ffeNXA8ebwAAAFANuhmSg005.png 

#然后再次重启

reboot

 

2、检查分区及分区系统能否被救援模式识别且自动挂载

最后再次进入救援模式,一种根据以往的设置显示出此界面

wKioL1ffeOvjxMsRAAASiorCRas643.png 

解析:显示出此简明表示已经检查到了有一个存放系统的根分区,而且将会被挂载到/mnt/sysp_w_picpath下面。于是确定进入下一个界面。

wKiom1ffePXzkeoEAAAHSDeoEB8793.png 

说明:最终出现此界面说明根系统分区真的被挂载上了,于是下面回车并选择进入shell。

#在救援模式shell下面使用df查看当前文件系统对于的挂载点

wKiom1ffeRWy2ursAAAW_UynNKE201.png 

 

3、根据上面的挂载点对应关系,下面进行具体系统恢复

(1)根据上面的挂载点对应关系,下面开始安装内核

wKioL1ffeSmgT9d3AAAWJsbqUo4544.png

解析:这里必须先挂载光盘,因为需要的命令工具和软件包都在其中,然后切换到此目录后,使用rpm工具进行安装,因为的当前是在救援模式下引导的系统,所有,在安装时必须使用--root=选项来指定系统根分区的路径,及在哪个系统分区上安装此kernel包。当然,因为kernel是直接忽略依赖关系进行卸载,难免会清除一下残留记录,所以使用--replacepkgs表示直接重新安装。

 

(2)重建/boot分区所需的所有文件

#通过挂载的光盘将vmlinuz拷贝到boot分区挂载点下

wKiom1ffeV_xONtTAAAGpyFfjH8895.png 

#切换到真正的根文件系统分区

wKioL1ffeXizmldbAAADsr_52ag937.png 

#重新安装initramfs.img文件

wKiom1ffeZmyneoQAAAMBKLTnYw471.png 

解析:因为已经重新安装了kernel,那么使用uname -r命令查看的也会是与其相对于的版本。

#重新完全安装gurb

wKioL1ffecHRIVYHAAAjC_rn_vg550.png 

说明:此时boot分区里的所有grub引导所选要的阶段文件以及备份文件都已经生成完毕,但是任然缺少最后的一个grub.conf配置文件。

#重新编写grub.conf配置文件

在编写之前,为了让其更加回到原状,这里把vmlinuz文件后面添加内核版本号

wKioL1ffed3y6TBeAAAHU1a8Vd0719.png 

使用vim新建/boot/grub/grub.conf文件

wKiom1ffeezihzkyAAAMByPoor4634.png 

提示:这里再次提示,必须要指定根分区所在的分区,否则grub第2阶段无法进行根切换。

 

一起完成后检查一下,然后exit退回到救援模式shell,然后reboot重启

wKioL1ffehCyovfEAAAKkP_LdG0378.png

等待selinux修复

wKiom1ffeiKxQCz0AAAJWJ_BiWI474.png