此文对平时测试过程中由不同原因导致Linux系统启动失败这个结果做一些分析并给出解决方案。
(注:此文中的“系统”专指RHEL4 Linux操作系统,内核版本:2.6.9-42。)
当执行fsck命令时,fsck命令如果发现存在孤立的文件或目录,这些孤立的文件或目录对于系统管理员或用户来说,无法访问到它,因为它与它的上级目录失去了关联,如果用户允许fsck重新把它们找回来的话,fsck命令就会把这些孤立的文件或目录放在文件系统的/lost+found目录下,并用各自的inode号来命名,以便用户查找自己需要的文件。
因此当某个用户发现自己丢失了某个文件,可以在执行fsck之后到/lost+found目录下去查找,这时通过文件名已无法辨认出文件的作用,只能用file之类的命令来确定文件的类型,如果是数据文件,可以用more或vi命令来查看,如果是二进制文件,可以用dbx命令来调试或者试着执行它(注意它可能是一个具有破坏性的程序),知道文件或目录的作用之后,可以对其进行改名。
如果用户不允许fsck把这些孤立的文件或目录找回来,那么fsck命令就会破坏这些文件或目录,彻底丢失这些文件或目录,用户或系统管理员永远也无法找回它们。
如果需要读或写分区的服务检测到分区坏或只读时会对该分区进行fsck动作,以期使分区能够完整保存原来的文件。但在测试过程中发现系统执行fsck命令时失败,并报告0x20错误。
没有加载swap分区。
1) fdisk –l找到swap分区/dev/sda2
2) swapon /dev/sda2,使能swap分区
3) 对需要进行fsck的分区手工执行fsck动作。
4) fsck完成后,编辑文件/etc/sysconfig/dump
## Type: list(0,1) ## Default: 1 # DUMP_ACTIVE indicates whether the dump process is active or not. If this # variable is 0, the dump kernel process will not be activated. # DUMP_ACTIVE="1" 更改上一行为: DUMP_ACTIVE="0" |
5) 重启系统。
(注:若系统中无swap分区,可以先在一块空闲分区上dd一个块,然后通过mkswap命令把该块转为swap系统,最后执行swapon把swap系统挂载到系统。)
使用dd命令对放在CF卡中的系统进行镜像拷贝备份保存,下次使用时重新把备份文件通过dd命令到CF卡即可。问题出现的场景是拷贝备份前的系统中保存着外挂存储分区信息,dd备份后放到没有外挂存储的系统上,系统启动时就要对备份中保存的外挂存储分区进行fsck检查,结果肯定是失败的。
系统启动时对不存在的分区进行fsck,启动过程失败。
最好的解决方法就是把不存在的分区信息从系统中删除。
linux的ext3文件系统中有一个备份超级块,可以尝试用备份的超级块加载根文件系统并对文件系统进行修复。
备份的超级块信息可以通过以下命令获得:
(注:这个命令模拟ext3文件系统创建时的动作并打印出备份超级块的位置,给出的位置缺省是以4k为单位的,mount在使用时需要为它提供以1k为单位的偏移,需要乘4。一定要使用“-n”作为参数模拟 ext3文件系统的创建而不是真的创建ext3文件系统)
mkfs.ext3 -n /dev/hda1
使用备份的超级块来加载 ext3文件系统的命令:
语法:mount.ext3 -o sb=n
mount.ext3 -o sb=131072 /dev/hda7 /media/hda7
使用备份的超级块来修复 ext3文件系统的命令:
语法:fsck.ext3 -b superblock
fsck.ext3 -b 32768 /dev/hda1
修复完成后重启系统,问题解决。
Linux操作系统ext2文件系统为工作平台。系统在写磁盘分区时断电后重启,由于ext2没有日志系统,系统启动过程中fsck不能完成磁盘的完全修复,ext2文件系统启动引导过程不能完成,致使机器不能恢复工作。
断电后,系统重启,系统提示:
During the first boot, it dropped into shell when it was checking the filesystem. Checking file systems /opt/db contains a file system with errors, check forced. Error reading block 131076 (Attempt to read block from filesystem resulted in short read) while doing inode scan.
/opt/db: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY. (i.e., without -a or -p options) [FAILED] *An error occured during the file system check. Dropping you to a shell;the system will reboot. Give root password for maintenance. or type control D for normal startup.
|
在采用了ext3文件系统后,此问题出现几率明显降低。
下面将对无日志系统的ext2文件系统和有日志系统的ext3文件系统做简单的对比分析后给出此问题的解决方法。
ext2主要考虑的是文件系统的效率和性能方面的问题。ext2在写入文件内容的同时并没有同时写入文件的元数据(即meta-data,和文件有关的信息,例如:权限、所有者以及创建和访问时间等)。换句话说,Linux先写入文件的内容,然后等到有空的时候才写入文件的meta-data。如果在写入文件内容之后但在写入文件的meta-data之前,突然断电了,文件系统就会处于不一致的状态。在一个需要大量文件操作的系统中(例如,像Hotmail这样的免费的Web e-mail),出现这种情况会导致很严重的后果。
假定系统正在更新一个目录项(directory entry),且已经在这个巨大的目录项的第五个文件块(block)中改变了23个文件项(file entry),正在写这个文件块的时候突然间断电了,这个文件块还没有写完,也就是被损坏了。
重新启动的时候,系统会运行“fsck”(file system check)的程序,扫描整个文件系统,保证所有的文件块都被正确地分配或使用。它将找到这个被损坏的目录项并试图修复它,但是fsck不能够保证一定能够修复损坏的目录项。所以,当出现上面那种情况,目录项中所有的文件项可能会丢失,也就造成文件的丢失。
1. 日志文件系统则是在非日志文件系统的基础上,加入了文件系统更改的日志记录。
日志文件的设计思想是:跟踪记录文件系统的变化,并将变化内容记录入日志。日志式文件系统的思想来自于大型数据库系统。数据库操作由多个相关的、相互依赖的子操作组成,任何一个子操作的失败都意味着整个操作的无效性,所以,对数据的任何修改都要求回复到操作以前的状态。日志式文件系统采用了类似的技术。
日志文件系统在磁盘分区中保存有日志记录,写操作首先是对记录文件进行操作,若整个写操作由于某种原因(如系统掉电)而中断,系统重启时,会根据日志记录来恢复中断前的写操作。这个过程只需要几秒钟到几分钟。
2. 日志文件系统是如何工作的?
在日志文件系统中,所有的文件系统的变化、添加和改变都被记录到“日志”(即记录文件元数据信息)中。每隔一定时间,文件系统会将更新后的文件元数据及文件内容写入磁盘,之后删除这部分日志,重新开始新日志记录。
在对元数据做任何改变以前,文件系统驱动程序会向日志中写入一个条目,这个条目描述了它将要做些什么。然后,它继续并修改元数据。通过这种方法,日志文件系统就拥有了近期元数据被修改的历史记录,当检查到没有彻底卸载的文件系统的一致性问题时,只要根据数据的修改历史进行相应的检查即可了。即日志文件系统除了存储数据和元数据(metadata)以外,它们还保存有一个日志,可以称之为元元数据(关于元数据的元数据)。
日志文件系统使得数据、文件变安全了,但是系统开销加大了,每一次更新和大多数的日志操作都需要写同步,这需要更多的磁盘I/O操作。
3. 使用日志文件系统有什么好处?
文件的安全提高了,文件被破坏的机率降低了,对磁盘的扫描时间缩短了,扫描次数减少了。当系统意外宕机后,不会再有文件内容的丢失,至少文件应该保持上一个版本的内容;采用日志文件系统,通常系统每重新启动20-30次后,才会对磁盘进行一次整体扫描,扫描次数减少了。
fsck 的工作就是确保要装载的文件系统的元数据是处于可使用的状态。通常情况下,当Linux系统启动时,首先运行fsck,由它扫描/etc/fstab文件中列出的所有本地文件系统;当系统关闭时,fsck又把所有的缓冲区数据转送到磁盘,并确保文件系统被彻底卸载,以保证系统下次启动时能够正常使用。
然而意想不到掉电或者其它故障会导致系统死机、重启。出现这种情况时,操作系统来不及卸载文件系统。重启后,fsck对磁盘进行彻底扫描,全面地检查元数据,竭尽全能修正检查过程中能找到的所有错误,对所有的元数据做彻底的一致性检查极其耗时。文件系统越大,完成彻底的扫描时间就越长。fsck也会碰到它无法修复的磁盘错误,碰到这种情况,就是简单地将文件删除或另存为一个文件。在高密度访问的数据中心,fsck可能会造成极大的数据文件破坏。只有当fsck完成扫描、检查与修复工作后,Linux系统才能开始使用。当然,如果有严重的文件或数据丢失的话,系统很可能无法重新启动了!
解决问题总的思路是把无日志系统的ext2文件系统加上日志系统,使其成为ext3文件系统。具体方法如下:
1. 对系统的根分区进行ext2到ext3的转变。
[root@VIComputer V1R2SP1]# tune2fs -j /dev/sdb1 tune2fs 1.35 (28-Feb-2004) Creating journal inode: done This filesystem will be automatically checked every -1 mounts or 180 days, whichever comes first.Use tune2fs -c or -i to override. |
2. 在文件/etc/fstab中修改根分区属性为ext3
[root@VIComputer etc]# vi fstab # This file is edited by fstab-sync - see 'man fstab-sync' for details LABEL=/ / ext3 defaults 1 1 none /dev/pts devpts gid=5,mode=620 0 0 …… |
3. ext2文件系统转化为ext3后,编译启动镜像。
根据系统对处理器的支持数,系统有单核和多核(包含SMP,对称多处理机制)之分,所以在编译启动镜像前需要确定系统运行模式。
1) 确认系统是否是多核的方法如下:
cat /proc/cpuinfo | grep processor,显示如下即为多核:
processor : 0
processor : 1
2)确认当前系统是运行在单核模式还是双核模式的方法如下:
[root@LINUX ~]# uname -a,显示的信息有两种:
l 多核:Linux 2.6.9-42.ELsmp #1 SMP Sat Aug 12 09:39:11 CDT 2006 i686 i686 i386 GNU/Linux
l 单核:Linux 2.6.9-42.EL #1 Sat Aug 12 09:17:58 CDT 2006 i686 i686 i386 GNU/Linux
提示: 启动时设置系统运行模式方法如下: 重启系统,系统启动界面上显示读取内存、cpu、磁盘信息后,敲击回车键,进入启动镜像选择界面,选择镜像。 |
3)启动镜像制作方法:
如果系统当前是运行于双核模式,可以只对其进行xxx.ELsmp镜像制作;同理,如果系统当前运行于单核模式,可以只对其进行xxx.EL镜像制作,其中xxx是内核版本号。
l 运行于单核模式下时:
[root@LINUX ~]# cd /boot [root@LINUX boot]# mv initrd-2.6.9-42.EL.img initrd-2.6.9-42.EL.img.bak [root@LINUX boot]# mkinitrd initrd-2.6.9-42.EL.img 2.6.9-42.EL [root@LINUX boot]# rm -fr initrd-2.6.9-42.EL.img.bak |
l 运行于多核模式时:
[root@LINUX ~]# cd /boot [root@LINUX boot]# mv initrd-2.6.9-42.EL.img initrd-2.6.9-42.EL.img.bak [root@LINUX boot]# mkinitrd initrd-2.6.9-42.ELsmp.img 2.6.9-42.ELsmp [root@LINUX boot]# rm -fr initrd-2.6.9-42.ELsmp.img.bak |
4. 重启系统,验证根目录系统属性是否为ext3:
l 通过mount命令检查根目录的系统属性
[root@LINUX conf]# mount /dev/hda1 on / type ext3 (rw) none on /proc type proc (rw) none on /sys type sysfs (rw) |
l 通过文件/proc/mounts检查根目录的系统属性
问题重现的几率大大的降低,因此此方法只能作为问题的规避方法。
在一次测试中把RHEL4光盘挂到系统并更改了系统的一些配置,把原来的initrd文件重命名后把重新生成了initrd文件拷贝到/boot下,但忘记把initrd更改回原来的名字。在重启系统后,系统提示:
root (hd0,0)+ Filesystem type is ext2fs, partition type 0x83 kernel /bzImage ro root=LABEL=/ ... Error 15: File not found Press any key to continue... |
原因是/boot/grub/grub.conf文件并未做修改,系统试图从修改前的镜像启动,但是原来的镜像文件又被重命名了,导致启动内核镜像无法找到。
1) 按任意键回到启动菜单,如grub的菜单。
2) 在菜单界面按'c'进入grub命令行界面。
3) 在grub命令行下输入:
grub>root (hd0,0)
回车。会得到Filesystem的提示。
4) 继续在grub命令行下输入:
grub>kernel (hd0,0)/boot/
不回车然后按tab键,会显示可选的内核镜像。
继续在未完成的命令后输入有效地内核镜像名,如:
grub>kernel (hd0,0)/boot/vmlinuz-2.6.9-42.ELsmp ro root=LABEL=/ vga=0x317
回车。
会得到一行提示信息。
(注:输入过程中按tab可以获得提示,后面的root和vga参数要自己确定,可在grub菜单里选择某一项按”e”查看和参考已有设置。)
5) 继续在grub命令行输入:
grub> initrd (hd0,0)/boot/initrd-2.6.9-42.ELsmp.img
回车。(同样可以在输入过程中按tab获得提示)
6) 最后在grub命令行中输入boot(不是reboot)启动系统:
grub> boot
7) 等待系统启动,问题解决。
系统启动失败原因众多,如BIOS版本不匹配、找不到启动镜像、自检不通过、某些关键服务启动失败等,涉及Linux系统的方方面面。本文描述的问题多是与系统对分区的fsck不能完成导致启动失败,而fsck不能完成又是由不同原因引发,所得启示就是对同一问题的现象或结果需要做仔细分析找出问题根源并试图解决,这样在解决问题的同时也提升了自己。