# ls: symbol lookup error: /lib64/libdl.so.2: undefined symbol: __libc_dlerror_result, version GLIBC_PRIVATE ## 成因 * 先說結論,如果你哪天想裝額外的套件,千萬不要在工作站執行yum update,千萬不要、千萬不要、千萬不要 ```bash sudo yum update ``` * 否則會因為libdl.so.2所連結的檔案改變,造成以下結果,ls, mv, ln...全部失效 ```bash $ ls ls: symbol lookup error: /lib64/libdl.so.2: undefined symbol: __libc_dlerror_result, version GLIBC_PRIVATE ``` * 這時候想法也很簡單,我們利用ln指令把libdl.so.2連回正確的檔不就可以了嗎? * 你說的沒錯,但你現在ln沒辦法使用、ls也沒辦法用、連上工作站的mobaxterm一關閉馬上就連不回去了。 * 因此我們需要借其他人的ln、ls來用,是誰呢? 沒錯就是開機碟 ## 開機碟製作(需大小至少為4GB隨身碟) * 由於工作站目前系統為CentOS,因此拿CentOS為例。 1. 至 https://rufus.ie/zh_TW/ 下載製作開機碟程序 2. 至 https://www.centos.org/download/ >> CentOS Stream >> 8下載 [x86_64](http://isoredirect.centos.org/centos/8-stream/isos/x86_64/)其中一個映像檔(我是使用第二個1GB的那個) 3. ![image](https://hackmd.io/_uploads/rkT3Ce8UT.png) 4. 將映像檔用rufus寫入開機碟 ## 開始救援 [圖片可參考](https://cndaqiang.github.io/2019/09/05/glibc/) 1. 將USB插上工作站主機 2. 重新開機並且狂按F2(因主機板牌子不同可能不一樣),進入BIOS 3. 找到使用開機碟開機的選項 4. Troubleshooting模式 5. Rescue a CentOS system 6. 如果可以輸入1,Continue能直接chroot /mnt/sysimage並且直接mount工作站硬碟在開機碟上。如果輸入1會死機的話可以看到補充的部分 ![image](https://hackmd.io/_uploads/HkhRrZUUa.png) 7. 這時如果順利的話,/mnt/sysimage/下的檔案就是工作站的根目錄 ```bash $ ls /mnt/sysimage/ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var ``` 8. 根據[這篇](https://gliderhx.github.io/2020/04/08/lib64-libc.so.6%E9%94%99%E8%AF%AF%E5%AF%BC%E8%87%B4%E7%9A%84%E7%B3%BB%E7%BB%9F%E5%B4%A9%E6%BA%83/),進入/mnt/sysimage/lib64/,先檢查有幾個可能被link的target,下圖就是有兩個target,分別是"libc-2.28.so", "libc-2.29.so" ```bash $ cd /mnt/sysimage/lib64/ $ ls libc-2.* libc-2.28.so libc-2.29.so ``` 9. 確定libc.so.6有沒有連錯。下面就是連錯了,原本應該要連到"libc-2.28.so",但因為執行了update所以就連結到了"libc-2.29.so",這就是一切錯誤的開始。 ```bash $ ls -la libc.so.6 lrwxrwxrwx. 1 root root 12 Dec 12 20:27 libc.so.6 -> libc-2.29.so ``` 10. 這時使用軟連結將其連結回正確的檔案就解決了,請注意**務必使用相對路徑**。 ```bash $ cd ../usr/lib64/ $ pwd /mnt/sysimage/usr/lib64 $ ln -sf ./libc-2.28.so ../../lib64/libc.so.6 $ ls -la libc.so.6 lrwxrwxrwx. 1 root root 12 Dec 12 20:27 libc.so.6 -> libc-2.28.so ``` ## 補充 * 如果你在上面開始救援的第6步卡住,或是你在開機要進入介面時卡住(按F1發現failed to execute /sbin/init),那就是另外一個ld-linux-x86-64.so.2出問題。 1. 依然是參考[這篇](https://gliderhx.github.io/2020/04/08/lib64-libc.so.6%E9%94%99%E8%AF%AF%E5%AF%BC%E8%87%B4%E7%9A%84%E7%B3%BB%E7%BB%9F%E5%B4%A9%E6%BA%83/)的修改軟連結的方式。 2. 接續上面步驟5,無法輸入1直接chroot,因此我們輸入3,Skip to shell 3. 現在要做的事是將工作站mount到開機碟上,因此我們先輸入lsblk找到工作站的硬碟(我那時候是nvme0n1) ```bash $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT . . . nvme0n1 259:0 0 931.5G 0 disk ``` 4. 根據[這篇](https://www.cnblogs.com/xzy186/p/15135959.html),先輸入lvdiplay查看邏輯卷 ```bash $ lvdiplay ``` 6. 使用lvm vgscan查看系統中的邏輯卷組 ```bash $ lvm vgscan Found volume group "cs" using metadata type lvm2 ``` 6. 根據邏輯卷組名稱激活 ```bash $ lvm vgchange -ay cs ``` 7. mount工作站硬碟到開機碟上 ```bash $ mkdir /mnt/sysimage $ mount /dev/cs/root /mnt/sysimage/ ``` 8. 跟上面的步驟相同,將/mnt/sysimage/usr/lib64/ld-linux-x86-64.so.2連回正確位置,**務必使用相對路徑** ```bash $ cd /mnt/sysimage/usr/lib64 $ ln -sf ./ld-2.28.so ./ld-linux-x86-64.so.2 $ ls -la ./ld-linux-x86-64.so.2 lrwxrwxrwx. 1 root root 10 Dec 12 20:22 ./ld-linux-x86-64.so.2 -> ld-2.28.so ```