天天看點

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

grub損壞,是導緻系統啟動失敗比較常見的原因。如何解決這類問題呢?

解決問題,好用的工具很重要。我們先讨論下好用的工具。

三大利器

關于工具的重要性我們就不絮叨了。解決啟停問題,一定要有三大利器的輔助

  • 快照
  • VNC
  • 錄屏工具

對排查啟停問題,有三個方面的用處。一是保留現場。有了這個現場,不管我們排查中做了什麼變更,我們總是能夠回撤到現場。這是現實版後悔藥。二是在沒有辦法進入系統的情況下,

可以讓我們把問題磁盤挂載到其他執行個體上。這樣我們有了一個排查、診斷和修複的途徑。三是快照提供了多種可選擇的途徑讓我們可以使用修複後的資料和結構。比如建立磁盤挂載拷貝、制作安裝鏡像覆寫有問題的系統盤等等。

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

高速公路是有應急車道的。同樣我們的業務系統也需要應急車道,用以解決異常、緊急等非正常問題。

就是我們的應急車道。

當然,VNC不是唯一可用的方案。這裡的關鍵是在系統異常時,提供一個root shell供排查隻用就好。

各主流平台都有好用的錄屏工具,功能大同小異,大家使用順手即可。為什麼我們要建議大家都配備錄屏工具呢?

系統啟停時,Linux控制台上的系統輸出很快。有些關鍵的報錯資訊,你可能完全沒有機會看到就過去了。如果類似資訊完全沒有記錄到日志中。那麼,你可能被後面的日志給誤導。

題外話:bind挂載

修複啟停時經常需要做chroot操作,即我們要在一個新的根檔案系統内操作。但是,隻執行chroot是不夠的。我們還需要挂載/dev、/proc和/sys目錄。

但是,因為/dev、/proc和/sys不是裝置,直接挂載是不可行的。這裡的技巧是使用

bind

挂載方式。

mount --bind /olddir /newdir # bind挂載選項執行個體
for d in dev proc sys;do mount /$d /new_root_dir/$d;done # 切換根檔案執行chroot前,先挂載需要的系統目錄           

回到話題

如何複現現場?

我們通過覆寫磁盤第一扇區來破壞grub的引導代碼部分,觀察下grub被破壞後,執行個體啟動的情況

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

具體操作的指令如下。注意,危險操作,切勿随意模仿。

fdisk -l -u /dev/{xvda,vda} # 确定系統盤裝置路徑
dd if=path_to_sys_disk bs=448 count=1 2>/dev/null | od -tx1 # 檢視MBR内容
dd if=/dev/zero bs=448 count=1 of=path_to_sys_disk # 覆寫MBR
dd if=path_to_sys_disk bs=448 count=1 2>/dev/null | od -tx1 # 驗證已經覆寫了MBR
reboot # 重新開機           

執行過程如下(fdisk操作沒有顯示)

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

修複

那麼,怎麼修複呢?grub損壞的修複方法簡潔明了:重新安裝grub即可。但是目前執行個體啟動失敗了,無法對問題系統進行讀寫處理。

是以我們需要解決的問題是兩個:

  1. 通過什麼方式來處理系統盤。
  2. 怎麼重新安裝grub。

解決第一個問題的方法很多。這裡我們給大家推薦能夠使用快照的方法。這個方法雖然稍顯啰嗦,但是卻能讓我們全程掌控。

如何使用快照?

我們為問題執行個體的系統盤

做快照

。然後再從

快照建立磁盤

。建立磁盤和系統盤内容一樣,但是可以作為資料盤挂載到正常執行個體上。

這樣我們就可以在正常執行個體上對新建立的磁盤做處理。調整配置、适當修改,而後重新安裝grub。

整個思路圖示如下

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

具體操作示例如下

首先做快照

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

給快照個顯著的名字

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

良好規劃和維護的系統盤,一般都尺寸不大

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

現在建立磁盤

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

處理系統盤的問題解決了。那麼,怎麼重新安裝grub呢?

重裝grub

主流Linux發行版都提供了

grub-install

工具(名稱也可能是grub2-install),大家直接調用即可。但是有幾點大家要注意。

小提示

首先,grub的引導器預設使用

BIOS

磁盤命名慣例

,這與Linux是不同。是以grub提供了配置檔案,用來在BIOS的磁盤命名和Linux系統的磁盤命名之間轉換。

這些配置檔案如下:

版本 應用配置 系統配置
grub /boot/grub/device.map /etc/{sysconfig,default}/grub
grub2 /boot/grub2/device.map

如果是KVM執行個體,則磁盤是vda;如果是較老的XEN執行個體,則磁盤是xvda。

第二,grub-install的操作對象是磁盤還是分區。不要給錯參數。

第三,如果您的系統比較老。那麼,您可能會碰到已知bug:

grub-install工具不能處理/dev/xvda*路徑

重裝步驟

有了以上的鋪墊,我們給出重新安裝grub的步驟

  1. 把建立磁盤挂載到正常執行個體上,以便對之讀寫、修改。
  2. 挂載目标根檔案系統,我們需要改動grub的device.map檔案。
  3. 把/dev、/proc和/sys挂載到新挂載檔案系統。這樣我們就能夠使用核心導出的系統資料了。
  4. chroot到目标根檔案系統,使之成為目前跟檔案系統。
  5. 檢查和核實/boot/{grub,grub2}/device.map和/etc/{sysconfig,default}/grub配置檔案中磁盤名稱是否正确。
  6. 使用grub-install來重新安裝grub。

這些步驟,用腳本來表達,如下

# 1. 挂載建立磁盤到正常執行個體需要在控制台操作
# 2. 把建立磁盤在執行個體内部挂載上。這裡我們假設/dev/vdb是系統盤
mount /dev/vdb1 /mnt
# 3. 通過bind方式,挂載系統目錄到新根檔案系統
for d in dev proc sys;do mount --bind /$d /mnt/$d;done
# 4. 切換到新根檔案系統
chroot /mnt
# 5. 檢查/boot/grub/device.map或者/boot/grub2/device.map檔案,确認磁盤名稱不當。如有則修改
cat /boot/{grub,grub2}/device.map
# 6. 重新安裝grub。因為是在其他執行個體上以資料盤的方式,是以是第二塊磁盤。
grub-install /dev/vdb           

我們按照上面的步驟,把前面破壞的那台執行個體的grub重新安裝下。

首先,挂載磁盤到正常執行個體

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

執行個體内部挂載

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

接下來我們bind挂載/dev、/proc和/sys

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

現在切換到新根檔案系統

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

第五步,檢查磁盤名稱是否需要修改,需要則修改之

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

最後一步,重新安裝grub

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞
再次請快照出場

怎麼通過修正完畢的建立磁盤來修複問題執行個體的系統呢?這裡需要注意

  1. 我們沒有辦法直接使用建立的快照復原問題執行個體的系統盤。
  2. 資料盤的快照不能建立安裝鏡像。但是,開通了白名單就可以。

我們新建立磁盤是資料盤,其建立的快照是不能復原問題執行個體的系統盤的。是以我們隻能通過把新建立磁盤轉為系統盤,而後建立安裝鏡像的方式來恢複問題執行個體。當然,這需要開通白名單。

即整體思路是這樣的

Linux系統診斷小技巧(13):啟停問題之如何修複grub損壞

怎麼把資料盤轉為系統盤?我們會專題讨論下。

終焉

祝探索愉快。

繼續閱讀