故事事故是這樣的
新開發的jar包部署在老伺服器上,版本是Red Hat Enterprise Linux AS release 4 (Nahant Update 5),提示需要高版本jdk,高版本jdk提示glibc版本太低得升級,是的,就像套娃。
使用編譯原始碼的方式將glibc由2.3升級到2.9,升級完ls命令不好使了。 用LD_PRELOAD方法解決了ls命令不好使的問題後還挺有成就感的呢!
輕度強迫症的我當然要重啟,然後
#reboot
就沒有然後了。。
作業系統起不來了。各種嘗試,最好的結果是卡死在
Starting cups-config-daemon:
Starting HAL daemon:
再也不往下走了。007的伺服器被996的程式設計師幹進了ICU。
看到了吧,搞垮伺服器可以顯得很無辜。刪庫顯得太刻意了,會被人指責性格有問題。
搶救思路
像《信條》一樣進行一次逆過程,把glibc相關的靜態庫、動態庫都用原來的低版本覆蓋回來。cp覆蓋和安裝rpm覆蓋一起上。
必要條件
- 能進機房,直接操作伺服器,因為ssh此時已經連不上了。
- 有相同版本的Linux系統光碟,Linux搶救模式需要光碟引導。
- 有相同版本的Linux系統的iso映象檔案,用來獲取rpm 【或者替代方法】
- 有相同版本的Linux系統的伺服器或者虛擬機器,用來下載.a檔案 【或者替代方法】
準備工作
rpm安裝包
將iso檔案解壓,在
RHEL4.6-i386-AS-DVD\RedHat\RPMS
目錄下就包括所有需要的rpm包。
需要準備的安裝包是下面這些:
.a靜態庫檔案
到好用的版本一致的伺服器對應目錄下載下面的庫檔案
目錄/lib
目錄/usr/lib
將這些安裝包和靜態庫放入一個U盤中,U盤插到伺服器上。
搶救過程
進入光碟系統
將光碟放入光碟機。
開機快速按F2,進入
通過+-號調整開機啟動順序,將CD-ROM調整到最上面
按回車,系統重新啟動,進入光碟引導介面
按F5,進入
輸入 linux rescue
按回車,稍等一會,進入
按回車,進入
按回車,進入
按回車,進入
將游標移動到No,按回車,進入
按回車,進入
提示原有系統已經掛載到/mnt/sysimage,按回車進入,目前所處的就是光碟搶救模式(rescue mode),環境是光碟系統,原系統所有檔案都在光碟系統的子目錄/mnt/sysimage裡。
可以看到原有系統的所有目錄結構在/mnt/sysimage下都是可以看見的。
掛載U盤
首先將U盤掛載到光碟系統,
mount -t vfat /dev/sdb1 /mnt/usb/
不同環境中U盤的識別符號不一定是sdb1,在物理機上可能是sda1, 可以通過
fdisk –l 命令看各個目錄容量大小來判定哪個是U盤。
如果掛載U盤提示格式錯誤,U盤可能是fat16格式,執行
mount -t msdos /dev/sdb1 /mnt/usb/ 試試
此時,U盤裡的檔案都在/mnt/usb/目錄下, 原系統所有檔案都在/mnt/sysimage下。將usb目錄下的檔案拷貝到/mnt/sysimage下面你能記住的任意目錄,本文拷貝到/mnt/sysimage/home下。
cp /mnt/usb/* /mnt/sysimage/home
切換到原系統
執行
#chroot /mnt/sysimage
這個指令使你由當前光碟系統切換到原系統(就是我們要搶救的那個系統),執行pwd和ls可以看到,你所處的目錄就是原系統的根目錄,賬號是原系統的root賬號。
一句話,原系統直接進進不去,但是從光碟系統跳,是能跳進去的。
安裝rpm
進入/home,
rpm -ivh --force rpm包名
一個一個安裝U盤的rpm包。裝失敗的就等把成功的都裝完了回頭重試,和答卷子題不會一個玩法,都是依賴關係導致失敗的。
rpm最好自己重新命名,改成簡短的名字(glibccomm.rpm這種),一定要去掉“-”。我當時看見顯示器上顯示的名字包括亂碼和問號,靠猜來判斷是哪個包,後悔之前沒重新命名。
替換靜態庫檔案
然後手動cp指令替換/lib 和 /usr/lib的靜態庫(*.a檔案)。
cp /home/libpthread.a /lib
cp /home/*.a /usr/lib
修改動態庫軟連線
手動修改動態庫的軟連線
無論安裝rpm包時是否自動修改過軟連線,都最好手動修改一遍。
到/lib目錄裡,先
rm *2.9* #刪除高版本的庫
然後
ln -sf libutil-2.3.4.solibutil.so.1
ln -sf libresolv-2.3.4.solibresolv.so.2
ln -sf libnss_nis-2.3.4.solibnss_nis.so.2
ln -sf libnss_nisplus-2.3.4.solibnss_nisplus.so.2
ln -sf libnss_hesiod-2.3.4.solibnss_hesiod.so.2
ln -sf libnss_files-2.3.4.so libnss_files.so.2
ln -sf libnss_dns-2.3.4.so libnss_dns.so.2
ln -sf libnss_compat-2.3.4.solibnss_compat.so.2
ln -sf libnsl-2.3.4.solibnsl.so.1
ln -sf libdl-2.3.4.solibdl.so.2
ln -sf libcrypt-2.3.4.solibcrypt.so.1
ln -sf libBrokenLocale-2.3.4.solibBrokenLocale.so.1
ln -sf libanl-2.3.4.solibanl.so.1
ln -sf libc-2.3.4.solibc.so.6
ln -sf librt-2.3.4.solibrt.so.1
ln -sf libpthread-0.10.so libpthread.so.0
ln -sf libm-2.3.4.solibm.so.6
跳回光碟系統
執行exit跳回到光碟系統,
在上圖游標處再一次輸入exit,按回車 ,系統會重新啟動。
立刻修改BIOS,設定系統從硬碟啟動,原系統可以正常啟動了。
完結撒花
搶救成功還挺有成就感的呢!其它操作搞垮伺服器,也可以試試,只要那個操作能逆向來一遍,問題都不大。
為什麼不重灌?上面部署的東西是多年前放的,物是人非,沒辦法重頭再來。
為什麼敢升級?親眼看見過別人把RHEL6.6的glibc升級了沒出事。真不知道會出這麼嚴重的問題。
如果沒有版本一致的光碟,接近的也可以。我實際用的光碟是RHEL4.6,和原系統差了一個小號。
rpm和.a檔案能拿到就行,不用非按本文方法。
網友提供的替換so的方案不靠譜,必須rpm安裝。
2.3升級到2.9不可以,不代表升級到2.4也不可以,版本離的近可能成功。
這個伺服器至今還在跑著,那些jar包部署到別的伺服器上了。