Linux系统启动流程之(3)系统故障修复之二
通过上一篇可以了解如何来重新安装grub从而修复grub引导,那么如果损坏的不仅仅为grub引导,如果还出现了其它更为严重的问题呢。下面几个案例来说明:
案例一:
通常系统服务运行之前会运行init程序来开启第一个进程,那么如果init被删除呢?
#删除或者移动init程序到别处
[[email protected] ~]# which init /sbin/init [[email protected] ~]# mv /sbin/init /testdir/ [[email protected] ~]# 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进程来当作第一个进程:
解析: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已经是否被挂载
[[email protected] ~]# 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里的所有文件
[[email protected] ~]# rm -rf /boot/ rm: cannot remove `/boot‘: Device or resource busy#因为此文件夹还是挂载点,所有提示
#查看/boot目录下,发现已经没有任何文件了
[[email protected] ~]# ls /boot/
#卸载此目录
[[email protected] ~]# umount /boot/
#然后重启
[[email protected] ~]# reboot
具体修复过程:
1、使用光盘引导启动救援模式
进入救援模式提供的shell后入后先安装grub-install
解析:
1、df查看当前分区是否已经挂载成功
2、挂载光盘的镜像,使用其中工具
3、切换到要安装grub的分区,也就是/dev/sda所挂载的/mnt/sysimage目录
4、直接指定磁盘使用grub-install对/dev/sda完全安装grub
5、查看/boot/grub是否生成各个阶段文件
2、然后恢复vmlinuz
#输入exit退会到救援模式shell进程,然后查看刚刚挂载的光盘镜像文件目录
解析:这时发现,在光盘的isolinux文件中已经提供了vmlinuz和initrd.img文件,甚至还有splash.jpg就是grub菜单文件已经grub.conf模板文件等,当然只需要绿框中指定的就行。
#拷贝vmlinuz到指定的目录下,就boot分区对应的目录
解析:因为刚才已经挂载了光盘,所有会得到很多命令工具,因此使用findmnt查看第一个分区及boot分区所在挂载点,当然也可以通过df查看;然后将光盘里保存的vmlinuz拷贝到指定挂载点/mnt/sysimage/boot下即可。
3、然后恢复initramfs.img文件
#重新切换到boot挂载点,并使用mkinitrd根据当前kernnel信息来生成对应版本号的initrd文件
解析:这里不去光盘里自身isolinux目录下去拷贝initrd.img。因为系统kernel里保存了内部版本信息,所有可以直接切回到boot分区挂载点来安装对应的版本,如果kernel升级过,使用此命令生成的也是对于版本的initramfs.img。
4、重新建立grub.conf配置文件
#虽然所选的各种文件都会恢复文件,但是grub.conf文件并未自动根据当前环境而自动生成,因此还需要根据当前环境进行手动编辑。
说明:因为vmlinuz从光盘镜像挂载点下的isolinux目录里命令就是vmlinuz而不带版本号,所有这里保持一致,直接路径即可。
#当然initramfs-`uname -r`.img这个文件名很长不好记忆,那么使用末行模式读入即可
#将指定需要的文件基名放到指定位置,并在kernel添加指定root分区的参数
注意:这里必须要指定root所在分区,kernel和initrd指定的参数必须和/boot目录下的文件名及路径所对应。
#下面重启系统。
reboot
#进入系统修复过程
然后等待系统修复完毕自动重启即可
案例三:
删除/boot下所有文件和/etc/fstab文件,并强制卸载当前kernel。然后通过救援模式来进行逐个恢复使系统正常使用。
逐一破坏过程:
#删除/boot下的所有文件
[[email protected] ~]# rm -rf /boot/*
#查看文件/boot下文件已经被清空
[[email protected] ~]# ls /boot/
#卸载boot分区
[[email protected] ~]# umount /boot/
#删除/etc/fstab文件
[[email protected] ~]# rm -f /etc/fstab
#忽律依赖关系直接卸载内核文件
[[email protected] ~]# rpm -e kernel --nodeps
#重启坏掉的系统
[[email protected] ~]# reboot
解析:以上的操作以及让主板无法找到boot分区,没有内核也就无法知道其内核版本,没有了/etc/fstab文件,即使是救援模式也无法检查其硬盘下挂载关系。
修复过程:
1、重启从光盘引导进入救援模式,修复分区表及文件系统探测
#安装以往的操作一种到救援模式自动检测分区的界面
解析:因为没有了/etc/fstab文件,救援模式下也无法知道对应的挂载关系。
#然后回车选择shell界面,df查看当前挂载情况
说明:此时已经确定救援模式也需要靠/etc/fstab文件来操作对应的分区以及其挂载关系。当然此文件被删除。
#为了检查分区的信息,这里挂载光盘镜像,来获取更多的命令工具
mkdir /mnt/cdrom && mount /dev/cdrom /mnt/cdrom
#使用blkid命令来查看当前磁盘的命令及对应UUID已经文件系统类型
blkid
解析:这里就发现了1个磁盘/dev/sda,已经4个分区,/dev/sda5可以猜测为逻辑分区,而一般系统会在主分区下,那么现在排除掉为交换分区的/dev/sda3,考虑的有/dev/sda{1,2,5}。
#下面进一步查看,使用parted工具来查看更详细的分区信息
解析:通过parted命令打印出/dev/sda的详细文件系统类型以及其对应的特殊标记,从上面可以看出,只有2个主分区; 再次这可以发现Number列为1,及第一个分区的大小只有210MB,而Number列为2及第二个分区大小为11G左右,由此可以猜测boot所在第一个分区,且其对应的文件系统都为ext4,而/分区为第二个分区,为了确定,下面也可以使用fsdisk命令查看详细大小。
#进一步查看分区信息来推断,使用fdisk 命令
解析:因为检查到了boot为一个独立的分区,所有说要要救援模式下的系统来识别当前系统下的分区及挂载关系,那么至少需要填写两个挂载关系,及boot分区和根分区。
#根据以上信息来挂载boot分区和/根分区
解析:只有对刚才猜测的分区提供了挂载点进行访问,那么下面才能通过查看其对应挂载点
下的文件列表来进一步推段。
#查看两个分区下的挂载点目录下文件列表
解析:这里root分区可以断定是/dev/sda2了,但是/mnt/boot挂载点下并没有任何东西,
可能是因为此分区下文件已经被清除。于是编写/etc/fstab文件。
#在编写/etc/fstab文件,提供根分区和boot分区的对应挂载关系
#然后再次重启
reboot
2、检查分区及分区系统能否被救援模式识别且自动挂载
最后再次进入救援模式,一种根据以往的设置显示出此界面
解析:显示出此简明表示已经检查到了有一个存放系统的根分区,而且将会被挂载到/mnt/sysimage下面。于是确定进入下一个界面。
说明:最终出现此界面说明根系统分区真的被挂载上了,于是下面回车并选择进入shell。
#在救援模式shell下面使用df查看当前文件系统对于的挂载点
3、根据上面的挂载点对应关系,下面进行具体系统恢复
(1)根据上面的挂载点对应关系,下面开始安装内核
解析:这里必须先挂载光盘,因为需要的命令工具和软件包都在其中,然后切换到此目录后,使用rpm工具进行安装,因为的当前是在救援模式下引导的系统,所有,在安装时必须使用--root=选项来指定系统根分区的路径,及在哪个系统分区上安装此kernel包。当然,因为kernel是直接忽略依赖关系进行卸载,难免会清除一下残留记录,所以使用--replacepkgs表示直接重新安装。
(2)重建/boot分区所需的所有文件
#通过挂载的光盘将vmlinuz拷贝到boot分区挂载点下
#切换到真正的根文件系统分区
#重新安装initramfs.img文件
解析:因为已经重新安装了kernel,那么使用uname -r命令查看的也会是与其相对于的版本。
#重新完全安装gurb
说明:此时boot分区里的所有grub引导所选要的阶段文件以及备份文件都已经生成完毕,但是任然缺少最后的一个grub.conf配置文件。
#重新编写grub.conf配置文件
在编写之前,为了让其更加回到原状,这里把vmlinuz文件后面添加内核版本号
使用vim新建/boot/grub/grub.conf文件
提示:这里再次提示,必须要指定根分区所在的分区,否则grub第2阶段无法进行根切换。
一起完成后检查一下,然后exit退回到救援模式shell,然后reboot重启
等待selinux修复