閱讀221 返回首頁    go 阿裏雲 go 技術社區[雲棲]


係統診斷小技巧(8):如何修複grub損壞

TL;DR

開始之前

目前普遍部署的的grub是,依據官方的叫法,grub legacygrub。社區常見的稱唿是grub(或者grub1)和grub2。我們引用的文檔可能遵循社區的用法;這裏我們遵循官方的用法。比如,我們說CentOS 6上默認部署的是grub legacy,而CentOS 7上默認部署的是grub;而不說我們說CentOS 6上默認部署的是grub1,而CentOS 7上默認部署的是grub2

除了要注意不同版本的grub,排查、診斷或者確認時,有可能需要使用文件係統的元數據或者數據。因此,需要了解如何檢查文件係統狀態和確認文件在文件係統上的信息(比如文件使用的磁盤塊信息)。同樣,這也涉及了不止一個文件係統和不同工具。比如,CentOS 6一般使用的是Ext 3文件係統,CentOS 7也可以使用Ext 3/Ext4文件係統,但是默認使用的是XFS文件係統。

因為我們要修複的是引導器損壞,不了解磁盤分區幾乎是不可能的。當然,相對而言,磁盤分區的種類要單調些。

因此,修複有問題的grub,需要較多的了解之。當然,簡單的修複操作隻需要大家對grub有粗略的了解即可。

grub是如何工作的?

grub是由某些固件啟動的。無論是BIOS還是UEFI,引導grub進而引導操作係統時,都要解決一個問題:如何加載可以使用文件係統的模塊。畢竟,無論是豐富的功能(比如菜單和各種選項支持),還是固件、內核乃至各種驅動模塊,都以文件的方式存儲在本地存儲或者遠端存儲媒介上。

MBR為例,可以供grub使用的空間不超過446字節。這種限製下不可能支持目前普遍使用的多種文件係統。所以grub必須提供一種解決方案來解決這個問題。

解決方案之一,隻支持一種文件係統。比如UEFI就要求EFI係統分區必須是FAT32的文件係統。

解決方案之二,以模塊的方式支持多文件係統。MBR模式下的grub legacygrub其實都是以這種方案工作的,雖然兩者的設計和實現迥然不同。

還有其他理論上可行的方案,這裏我們隻考慮上麵那兩種普遍使用的方案。這兩種方案--無論是隻支持一種文件係統,還是以模塊的方式支持多種文件係統--都表明,在引導過程中,存在著一個不支持文件係統階段和支持文件係統的階段。

毫無疑問,對於在文件係統中如何找到一個文件我們是駕輕就熟。但是,如果文件係統不存在時,我們怎麼定位和使用一個文件呢?答案是邏輯區塊地址:LBA (Logical Block Addressing):即直接使用磁盤固件接口提供的定位和索引方案。所以,引導過程中,grub至少會使用兩種文件定位方案:文件係統方案和LBA方案。

grub至少會使用兩種文件定位方案,這引申出一個問題:如果grubLBA的方式定位和使用一個文件,那麼,這樣的文件存儲在哪裏呢?

存儲方式一。既然grub不通過文件係統接口使用這個文件,那麼,這個文件完全沒有必要存儲在文件係統上。因為現在磁盤分區和文件係統都因效率或者兼容的原因,要滿足對齊的約束。因此,分區之間,或者文件係統內部,都會有一些空閑不用的扇區。因此我們可以把這個文件存儲在,比如,相鄰兩個分區之間的空閑扇區上。毫無疑問,這要求分區間的空閑扇區至少不小於這樣文件需要的大小。我們會看到grub就采取的這種方案(把core.img存儲在第一個分區前的空閑扇區中)。

存儲方式二。把文件就存儲在文件係統中。這種存儲方式要求,雖然grub並不使用文件係統接口來定位和使用這個文件,但是,我們必須在文件係統中為這個文件建立記錄。否則文件係統就對這個文件一無所知。文件係統的寫操作可能覆蓋之或者改動之。不在文件係統中為這個文件建立記錄,這種被寫操作破壞的問題就難以解決和避免。grub legacy就使用了這種存儲方案。

