Linux共享鏈接庫(kù)錯(cuò)誤解決一例
2024-07-21 02:37:39
供稿:網(wǎng)友
作者:四川省成都市體育學(xué)院 劉紀(jì)恩
不久前,筆者一位在銀行工作的網(wǎng)管朋友給筆者打電話,說(shuō)他的一臺(tái)安裝有數(shù)據(jù)庫(kù)的linux服務(wù)器無(wú)法啟動(dòng),這臺(tái)Linux服務(wù)器存儲(chǔ)著銀行非常重要的數(shù)據(jù),請(qǐng)幫助解決。他告訴筆者這臺(tái)Linux服務(wù)器(安裝的是Red Hat 5.1,內(nèi)核為2.0.34)一直運(yùn)行得很好,不巧UPS出了問(wèn)題,電源斷電,再啟動(dòng)服務(wù)器,當(dāng)啟動(dòng)到init,出現(xiàn)如下錯(cuò)誤提示:
INIT:2.74 version booting
can’t find libc.so.6
然后就無(wú)法啟動(dòng)系統(tǒng)了。
投石問(wèn)路
Linux下的共享鏈接庫(kù)主要放在/lib目錄下,以lib*.so.*為典型的文件名。Linux下的共享鏈接庫(kù)對(duì)于Linux非常重要,幾乎所有的程序都要調(diào)用共享鏈接庫(kù),類似于Windows下的*.dll文件。
筆者先進(jìn)入單用戶模式,在“LILO:”提示符下輸入:Linux single,結(jié)果同樣提示libc.so.6文件找不到!看來(lái)Linux調(diào)用共享鏈接庫(kù)是在讀取/etc/inittab文件之前。在這里筆者簡(jiǎn)單地介紹一下Linux的啟動(dòng)過(guò)程: Linux的啟動(dòng)首先要引導(dǎo)內(nèi)核,然后進(jìn)行設(shè)備檢測(cè),緊接著調(diào)用一個(gè)稱為init的進(jìn)程,該進(jìn)程按照一定的規(guī)則,讀取/etc/inittab文件的內(nèi)容并且執(zhí)行文件中的相關(guān)進(jìn)程,指引系統(tǒng)進(jìn)入某一特定的運(yùn)行規(guī)則進(jìn)程,也就是大家眾所周知的6種模式:0為待機(jī),1為單用戶,2為多用戶本機(jī)模式,3為多用戶網(wǎng)絡(luò)模式,4為系統(tǒng)保留,5為XWindows,6為重啟。init進(jìn)程首先調(diào)用共享鏈接庫(kù),由于共享鏈接庫(kù)發(fā)生錯(cuò)誤, 所以現(xiàn)在單用戶模式也進(jìn)不去,看來(lái)只有用啟動(dòng)盤和修復(fù)盤進(jìn)入Linux的急救模式去試一試。于是筆者在另一臺(tái)機(jī)器的DOS下,利用Linux光盤dosutils目錄下的rawrite.exe程序制作了一張啟動(dòng)盤和一張修復(fù)盤,筆者先用啟動(dòng)盤引導(dǎo)系統(tǒng),在“LILO: ”提示符下輸入:rescue,直至系統(tǒng)提示筆者插入修復(fù)盤,進(jìn)入急救模式。由于處于急救模式狀況下,許多常用的命令不能用,而且由于只是將軟盤中的內(nèi)核映射到內(nèi)存中,連根分區(qū)也沒(méi)有掛上,而/lib目錄正是在根分區(qū)上。筆者先掛上了根分區(qū): mount -ext2 /dev/hda1 /mnt/hda1,進(jìn)入/lib目錄用ls命令查看,libc.so.6存在,于是懷疑是否是超級(jí)塊或者節(jié)點(diǎn)出了問(wèn)題,于是便用fsck命令(在急救模式狀況下常規(guī)的ext2文件系統(tǒng)的檢查命令e2fsck不可用):fsck -b 8193 /dev/hda1,然后退出重啟,結(jié)果故障依舊,反復(fù)用fsck命令檢查也無(wú)法解決。
柳暗花明
反復(fù)了幾次之后筆者耐下性子,又到/lib目錄下去仔細(xì)看了一下libc.so.6: ls -l libc.so.6,注重到:
lrwxrwxrwx 1 root root 13 Mar 10 03:32 libc.so.6 -> libc-2.?.7.so
原來(lái)libc.so.6文件只是libc-2.?.7.so文件的一個(gè)鏈接,看來(lái)此前筆者大意了。指向的鏈接名有一個(gè)“?”號(hào),問(wèn)題可能就出在這兒,init進(jìn)程運(yùn)行首先要調(diào)用libc-2.?.7.so所指向鏈接文件libc.so.6,init進(jìn)程真正調(diào)用的是libc-2.?.7.so,而libc-2.?.7.so文件肯定是不存在的,那么到底應(yīng)該是那個(gè)文件呢?再用ls查看,lib目錄下有一個(gè)libc-2.0.7.so文件,這個(gè)文件才是真正指向libc.so.6的文件。筆者執(zhí)行“rm -f libc.so.6, ln -s libc-2.0.7.so libc.so.6”,重新做了指向libc.so.6的正確鏈接,然后退出重啟,結(jié)果故障仍然存在。
水落石出
可筆者總覺(jué)得判定是對(duì)的,又到lib目錄下去仔細(xì)看了一下libc.so.6這個(gè)文件:ls -l libc.so.6,結(jié)果如下所示:
lrwxrwxrwx 1 root root 13 Mar 10 03:32 libc.so.6 -> libc-2.?.7.so
看來(lái)剛才筆者所做的操作并沒(méi)有寫進(jìn)磁盤,于是筆者又重新做了剛才的操作。可這一次筆者老老實(shí)實(shí)地“umount /dev/hda1”,然后退出重啟,系統(tǒng)又重新正常啟動(dòng)了,再到lib目錄下去看了一下libc.so.6這個(gè)文件:ls -l libc.so.6,結(jié)果如下:
lrwxrwxrwx 1 root root 13 Mar 10 03:32 libc.so.6 -> libc-2.0.7.so
這回所做的修改寫進(jìn)了磁盤。看來(lái)問(wèn)題歸根結(jié)底是出在libc.so.6文件的鏈接問(wèn)題上,問(wèn)題總算解決了!
后 記
為什么非要做umount?在正常模式下沒(méi)做umount,所做的操作也能寫進(jìn)磁盤的。筆者查了一下資料才明白: Linux文件系統(tǒng)更新是一個(gè)復(fù)雜的過(guò)程,當(dāng)用戶程序?qū)ξ募到y(tǒng)進(jìn)行修改以后,例如進(jìn)行了寫操作,文件數(shù)據(jù)將修改記錄在內(nèi)核緩沖中,在數(shù)據(jù)沒(méi)有寫到磁盤的時(shí)候,依然能夠執(zhí)行用戶進(jìn)程,所有數(shù)據(jù)的改變都在inode的內(nèi)容中得到反映。磁盤的數(shù)據(jù)更新實(shí)際上是異步進(jìn)行的,很有可能在寫操作已經(jīng)完成很長(zhǎng)時(shí)間以后才真正對(duì)磁盤的數(shù)據(jù)進(jìn)行更新。sync命令強(qiáng)制將磁盤緩沖的所有數(shù)據(jù)寫入磁盤,假如在沒(méi)有將磁盤緩沖區(qū)的信息寫入磁盤之前終止系統(tǒng),則磁盤的文件系統(tǒng)就會(huì)處在一個(gè)不穩(wěn)定的狀態(tài)。
而在正常模式下即使沒(méi)有對(duì)分區(qū)進(jìn)行umount的操作,在重啟之前系統(tǒng)會(huì)調(diào)用sync命令強(qiáng)制將磁盤緩沖的所有數(shù)據(jù)寫入磁盤,而在急救模式下必須對(duì)所掛的分區(qū)進(jìn)行umount的操作,系統(tǒng)才會(huì)調(diào)用sync命令強(qiáng)制將磁盤緩沖的所有數(shù)據(jù)寫入磁盤,請(qǐng)?jiān)诩本饶J较碌呐笥炎⒅剡@個(gè)問(wèn)題。其實(shí)“reboot -n(Don’t sync before reboot or halt)”在重啟之前不用sync命令強(qiáng)制將磁盤緩沖的所有數(shù)據(jù)寫入磁盤,就很能說(shuō)明問(wèn)題。