Linux操作系统共享链接库错误解决一例
不久前,笔者一位在银行工作的网管朋友给笔者打电话,说他的一台安装有数据库的Linux服务器无法启动,这台Linux服务器存储着银行非常重要的数据,请帮助解决。他告诉笔者这台Linux服务器(安装的是Red Hat 5.1,内核为2.0.34)一直运行得很好,不巧UPS出了问题,电源断电,再启动服务器,当启动到init,出现如下错误提示:
INIT:2.74 version booting
can’t find libc.so.6
然后就无法启动系统了。
投石问路
Linux下的共享链接库主要放在/lib目录下,以lib*.so.*为典型的文件名。Linux下的共享链接库对于Linux非常重要,几乎所有的程序都要调用共享链接库,类似于Windows下的*.dll文件。
笔者先进入单用户模式,在“LILO:”提示符下输入: Linux single,结果同样提示libc.so.6文件找不到!看来Linux调用共享链接库是在读取/etc/inittab文件之前。在这里笔者简单地介绍一下Linux的启动过程: Linux的启动首先要引导内核,然后进行设备检测,紧接着调用一个称为init的进程,该进程按照一定的规则,读取/etc/inittab文件的内容并且执行文件中的相关进程,指引系统进入某一特定的运行规则进程,也就是大家众所周知的6种模式:0为待机,1为单用户,2为多用户本机模式,3为多用户网络模式,4为系统保留,5为XWindows,6为重启。init进程首先调用共享链接库,由于共享链接库发生错误, 所以现在单用户模式也进不去,看来只有用启动盘和修复盘进入Linux的急救模式去试一试。于是笔者在另一台机器的DOS下,利用Linux光盘dosutils目录下的rawrite.exe程序制作了一张启动盘和一张修复盘,笔者先用启动盘引导系统,在“LILO: ”提示符下输入:rescue,直至系统提示笔者插入修复盘,进入急救模式。由于处于急救模式状况下,许多常用的命令不能用,而且由于只是将软盘中的内核映射到内存中,连根分区也没有挂上,而/lib目录正是在根分区上。笔者先挂上了根分区: mount -ext2 /dev/hda1 /mnt/hda1,进入/lib目录用ls命令查看,libc.so.6存在,于是怀疑是否是超级块或者节点出了问题,于是便用fsck命令(在急救模式状况下常规的ext2文件系统的检查命令e2fsck不可用):fsck -b 8193 /dev/hda1,然后退出重启,结果故障依旧,反复用fsck命令检查也无法解决。
柳暗花明
反复了几次之后笔者耐下性子,又到/lib目录下去仔细看了一下libc.so.6: ls -l libc.so.6,注意到:
lrwxrwxrwx 1 root root 13 Mar 10 03:32 libc.so.6 -> libc-2.?.7.so
原来libc.so.6文件只是libc-2.?.7.so文件的一个链接,看来此前笔者大意了。指向的链接名有一个“?”号,问题可能就出在这儿,init进程运行首先要调用libc-2.?.7.so所指向链接文件libc.so.6,init进程真正调用的是libc-2.?.7.so,而libc-2.?.7.so文件肯定是不存在的,那么到底应该是那个文件呢?再用ls查看,lib目录下有一个libc-2.0.7.so文件,这个文件才是真正指向libc.so.6的文件。笔者执行“rm -f libc.so.6, ln -s libc-2.0.7.so libc.so.6”,重新做了指向libc.so.6的正确链接,然后退出重启,结果故障仍然存在。