1. 簡單介紹
使用Window每次非正常退出系統都會招來scandisk的一頓狂掃;Linux也不例外,只不過它調用的是fsck程序來檢查文件系統。作為一名系統管理員,當你發現文件系統發生故障時,你會怎麼做?當然是手動地執行fsck來檢查文件系統。所以本文就是教大家如何正確地使用並且使用好fsck工具的。
2. 文件系統
2.1. 超級數據塊(Superblock)
一個文件系統總是由它的superblock來定義的,所以創建文件系統的同時superblock也被創建。它包含了文件系統的一些基本參數,例如文件系統中的數據塊(data blocks)數和最大文件數等等。因為superblock包含了一些臨界數據,以便於進行災難性的恢復。缺省的superblock總是固定地位於文件系統所在磁盤分區的開始處。Superblock還有一個備份叫做冗余superblock,就像DOS中的文件分配表的副本。冗余superblock和缺省的superblock不一樣,它被分散地保存在磁盤分區上。
一個特定的文件被看成是目錄或包含了指向它的內容的指針。每一個文件都有一個和文件節點(inode)相關聯的描述符。一個文件節點包含了文件的屬性,例如文件的所有者、最後修改時間、最後訪問時間和指向此文件數據塊的指針等等。假設一個文件的前12個數據塊被文件節點結構中的變量直接指向,那麼文件節點結構可能還包含著指向間接文件數據塊的指針以便將來擴充文件的內容。其實文件節點結構中包含了3個級別的數據塊指針,一個文件有4096個字節的數據塊,則第一級間接數據塊包含了1024個字節,第二級間接數據塊也包含了1024個字節,並且被第一級間接數據塊指向;同理,第二級間接數據塊也指向第三級大小為1024字節的間接數據塊。其實在實際應用中第三級間接數據塊很少被使用,因為一般沒有那麼大的文件。文件系統的數據塊大小保存在superblock中,這就使在同一系統中同時訪問不同數據塊大小的文件系統成為可能。
最後再說明一下,文件數據塊的大小是在創建文件系統時給定的,並且在以後的使用中無法被改變。
2.2. 概要信息(Summary information)
概要信息和superblock相關聯,並且是唯一關聯;當文件系統被改變時,它就隨之記錄這種改變,記錄文件系統中的數據塊數目、碎片數目、文件節點和目錄等信息。
2.3. 柱面組群(Cylinder groups)
文件系統將磁盤分為一個或多個被稱為"柱面組群"的區域,它包含了一個和多個連續的磁盤柱面。每個柱面組群指示了文件的節點槽,一個數據塊映象(block map)描述了在柱面組群中所有可用的數據塊,並且概要信息描述了在柱面組群中數據塊的使用情況。當文件系統生成時,柱面組群中的文件節點數就被確定了下來。目前一般的規則是在磁盤上每2048個字節被分配入一個文件節點。在每個柱面組群的開始處都記錄有組群信息,一旦磁盤發生錯誤時將組群信息丟失。
2.4. 磁盤碎片(Fragments)
為了防止存儲小文件時浪費磁盤空間,文件系統允許將一個數據塊分割成2、4或8份。其中最小的份額時磁盤的簇大小,通常為512個字節。每一個同柱面組群相關聯的數據塊映象記錄著磁盤空間的碎片程度。
2.5. 文件系統的更新
在每天的日常工作中,我們創建、刪除數以百計的文件。操作系統為此產生了一系列的文件系統更新工作。當數據被寫入磁盤時,產生了一個連續的文件系統,同時文件系統更新所有的臨界信息。當用戶改變文件系統時,比如執行write時,要寫入的數據被復制入系統內核的被稱作in-core的緩沖區中,所以這種數據更新不是同步的,只有當write函數執行完畢,並且返回時,數據才真正地被寫入磁盤。同時用戶也可以手工地執行sync命令來迫使數據寫入磁盤。另外,每當內核的in-core緩沖區被用作新用途時,系統也會使用/etc/update來調用sync將數據寫入磁盤。
3. 修復破壞的文件系統
有很多方式可以使文件系統遭到破壞,最通常的是不正常關機和一些硬件錯誤。原因是在關閉系統並且掛起CPU之前沒有執行sync來將數據寫入磁盤,導致文件系統不完整。另外,硬件錯誤也是很致命的,特別是磁盤的物理損傷,將導致數據永久性地丟失。
3.1. 檢測和修復被破壞的文件系統
平時,fsck不進行交互式執行,而是每當不正常退出系統後,開機時自動執行。這個功能是在fsck進行交互式執行時的一個子集。所以本文下面的介紹都是基於交互式執行的,並且所有可能發生的錯誤都會被捕捉到。在此模式下運行,我們可以根據錯誤的類型來采取相應的修復措施。對於一個靜態的文件系統,fsck檢查它的結構完整性。在下面的介紹裡,我們著重討論發現柱面組群、文件節點、間接文件節點和數據塊的錯誤和各種可能采取的修復措施。
3.2.超級數據塊檢查
常見的文件系統破壞形式是概要信息中關於超級數據塊的信息破壞。概要信息很容易被破壞,因為對文件系統的任何改變都會導致概要信息的修改,並且也很容易在非正常退出時被破壞。對超級數據塊的檢查主要是針對文件系統的長度、文件節點數目、空閒數據塊統計和空閒文件節點統計等;文件系統的長度必須大於被超級數據塊使用的數據塊數目的總和和被文件節點列表所使用的數據塊數目的總和。對fsck來說,文件系統的長度和它的布局信息是最為重要的。
3.3. 空閒數據塊檢查
Fsck檢查所有在柱面組群的數據塊映象中被標識為未使用的數據塊,也即空閒數據塊。Fsck合計空閒數據塊的數目,並且把它加上被文件節點使用的數據塊的數目,檢查這個結果是否等於文件系統中所有數據塊的總和。如果fsck發現數據塊分配映象有錯時,它會自動重建它。概要信息中和超級數據塊相聯系的信息包含了在文件系統中所有空閒數據塊的數目。Fsck將它檢查所得到的空閒數據塊數目和上面概要信息中的空閒數據塊數目進行比較,如果兩者不一致,fsck就將實際檢查得到的空閒數據塊覆蓋概要信息中的空閒數據塊信息。對於空閒文件節點的檢查也會作同樣的處理。
3.4. 文件節點狀態檢查
一個單獨的文件節點一般不會出錯,然而,由於在文件系統中有大量的文件節點處入活動狀態,所以會有一小部分文件節點會發生錯誤。Fsck從第二個文件節點開始檢查(文件節點0被標記為"未使用"、文件節點1被留作後用)直至最後一個文件節點。每一個文件節點都被進行格式、類型、鏈接數、重復數據塊、壞數據塊和節點大小的檢查。
每個文件節點都有一個模式定義,它指示了文件節點的類型和分配狀態,這些類型有:常規節點、目錄節點、符號連接節點、特殊塊設備節點、特殊字符設備節點和套接字節點;而其分配狀態有:未分配、已分配和非分配三種狀態,其中非分配狀態的節點指示了這個節點具有不正確的節點格式,這種情況常常是由於非法數據的寫入而造成的,對於這種情況,fsck會清除此文件節點的內容。
3.5. 文件節點鏈接
每一個文件節點都包含有對於目錄項的總鏈接數。Fsck為了校核一個文件節點的鏈接數,它從根目錄開始掃描,並且依次遞減目錄項中的鏈接數,最後比較所得鏈接數和文件節點包含的鏈接數是否一致,如果不一致則fsck會將實際的鏈接數保存到文件節點中。如果發現鏈接數為零,則說明此目錄項是被丟棄了的,於是fsck會將此目錄項存儲到lost+found目錄項中。每一個文件節點都保存有一個列表或是指向該列表的指針,此列表包含了此節點所使用的數據塊。由於間接數據塊是被文件節點所擁有的,所以如果它被破壞也直接地影響到文件節點。Fsck檢查一個文件節點所擁有數據塊是否存在於"已分配數據塊"列表中,如果不是,則查看它是否存在於"重復塊(duplicate blocks)"列表中,如果都不是,則將這個數據塊的塊號加入到"已分配數據塊"列表中。另外由於沒有足夠的信息來表明文件節點所指向的數據塊內容的正確性,所以如果文件內容被改變則無法被探測到。如果遇到硬件故障使得數據塊內容改變,此時fsck同時清除數據塊和文件節點。Fsck檢查一個文件節點包含的所有數據塊號對應的數據塊,如果這個數據塊號小於文件系統中最小的數據塊號或者大於最大的數據塊號則將它置為壞塊。壞塊通常是由硬件故障引起的,如果一個文件節點包含有壞塊號,則fsck將會清除此節點。
3.6. 文件結點數據大小
每個文件節點都有它所包含數據塊的總數,這個總是是已分配數據塊數目和間接數據塊數目的總和。Fsck就比較它計算所得到的數據塊總數和文件節點中的數據塊總數,看兩者是否一致,如果不一致,那麼fsck將修復它。另外,每一個文件節點都包含有一個32位的長度字段,它表示了文件大小的字節描述。
3.7. 檢查與文件節點相關聯的數據
一個文件節點可以和三種形式的數據塊相關聯。它們是:無格式數據塊(Plain data blocks)、符號鏈接數據塊(symbolic link data blocks)和目錄數據塊(directory data blocks)。
其中,無格式數據塊包含了文件的內容;符號鏈接數據塊包含了所指向文件的路徑;而目錄數據塊包含了目錄的結構信息。
Fsck只能檢查目錄數據塊的有效性,它檢查一系列的目錄錯誤,它們包括目錄節點號所指向的未分配文件節點、目錄節點號是否大於文件系統中所允許的最大目錄節點號、關於目錄項"."及".."的節點號是否有錯和一個目錄數據塊是否附在文件系統之上等錯誤。如果一個目錄節點的類型是"未分配節點"時,fsck將會刪除整個目錄節點和它所包含的目錄數據塊,這通常是由硬件故障引起的。當一個非法數據寫入目錄數據塊時,會引起目錄節點跑到文件系統節點列表之外,這種情況,fsck將刪除這個目錄節點。另外,對於目錄項"."的數據塊號必須時目錄節點數據塊列表中的第一項,因為它相當於這個目錄節點,如果不是這樣,fsck會修正它並使它成為此目錄節點數據塊列表中的第一數據塊。
3.8. 文件系統的連通性
Fsck檢查文件系統的連通性,檢查目錄項是否都被鏈入文件系統,如果不是則將它們存入lost+found目錄中,這種情況通常發生於硬件故障。