Linux共享連結庫錯誤解決一例(轉)

BSDLite發表於2007-08-12
Linux共享連結庫錯誤解決一例(轉)[@more@]  作者:四川省成都市體育學院 劉紀恩
  
  不久前,筆者一位在銀行工作的網管朋友給筆者打電話,說他的一臺安裝有資料庫的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的正確連結,然後退出重啟,結果故障仍然存在。
  
  水落石出
  
  可筆者總覺得判斷是對的,又到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
  
  看來剛才筆者所做的操作並沒有寫進磁碟,於是筆者又重新做了剛才的操作。可這一次筆者老老實實地“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命令強制將磁碟緩衝的所有資料寫入磁碟,就很能說明問題。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617542/viewspace-948698/,如需轉載,請註明出處,否則將追究法律責任。

相關文章