文章目錄
- 前言
- 1. 故障描述
- 2. 故障診斷
- 3. 故障原因
- 4. 解決方案
- 總結
前言
上周幫用戶處理了一個 linux 虛擬機在重啟后無法正常進入操作系統的故障,覺得比較有意思,在這里分享給大家。
1. 故障描述
事情的起因是一臺系統版本為 CentOS 7.2 的 VMware 虛擬機出現了 ssh 登錄報錯,然后客戶就想著通過重啟操作系統的方式看看能否解決問題,結果發現重啟后操作系統直接就起不來了,卡在如下所示界面:
故障表現即:不管怎么重啟虛擬機,最后都會卡在 Starting Switch Root...
這里,在等待較長時間后會提示 Failed to execute /bin/sh, giving up: No such file or directory
。
2. 故障診斷
Step1
:在接到客戶的消息時,我腦海里第一時間想到了如下幾種可能性:
- 系統 Crash 了?
- 系統
/etc/fstab
文件中某些設置了開機自動掛載的項掛載失敗了? - 磁盤或者分區出現了壞塊?
Step2
:聯系客戶發起遠程,由于客戶也不清楚系統在發生故障前都做了哪些操作,所以想著還是先進單用戶模式做個初步排查,結果在執行 chroot /sysroot
時出現了如下報錯:
到這一步時我開始覺得這個故障的原因和我一開始想象的不一樣了,因為之前處理過的一些故障,還從來沒有遇到過進單用戶模式在切換根環境變量時出現報錯。
Step3
:既然單用戶模式在切換根環境變量時報錯,我想著那進救援模式是不是也會報錯呢?接下來就讓用戶掛載了一個 CentOS 7 版本的鏡像進救援模式,果然不出所料,在執行 chroot /mnt/sysimage
切換根環境變量時也出現了如下報錯:
Step4
:接下來就是要檢查 /bin/sh
和 /bin/bash
兩個文件是否存在,查詢完發現系統提示沒有該文件:
特別說明:這里有個點需要注意下,因為不管是單用戶模式還是救援模式,我們其實都沒有成功切換到系統的根環境變量下來,所以在查詢時一定要注意你查看的是 iso 救援模式系統的信息還是故障主機的系統信息
。如上圖所示,編號為1的地方我們查看的信息就是 iso 救援模式系統的,而編號為2的地方查看的才是故障主機系統的信息,由此可以判斷,原系統里面就是缺少了 /bin/sh
和 /bin/bash
兩個文件。
Step5
:帶著關鍵報錯信息和疑問去網上查了一些資料,類似的故障案例里面有說是因為 /lib64
的軟鏈接異常導致的,后面看到了紅帽官網的《Kernel panicked on boot and ‘chroot /mnt/sysimage’ command in rescue mode fails with ‘chroot failed to run command /bin/sh no such file or directory’ error》 這篇 KB 文章。
1)首先我查看了下 /lib64
的軟鏈接信息,發現軟鏈接是正常的(此時我以為是正常的,其實被誤導了,后面會說):
sh-4.2# ls -l /mnt/sysimage
2)緊接著我又查看了下 /bin
目錄的信息(此時我還以為是正常的,呵呵):
3)接著我按照紅帽官方 KB 所提供的步驟去做檢查:
敲重點:終于在這一步我發現了問題,因為前面的檢查讓我認為不管是 /lib64
的軟鏈接還是 /bin
的軟鏈接都是正常的,但是當我在執行 /mnt/sysimage/lib64/ld-linux-x86-64.so.2
命令時發現 ld-linux-x86-64.so.2
居然不能自動補全,此時我開始懷疑:雖然軟鏈接看似存在,但是源文件 /usr/lib64
可能缺少了;再聯想到 /bin
目錄也從 /usr/bin
軟鏈接過來的,但前面查詢時明明提示 /bin/sh
和 /bin/bash
兩個文件也是不存在的;基于此,我愈發覺得可能是 /usr
目錄有異常。
Step6
:檢查發現原系統的 /usr
目錄下除了一個 local 目錄,其余啥也沒有,此時終于找到“罪魁禍首”了,就是因為 /usr
目錄下的其它文件被刪除了,所以即使 /lib64
的軟鏈接和 /bin
的軟鏈接看著都正常,但其實已經失效了。
故障原因已經定位到,接下來就是該如何解決問題了。
3. 故障原因
系統 /usr
目錄下的文件被刪除,導致很多從 /usr
目錄下的文件創建的軟鏈接失效,如 /usr/lib64
和 /usr/bin
等,從而出現 ssh 登錄報錯,甚至重啟后無法進入操作系統。
系統 ssh 服務依賴的關鍵文件主要位于 /usr/sbin/sshd 和 /usr/lib64
,因此系統 /usr
目錄下的文件被刪除,ssh 肯定會受到影響;其次,登錄系統所需的 bashshell 通常位于 /usr/bin/bash
,這也是為什么系統在重啟后會卡在 Starting Switch Root...
這里進不去,而在單用戶以及救援模式下我們也無法切換到根環境變量下。
除此之外,用戶環境配置所需的很多工具如 ls、grep 等命令都在 /usr/bin
下,所以當 /usr
目錄下的文件被刪除,在使用這些命令時肯定也會報錯的(后面我自己復現了故障并進行了驗證)。
4. 解決方案
由于客戶沒有做任何的備份,也沒有虛擬機快照,因此只能通過掛載一個和故障主機操作系統版本一致的 iso 鏡像,進入救援模式后采用 cp -a
命令,將 iso 救援模式系統里原生的 /usr
目錄下的所有文件全部拷貝到 /mnt/sysimage/usr
目錄下去。
通過上圖不難發現,在拷貝操作完成后,此時可以成功執行 chroot /mnt/sysimage
切換到根環境變量。
后面取消 iso 掛載,重啟虛擬機就正常進入系統了。不過值得注意的是,此舉只能保證系統可以正常進入,但是如果之前有一些應用程序安裝在 /usr 目錄下,那么很大可能應用程序會無法正常被執行;又或者用戶自己的數據保存在 /usr 目錄下,此時也是沒有辦法恢復的。
總結
雖然這次故障基本上得到了解決,但是也反映出我自己對 linux 文件結構還是不夠熟悉,否則在看到 ssh 登錄異常、/bin/sh
異常以及 /bin/bash
異常時,就應該第一時間想到去查看 /usr
目錄的。
另外,日常工作中還是要建議客戶加強備份建設,這樣一旦出現故障,保底還有備份集可以進行還原;除此之外,在虛擬化環境中如果要對虛擬機做一些風險不可控的操作,建議先打快照再操作,這樣即使出現了問題,恢復快照就可以了。