一台即将上线的主机被工程侧的兄弟在补漏洞时把glibc包给删除了,重启后导致主机启动出错,同事打过来电话求破解方法。这里记录下常见的修复模式修复的方法以便科普。

一、模拟故障现象

以下步骤请慎在现网环境上操作,这里只是模拟现网中经常发生的情况。登陆linux系统之后,依次执行以下命令人为破坏当前linux系统:

1# cd /
2# umount /boot                    ---卸载/boot分区
3# rm -rf /boot                    ---删除/boot目录(boot目录下包含所有GRUB有关的文件)
4# rm -rf /etc/inittab             ---删除init表(此文件定义了系统运行级别和脚本)
5# rm -rf/etc/rc.d/rc.sysinit     ---删除init运行级别脚本文件
6# rm -rf/etc/rc.d/rc.local       ---删除开机脚本文件
7# mv /etc/fstab/etc/fstab.bak    ---备份系统挂载表fstab文件(此文件记录了linux分区信息)
8# sync   ---将系统缓冲区的内容写入硬盘(在Linux系统中,当数据需要存入磁盘时,通常会先放到缓冲区内,等到适当的时刻再写入磁盘,如此可提高系统的执行效率)
9# reboot

经过这一番蹂躏之后,重启肯定是无法进入系统了。但是,只要根分区没有被格式化,就可以进入linux修复模式恢复该linux系统。

二、linux系统修复

1、光盘引导进入修复模式

通过redhat光盘引导进入安装选项界面时,输入linux rescue或按F5键进入rescue修复模式。

进入修复模式之后,系统会提示选择语言Language和键盘类型Keyboard,直接回车就行了。系统会再次询问是否配置网络,选择No,因为修复系统不需要用到网络。 Rescue程序将查找当前硬盘上是否有已安装的linux系统,如果找到了的话,就自动挂载到/mnt/sysimage下。选择”Continue”继续,rescue程序会搜索硬盘是否存在已安装过的linux和硬盘分区,最终结果如下图:

搜索结果显示,找不到Linux分区,因为/etc/fstab文件被删除了,所以导致系统无法读取Linux分区,但是如果找到了,就将它挂到/mnt/sysimage里面,可以读写。选择”OK”确定之后,系统会进入到修复模式的shell下。

2、还原fstab文件

根据上面步骤得知,rescue程序无法找到硬盘分区,所以现在要做的事情就是恢复linux分区——也就是fstab文件(这个fstab文件在删除之前,有做过备份/etc/fstab.bak)。

#fdisk -l 查看磁盘分区

根据fdisk –l输出,得到系统分区有两个/dev/sda1和/dev/sda2。可使用e2label命令查看这两个分区的卷标

由上图中的卷标可得知/dev/sda1是/boot分区,而/dev/sda2无法查看,因为sda2是LVM分区。

使用命令激活LVM分区#lvm vgchange-ay 这个命令的作用就是告诉系统建立相关的device-mapper,这样就可以看到/dev下建立了/dev/mapper/VGname-LVname和/dev/VGname/LVname的设备文件和链接文件.

使用ls /dev/mapper命令可以看到VolGroup00-LogVol00(就是/根分区)和VolGroup00-LogVol01(就是swap分区)

注:有上面不难看出,对于故障恢复,在安装规划时给以便以识别的信息非常重要。

接下来,要挂载/根分区,并恢复fstab文件。

1# mkdir test                  ---建立一个空目录用于挂载分区
2# mount -t ext3 /dev/VolGroup00/LogVol00 /test      ---挂载包含根分区的LVM分区到test目录下

将系统原来的/根分区挂载到/test目录之后,就可以还原fstab.bak到fstab了!

#reboot —-重启系统

3、修复内核和grub

重启之后,按ESC键选择CDROM引导,输入linux rescue再次进入到修复模式。

此时再次进入到修复模式时,rescue程序将会找到fstab文件,也就是会找到linux分区!并且把损坏的原linux系统挂载到/mnt/sysimage下。并且rescue程序会提示你,可以使用#chroot(changeroot修改根目录)修改根目录,进入到原系统中。如下图所示:

选择OK之后,系统已经全部挂载到了/mnt/sysimage,如果想进去,敲入#chroot/mnt/sysimage,修改根目录为/mnt/sysimage,使用ls命令可以查看原系统里的文件和目录。使用exit可以退回rescue程序下,再次使用ls命令可以比较一下区别。

一般把处于resuce模式的系统称为伪系统,把#chroot/mnt/sysimage后看到的称为真正的系统。

接下来要修复内核文件:

1# exit          ---退回到resecu模式下
2# mount /dev/hdc /mnt/source      ---挂载光驱cdrom到/mnt/source目录
3# rpm -ivh /mnt/source/Server/kernel-2.6.18-164.e15.i686.rpm--root=/mnt/sysimage/ --force

安装完成后可以到/mnt/sysimage/boot目录下查看。

注:需要修复的三个内核文件在系统盘server目录下kernel-2.6.18.rpm软件包里,所以要挂载光盘之后并安装kernel软件包。

此时,内核已修复完成!再继续修复grub程序。。。

1# chroot /mnt/sysimage  进入到已损坏的linux系统中
2# grub-install /dev/sda   安装grub程序到/dev/sda
3# ls /boot/grub          查看grub目录下是否存在grub.conf文件。如果没有就手动编辑一个。
4# vim /boot/grub/grub.conf

手动编辑grub.conf文件内容如下:

1title CentOS (2.6.18-164.e15.x86_64)
2        root (hd0,0)
3        kernel /boot/vmlinuz-2.6.18-164.e15.x86_64 ro root=/dev/VolGroup00/LogVol00 rhgb quiet
4        initrd /boot/initrd-2.6.18-164.e15.x86_64.img

注:一些高版本里为:/boot/initramfs-2.6.32-431.29.2.el6.x86_64.img

保存退出。。。grub修复完成!

4、修复/etc/inittab等文件

查看inittab相关文件所属包

1# rpm -qf /etc/inittab         查询包含inittab文件的软件包
2# rpm -qf /etc/rc.d/rc.sysinit   查询包含rc.sysinit文件的软件包
3# rpm -qf /etc/rc.d/rc.local   查询包含rc.local文件的软件包

经过rpm –qf查询命令可得知,要修复的文件都包含在initscripts-8.45.rpm这个软件包里面。下一步,要把文件从这个RPM里面分离出来,并还原到/etc目录下.

 1# exit
 2# cp /mnt/source/Server/initscripts-8.45.30-2.el5.i386.rpm   /mnt/sysimage/tmp
 3# chroot /mnt/sysimage
 4# cd tmp/
 5# ls
 6# rpm2cpio initscripts-8.45.30-2.el5.i386.rpm  |cpio -imd    解压软件包到当前目录
 7# cd etc/
 8# ls
 9# cp inittab /etc/
10# cp rc.sysinit /etc/rc.d/
11# cp rc.local /etc/rc.d/

最后只需要reboot就可以正常进入到linux系统了!