雖然常見的情形是grub安裝在磁盤的第一扇區,用作MBR。但是也存在著grub安裝在跟文件係統的第一扇區,用作VBR,由其他MBR加載啟動而已。比如,SUSE 11默認就是以Master Boot LoaDeRMBR,而把grub安裝在根文件係統第一扇區。

因此,檢查、核實和修複grub,可能麵臨多種情形,需要考慮多種情況。幸好,grub提供了良好的封裝。在簡單情形下,修複grub有可能是一個簡單任務。

比如,如果我們已經確認了是grub損壞,或者我們隻是需要重新安裝grub,那麼,重新安裝grub是很簡單的一個任務。

重新安裝grub:grub-install方法

grub legacygrub默認都提供了grub-install工具。比如,如果我們要在/dev/vda盤上重新安裝grub,那麼,簡單執行如下命令即可

grub-install /dev/vda

但是,使用grub-install過程中,需要注意以下幾個問題。

  1. 不同的發行版提供的grub-install名稱可能不同。比如,CentOS 6提供了grub-install,但是,CentOS 7提供的是grub2-install

  2. grub默認使用的磁盤路徑是底層(比如,BIOSUEFI)提供的,與Linux啟動後提供的磁盤路徑並不一致。因此,grub使用(/boot/grub或者/boot/grub2目錄下的)device.map文件來完成這兩種路徑之間的映射。在使用grub-install工具前,需要核實和確認device.map的內容是合適的。具體可以參考How to specify devices文檔。

  3. CentOS、Debian和Ubuntu等係統,一般都有係統層級的grub的配置文件。其中也有關於磁盤映射的選項或者配置項,也需要調整。這樣的配置文件,在CentOS係統上是/etc/sysconfig/grub文件,而在Debian或者Ubuntu則是/etc/default/bootloader或者/etc/default/grub文件。

  4. 因為grub-install工具不能處理/dev/xvda*路徑,所以在磁盤路徑是/dev/xvd*這種路徑時,我們需要適當調整grub-install工具。

  5. grub,官方手冊隻提供了使用grub-install的安裝方式;對grub legacy,則有手工安裝方法。

  6. 我們這裏隻是修複grub,而不是(初次)安裝之。

手工安裝grub

grub-install工具是封裝了grub legacy的底層工具來執行安裝操作的。

比如,在[device.map]與grub legacy各類鏡像文件和工具安裝、部署完畢的情況下,如果/boot不是獨立分區,則我們可以這樣手工執行安裝操作(更多請參考GInstalling GRUB natively

[root@grub-demo ~]# grub
Probing devices to guess BIOS drives. This may take a long time.


    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)

 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename.]
grub> find /boot/grub/stage1
find /boot/grub/stage1
 (hd0,0)
grub> root (hd0,0)                   
root (hd0,0)
 Filesystem type is ext2fs, partition type 0x83
grub> setup (hd0)
setup (hd0)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd0)"...  27 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd0) (hd0)1+27 p (hd0,0)/boot/grub/stage2 /boot/grub/grub.conf"... succeeded
Done.
grub>

修複grub的步驟

我們討論了grub如何工作、其使用存儲和文件係統的特點,以及如何修複之。簡單計,我們總結下修複grub的步驟

  1. 從存儲和文件係統的角度排查和診斷grub的狀態,確定是否是grub損壞。
  2. 核實並且必要時調整,使grub的修複環境和工具可用。
  3. 選擇適當的方法修複之。

最後更新:2017-09-12 10:02:41

  上一篇:go  智能家庭本周鋒聞:小米也要來玩壞智能家居?
  下一篇:go  2017阿裏巴巴技術論壇,本周起將席卷全球四大頂級名校!