不久前,筆者一位在銀行工作的網管朋友給筆者打電話,說他的一台安裝有資料庫的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下,利用LinuxCD光牒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的正确連結,然後退出重新開機,結果故障仍然存在。
水落石出
可筆者總覺得判斷是對的,又到lib目錄下去仔細看了一下libc.so.6這個檔案:ls -l libc.so.6,結果如下所示:
看來剛才筆者所做的操作并沒有寫進磁盤,于是筆者又重新做了剛才的操作。可這一次筆者老老實實地“umount /dev/hda1”,然後退出重新開機,系統又重新正常啟動了,再到lib目錄下去看了一下libc.so.6這個檔案:ls -l libc.so.6,結果如下:
lrwxrwxrwx 1 root root 13 Mar 10 03:32 libc.so.6 -> libc-2.0.7.so
這回所做的修改寫進了磁盤。看來問題歸根結底是出在libc.so.6檔案的連結問題上,問題總算解決了!
後 記
為什麼非要做umount?在正常模式下沒做umount,所做的操作也能寫進磁盤的。筆者查了一下資料才明白: Linux檔案系統更新是一個複雜的過程,當使用者程式對檔案系統進行修改以後,例如進行了寫操作,檔案資料将修改記錄在核心緩沖中,在資料沒有寫到磁盤的時候,依然能夠執行使用者程序,所有資料的改變都在inode的内容中得到反映。磁盤的資料更新實際上是異步進行的,很有可能在寫操作已經完成很長時間以後才真正對磁盤的資料進行更新。sync指令強制将磁盤緩沖的所有資料寫入磁盤,如果在沒有将磁盤緩沖區的資訊寫入磁盤之前終止系統,則磁盤的檔案系統就會處在一個不穩定的狀态。而在正常模式下即使沒有對分區進行umount的操作,在重新開機之前系統會調用sync指令強制将磁盤緩沖的所有資料寫入磁盤,而在急救模式下必須對所挂的分區進行umount的操作,系統才會調用sync指令強制将磁盤緩沖的所有資料寫入磁盤,請在急救模式下的朋友注意這個問題。其實“reboot
-n(Don’t sync before reboot or halt)”在重新開機之前不用sync指令強制将磁盤緩沖的所有資料寫入磁盤,就很能說明問題。