Linux 啟動故障與排除

映像檔檔案系統錯誤

第三種錯誤類型是與 initrd 映像檔檔案系統相關的錯誤。在系統啟動流程的第三步,需要運行核心和載入映像檔檔案系統 initramfs,一些必要的使用者程式和驅動模組在載入 initramfs 映像檔檔案系統之後將獲得支援。在 CentOS 或者 RHEL 系統上,核心安裝和升級後,都會根據記憶體中的驅動資訊,自動重建對應版本的映像檔檔案系統,檔案名是與核心版本相同的 initramfs.img。重建 initramfs.img 時,通常會使用當前系統的設備驅動模組設定檔,如 /etc/modprobe.conf 或者 /etc/modprobe.d/*.conf,同時還有一些關鍵的設備設定檔,如邏輯卷配置 /etc/lvm/lvm.conf,多路徑配置 /etc/multipath.conf,並將其內容完整集成到 initramfs 檔案系統中。在大部分情況下,並不會出現因為 initramfs 所導致的系統啟動錯誤。但是在某些特殊場景,卻中會有一些例外。典型的場景是伺服器通過多路徑方案連接和使用外部儲存裝置,作業系統根目錄也直接安裝在外接儲存裝置,同時又使用了邏輯卷,就是我們常說的 Boot from SAN。在這種場景中,安裝系統的時候就需要先載入儲存裝置驅動,以及相關的多路徑軟體,並且根據驅動載入的情況,重建 initramfs 映像檔檔案系統。如果這個映像檔檔案系統中的設備驅動模組和儲存裝置不配,或者是設備驅動和當前系統使用的邏輯卷的篩檢程式設置有一些衝突,那就有可能導致系統啟動不成功。

使用外部儲存裝置的問題

例如筆白曾經接觸過一些 EMC 的多路徑儲存裝置方案,因設置 initramfs 不當所導致的問題。EMC PowerPath 是 EMC 所提供的多路徑軟體方案,當安裝在 Linux 之後,會針對多路徑設備產生一組虛擬的聚合設備,設備檔案名通常是 /dev/emcpower<N> 同時會重建 initramfs 檔案系統。在重建過程中會使用當前系統的邏輯卷配置 /etc/lvm/lvm.conf 並將該配置編入 initramfs 檔中。用戶當前環境的 lvm.conf 中篩檢程式 filter 設置如下。
filter=[“a/sdi[1-9]$/”, “a/sda1/”, “r/sd.*/”, “r/disk.*/”]
該設置表示只允許作業系統對有限的以 sd 開頭的設備建立物理卷並啟動卷組,而在其他的設備檔上一律不允許建立物理卷。這樣的配置被編入 initramfs 後,系統重啟之後,可載入 initramfs 檔案系統,也能通過 initramfs 成功載入了多路徑設備驅動,但是因為產生的聚合設備名是 /dev/emcpower<N>,所以在 initramfs 中邏輯卷的 filter 配置不允許在上面啟動卷組,就會無法識別和掛載硬碟上的根分割區 /dev/emcpower<N> 所在的邏輯卷,接著就會報上 Volume Group Not Found 的錯,誤並且最終卡在 Kernel Panic 上。

問題關鍵是看到了系統在 Kernel Panic 之前,可看到 Volume Group Not Found 的資訊。此時要考慮為什麼沒有修改過任何配置的邏輯卷,在系統重啟之後無法被識別。顯然載入 initramfs 檔案系統是第一個會啟動邏輯卷的地方,我們自然需要看看 initramfs 中的邏輯卷設置。因此首先需要將 initramfs 映像檔檔解開,檢查其中的配置。如果發現邏輯卷配置有問題,則需要手動修改之後再將其封裝回去。所以我們還是需要借助安裝光碟的 Rescue 模式,進入到系統的根分割區或者開機磁碟分割。不過真正的系統根分割區是建立於邏輯卷上的,而邏輯卷又是在通過多路徑軟體生成的特殊聚合設備如 /dev/emcpower<N> 上建立的。要能成功載入根分割區,至少要確保先識別儲存裝置,然後載入協力廠商多路徑軟體,才有可能識別這些特殊的聚合設備名稱,而 Rescue 模式下很可能不具備這種能力。這時在 Rescue 模式下使用預設的自動掛載根分割區的方式,恐怕不能成功。所以要選擇 Skip,暫時放棄掛載根分割區,而確保手動掛載 /boot 分割區(圖28)。因為 /boot 分割區無法建立在邏輯卷上,而且即便無法聚合多路徑,仍然可以嘗試將組成多路徑的單個設備如 /dev/sda1,手動掛載到一個臨時目錄上。

圖28:選擇手動掛載根檔案系統。
圖28:選擇手動掛載根檔案系統。

由於系統的根和開機磁碟分割都在儲存裝置上,而且根分割區又在邏輯卷,所以用光碟 Rescue 模式啟動能識別根的前提,是先嘗試掛載根分割區和開機磁碟分割。
mount /dev/sda1 /mnt/sysimage/boot    (ENTER)
備份原來的 initramfs 檔。
cp /mnt/sysimage/boot/initramfs-3.8*.img /mnt/sysimage/tmp    (ENTER)
建立一個臨時目錄,並將 initramfs 檔手動解開。
mkdir /mnt/sysimage/backup    (ENTER)
cp /mnt/sysimage/boot/initramfs-3.8*.img /mnt/sysimage/backup    (ENTER)
cd /mnt/sysimage/backup    (ENTER)
gunzip -cd initramfs-3.8*.img | cpio -vid    (ENTER)
修改其中的 lvm.conf 檔案。
vi /mnt/sysimage/backup/etc/lvm/lvm.conf    (ENTER)
然後找出這一行。
filter=[“a/sdi[1-9]$/”, “a/sda1/”, “r/sd.*/”, “r/disk.*/”]
更改成如下模樣。
filter = [ “a/.*/” ]
並保存退出。之後重新封裝 initramfs。
cd /mnt/sysimage/backup    (ENTER)
rm -fr initramfs-3.8*.img    (ENTER)
cd /mnt/sysimage    (ENTER)
find . | cpio -ov > ../initramfs-3.8.13-16.2.1.el6uek.x86_64.img    (ENTER)
gzip .. /initramfs-3.8.13-16.2.1.el6uek.x86_64.img    (ENTER)
最後替換掉舊的 initramfs。
cp /mnt/sysimage/initramfs-3.8.13-16.2.1.el6uek.x86_64.img /mnt/sysimage/boot    (ENTER)
再次重啟設備系統即可恢復正常。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。