描述

描述

描述

我有一個包含 6 個 SSD 驅動器的 IMSM RAID 5 陣列。其中一個驅動器幾個月前出現故障,我還無法更換它。 (是的,我知道我有時很懶。請不要評判我。)但我已經將其從 RAID 中刪除了。

然而昨天另一個驅動器似乎故障了。數組未組裝。因為即使 BIOS 也無法建置 RAID,我無法啟動任何東西。仔細檢查後發現驅動器似乎沒有問題。我可以訪問它並使用 dd 進行備份。但現在一開始好像有MBR記錄。也許某個進程用 MBR 表覆蓋了 RAID 超級區塊?如果是這種情況,數據應該仍然存在。我只需要能夠說出mdadm正確的元資料。當我想到這一點時,同樣的事情可能也發生在第一個據稱“失敗”的驅動器上。因為它仍然可讀。但當時我並沒有費心去調查。

儘管如此,我現在正在嘗試找到一種方法來重新組裝數組以存取其資料(如果可能)。我知道區塊大小、磁碟機的確切順序以及 RAID 等級。這些資訊還不夠嗎?

一些資訊

dd我做的第一件事是使用(named )建立剩餘 5 個磁碟機的映像sd[a-e].backup。我還檢查了所有使用的驅動器--examine並保存了輸出。您可以讀取輸出這個要點。如您所看到的,mdadm 讀取 MBR 標頭sdb並繼續到下一個驅動器,而不會偵測到任何 RAID 資訊。對於所有其他驅動器,mdadm 會列印正確的元資料。當我們這樣做時,這是輸出cat /proc/mdstat

Personalities:
md127 : inactive sda[3](S) sdd[2](S) sde[1](S) sdc[0](S)
      13049 blocks super external:imsm

unused devices: <none>

我嘗試過的

  • 顯然我試圖“將其關閉並再次打開”:
# mdadm --stop /dev/md127
mdadm: stopped /dev/md127
# mdadm --assemble /dev/md0 /dev/sdb missing /dev/sda /dev/sdc /dev/sde /dev/sdd
mdadm: Cannot assemble mbr metadata on /dev/sdb
mdadm: /dev/sdb has no superblock - assembly aborted
# mdadm --assemble --scan

最後一次呼叫 mdadm 後,/proc/mdstat再次看起來與上面的輸出相同。

然後我創建了只讀循環設備:

# losetup --show -rf /mnt/backup/sdX.backup
[...]
# losetup -a
/dev/loop1: [...] (/mnt/backup/sda.backup)
/dev/loop2: [...] (/mnt/backup/sdb.backup)
/dev/loop3: [...] (/mnt/backup/sdc.backup)
/dev/loop4: [...] (/mnt/backup/sdd.backup)
/dev/loop5: [...] (/mnt/backup/sde.backup)
  • 接下來我嘗試使用,--build因為它不需要任何超級塊信息,並且所有元數據都可以手動提供:
# mdadm --build /dev/md0 --raid-devices=6 --level=5 --chunk=32 /dev/loop2 missing /dev/loop1 /dev/loop3 /dev/loop5 /dev/loop4
mdadm: Raid level 5 not permitted with --build

但顯然我不被允許--build在 5 級 RAID 環境中使用。

  • 接下來我嘗試使用--assemble但不使用有關 RAID 的 OROM 資訊。
# IMSM_NO_PLATFORM=1 mdadm --assemble /dev/md0 /dev/loop2 missing /dev/loop1 /dev/loop3 /dev/loop5 /dev/loop4
mdadm: Cannot assemble mbr metadata on /dev/loop2
mdadm: /dev/loop2 has no superblock - assembly aborted

我想那太容易了。我可以以某種方式告訴 mdadm 假設這loop2是該陣列中的第一個裝置並使用來自其他磁碟機的元資料嗎?

  • 我嘗試的最後一件事是將循環設備重新安裝為讀寫並重新建立陣列。然而我發現的所有例子(像這個或者這個)假設該數組是使用 mdadm 建立的。但事實並非如此。它最初是由 BIOS 中的實用程式創建的,具有 IMSM 或 Intel 快速儲存格式。我想我必須對它有更詳細的了解,例如佈局或資料偏移。我不確定 IMSM 的預設設定是什麼,也不知道在哪裡可以找到它們。但更重要的是,我擔心 mdadm 的元資料格式比 IMSM 使用更多的空間和更大的超級區塊,並且在儲存元資料時會覆蓋資料。也許也可以使用 IMSM 重新建立陣列?或者也許可以將元資料儲存在外部。長話短說,我不知道如何使用 mdadm 手動重新建立 IMSM 陣列。

StackExchange 上的其他問題

  • 我知道這個問題。但我不確定這是否可以應用於我的情況,因為我使用的是具有不同超級塊(如果有的話)的 IMSM。
  • 我也讀過這個問題。然而,它處理的是 RAID 0,答案建議使用--build它不適用於 RAID 5。
  • 我也知道這個。但--force不適用於我的情況,因為有問題的驅動器不僅被標記為故障或不同步。我再次不確定應該如何使用 IMSM 專門重新建立陣列。

答案1

尤里卡 - 簡介

所以我找到瞭如何再次存取我的數據。不幸的是我無法使用重新建立數組mdadm。問題是,對於 IMSM,我必須先建立一個容器。但容器不接受遺失的設備。我需要原來的 6 個硬碟,但現在我只有 5 個。我也無法使用任何虛擬硬碟,因為它們需要連接到 RAID 控制器。此外,我不確定mdadm創建卷後是否或如何開始同步驅動器。然而我找到了一種涉及dmsetup.我可以再次存取我的所有文件。

在對驅動器執行多個備份以與它們一起使用時,我還意識到不再屬於陣列的一個驅動器有時會因 IO 錯誤而失敗。我仍然能夠進行備份,因為這些錯誤大約每三次調用dd.我推測,只要發生一個 IO 錯誤,驅動器就可能被 IMSM 從陣列中踢出,並且其所有元資料都被刪除。

我還意識到該驅動器是陣列中的第一個驅動器。由於我有一個 GPT 表,並且數組的資料從第一個扇區開始,因此它以 MBR 開始也是合乎邏輯的。因此驅動器的超級扇區沒有被 MBR 覆蓋。它一直在那裡。

讀取數據

我試圖在這裡給出一個逐步的解決方案,解釋該過程中使用的所有命令。希望這對那裡的人有幫助。

(可選)備份所有磁碟機

這並不是絕對必要的。特別是因為我們稍後將使用唯讀循環設備。然而,在我的儲存解決方案發生重大故障後,我特別偏執。所以我盡量避免使用實際數據。除此之外,使用備份檔案顯示這種方法根本不需要原始硬碟或BIOS。您所需要的只是一個 dd 圖像。如果您要跳過本節,請確保在下一節中將循環設備真正建立為唯讀,否則您可能會面臨資料品質進一步下降並可能永遠遺失的風險。

不過,這裡是備份硬碟的指令。您可能已經熟悉 dd。但如果您沒有為陣列中的每個硬碟執行此命令:

# dd if=/dev/sdX of=/path/to/backups/sdX.img status=progress
# dd if=/dev/sdY of=/path/to/backups/sdY.img status=progress
# [...]

輸入檔if=/dev/sdX是您的硬碟。替換sdXsdasdbof=/path/to/backups/sdX.img。再次sdX適當更換。status=progress只是告訴 GNU 版本的 dd 將當前進度印到 stderr。

建立循環設備

接下來我們將建立循環設備。如果我們使用備份映像,它可以確保它們被識別為區塊檔案。儘管這可能沒有必要。但無論如何,它確保圖像只會被讀取,因為我們使用的是唯讀標誌-r

# losetup --show -rf /path/to/backups/sdX.img
# losetup --show -rf /path/to/backups/sdY.img
[...]
  • -r: 只從檔案讀取,不寫入
  • -f:使用循環設備的下一個可用數字,這樣我們就不必自己猜測。
  • --show:列印實際選擇的名稱-f。這通常非常有用。儘管我們無論如何都會在下一步中列印這些值。

為了更好地了解我們剛剛創建的循環設備,我們可以使用以下命令:

# losetup -a
/dev/loop1: [2129]:251265027 (/path/to/backups/sdX.img)
/dev/loop2: [2129]:251265027 (/path/to/backups/sdY.img)
[...]

嘗試記住哪個循環設備屬於哪個影像。

收集一些元數據

接下來我們需要了解一些關於RAID的資訊。具體來說,我們需要找出 RAID 從哪個磁區開始(尤其是在矩陣 RAID 的情況下)、它跨越了多少個磁區、它的區塊大小和佈局是什麼以及磁碟機新增到陣列的順序。

如果至少有一個驅動器仍然是陣列的一部分並且附加了元數據,您可以使用它來檢索大部分所需的資訊。sdX在仍屬於陣列的磁碟機上執行下列命令:

# mdadm --examine /dev/sdX
/dev/sdX:
          Magic : Intel Raid ISM Cfg Sig.
        Version : 1.3.00
    Orig Family : aa0b2c12
         Family : 48d867fb
     Generation : 0018f99c
     Attributes : All supported
           UUID : 0312fa14:fa8db3c2:2a76dc3f:299ed5b4
       Checksum : 084869b8 correct
    MPB Sectors : 6
          Disks : 6
   RAID Devices : 1

  Disk02 Serial : S21PNSBG710576N
          State : active
             Id : 00000000
    Usable Size : 488391936 (232.88 GiB 250.06 GB)

Bad Block Management Log:
       Log Size : 2040
      Signature : abadb10c
    Entry Count : 254

[NameOfYourArray]:
           UUID : 24b1e785:14f37ee5:41f6a4ab:d8b89e11
     RAID Level : 5
        Members : 6
          Slots : [__UUUU]
    Failed disk : 1
      This Slot : 2
    Sector Size : 512
     Array Size : 2441959424 (1164.42 GiB 1250.28 GB)
   Per Dev Size : 488392200 (232.88 GiB 250.06 GB)
  Sector Offset : 0
    Num Stripes : 7631124
     Chunk Size : 32 KiB
       Reserved : 0
  Migrate State : idle
      Map State : failed
    Dirty State : clean
     RWH Policy : off

輸出繼續,但您可以忽略其餘部分。上面顯示的輸出產生以下有價值的資訊:

Sector Offset : 0       # Where the data starts
                        # (right at the first sector in my case)
Array Size : 2441959424 # Size of the volume (data) inside the array
Chunk Size : 32 KiB     # Size of a single chunk

您甚至可以確定特定磁碟機在陣列中的位置。

This Slot : 2

這意味著這是陣列中的第三個驅動器。 (槽號從零開始。)或Disk## Serial : [...]也提示槽號:

Disk02 Serial : S21PNSBG710576N

對所有磁碟機執行此命令。對於仍產生有效結果的結果,請記下插槽編號。

您可以使用另一個技巧來確定陣列中的第一個磁碟機。由於 RAID 是按區塊而不是按位元組寫入的,因此前 32 kiB 駐留在第一個磁碟機上。第二個驅動器上的第二個 32 kiB 依此類推。這意味著第一個磁碟機應該有足夠的磁區包含分割表的開頭。這意味著開始時應該有一個 MBR(即使您使用 GPT,因為它以保護性 MBR 開始)。mdadm --examine已經告訴您它在沒有元資料的情況下找到了 MBR。但您也可以使用fdisk -l.

就我而言,我能夠透過四個磁碟機的元資料找到它們的插槽號碼。我很幸運,第五個驅動器包含 MBR,所以我自動知道它是第一個。 6 個磁碟機中的 5 個足以啟動陣列。如果您不知道足夠驅動器的確切插槽號,您可以嘗試使用不同的排列,直到此方法成功。

這意味著我的驅動器以及循環設備的正確順序是:

投幣口 駕駛 循環裝置
主引導記錄 (0) /dev/sdb /dev/循環2
1 遺失的 -
2 /dev/sda /dev/循環1
3 /dev/sdc /dev/loop3
4 /dev/sde /dev/loop5
5 /dev/sdd /dev/loop4

最後要弄清楚的是佈局。不幸的是,mdadm我們沒有提供任何相關資訊。然而當我們看看Intel 的 RAID 定義看起來 RAID 5 的佈局總是不對稱的。我不確定 IMSM 陣列是否可以配置不同的佈局,但對我來說似乎不太可能。如果這一切都不適合您,那麼您可以嘗試不同的佈局。看一看在來源中閱讀有關其他佈局的更多資訊。

以下是 IMSM 支援的所有 RAID 等級的概述。 dmsetup 關鍵字將在下一章中使用。

RAID等級 佈局 dmsetup 語法
0 不適用 突襲0
1 不適用 突襲1
5 左不對稱 突襲5_la
10 預設(無 1E 或複製) 突襲10

如果您無法從任何驅動器收集任何元數據,那麼您必須猜測值和/或嘗試不同的組合。作為幫助,這些是 IMSM 支援的不同模式:

資訊 可能的值
RAID 級別 0、1、5、10
塊尺寸 4 kiB、8 kiB、16 kiB、32 kiB、64 kiB、128 kiB

對於起始磁區和大小,如果您不確定,最好假設為零,並且陣列中最小磁碟機的大小乘以非奇偶校驗磁碟機的數量。您可以透過發出以下命令來取得磁碟機的磁區大小:

blockdev --getsize /dev/sdX

如果您的資料實際上並非從零開始,您仍然可以稍後透過以下方式獲得正確的偏移量搜尋分區頭或者甚至可以透過搜尋檔案系統

使用 dmsetup 組裝陣列

不幸的是,當您使用時,無法手動提供元資料mdadm。唯一的例外是可以使用的 RAID 等級 0 和 1--build:

mdadm --build /dev/md0 --raid-devices=2 --level=0 --chunk=32 /dev/loop0 /dev/loop1

由於我們在這裡運氣不佳,因此我們需要使用不同的工具。因此我們將使用它來dmsetup代替。dmsetup是建立映射到真實磁碟機或其他來源的虛擬硬碟的命令。這些映射由多個部分組成,每個部分可以映射到不同的驅動器。在我們的例子中,我們只需要一個部分,並且我們將映射到一個 RAID,我們將手動提供其元資料。

但首先我們需要談談數字。正如我們之前確定的,我的案例中的區塊大小為 32 kiB。但是dmsetup需要部門。幾乎在所有情況下,一個磁區等於 512 位元組。如果您想安全起見,可以使用 檢查磁區大小blockdev --getss /dev/sdX。就我而言,這意味著32 kiB / (512 bytes/sector) = 64 sectors。我們已經知道數組中資料的大小(以扇區為單位)(即 2441959424)。但有一個問題。我有 6 台設備。對於每個條帶一個奇偶校驗區塊,區塊的數量必須可以被 5 整除。但我什至不確定這是否得到保證。數據似乎在最後一條條帶的中間停止了。不幸的是 dmsetup 不會容忍這種情況。這意味著我們需要四捨五入到可被 5 個驅動器和 64 個扇區整除的最接近的整數(根據您的情況調整這些數字)。在我的例子中,這是:2441959680 fdisk。但我們可以透過截斷 dd 圖像來解決這個問題。

現在建立一個文件(例如table.txt),其中一個部分包含一行。

<start> <size> raid <raid layout> 2 <chunk size> nosync <num devices>[ - /dev/loopN|-]*num_devices

首先,您必須給出扇區的起始位置和大小。下一個參數表示這是一個 RAID。有關 RAID 佈局,請參閱上一節中的表格。下一個參數中的「2」表示 RAID 的兩個特殊參數。第一個是塊大小。第二個將阻止任何同步。之後,您必須透過先提供裝置數量,然後為每個裝置提供一對元資料和裝置路徑來描述您的磁碟機。由於我們不想提供任何元數據,因此我們使用破折號來表示這一點。如果設備遺失,我們會寫兩個破折號,表示元資料和設備都不可用。如果 RAID 等級允許,建議至少保留一個裝置。如果您已經懷疑某個磁碟機可能包含錯誤資料,請選擇該磁碟機。

例如,就我而言,文件如下所示。請注意,第二個設備遺失了。

0 2441959680 raid raid5_la 2 64 nosync 6 - /dev/loop2 - - - /dev/loop1 - /dev/loop3 - /dev/loop5 - /dev/loop4

現在執行以下命令來建立一個映射到我們的陣列的新區塊檔案:

# dmsetup create sdr /path/to/table.txt

這可能會引發一堆 IO 錯誤。在這種情況下,磁區的大小可能無法被區塊大小整除。您可以使用以下命令刪除區塊檔案以重做最後一步:

# dmsetup remove sdr

現在讓我們看看這個新建立的設備檔案。如果你跑

# fdisk -l /dev/mapper/sdr

您應該能夠看到您的分區表。如果您有 GPT 表,請不要擔心會出現的兩個錯誤。大小不匹配和丟失備份表的原因是我們為 RAID 選擇的大小太大。

我的看起來像這樣:

Device                     Start        End    Sectors   Size Type
/dev/mapper/sdr-part1       2048     923647     921600   450M Windows recovery environment
/dev/mapper/sdr-part2     923648    1128447     204800   100M EFI System
/dev/mapper/sdr-part3    1128448    1161215      32768    16M Microsoft reserved
/dev/mapper/sdr-part4    1161216  679840003  678678788 323.6G Microsoft basic data
/dev/mapper/sdr-part5  679841792  680902655    1060864   518M Windows recovery environment
/dev/mapper/sdr-part6  680904704 2295472127 1614567424 769.9G Linux filesystem
/dev/mapper/sdr-part7 2295472128 2441957375  146485248  69.9G Linux swap

使用此表中的起始和磁區列,我們甚至可以掛載其中一些分割區。請注意,所有數字均以磁區為單位,需要乘以 512 轉換為位元組。

# mount -o ro,noload,loop,offset=348623208448,sizelimit=826658521088 /dev/mapper/sdr /mnt

這意味著我的 Linux 分割區現在安裝在 /mnt 上,我可以以ro(即唯讀)模式瀏覽所有檔案。需要noload的是阻止 ext4 執行寫入操作

現在我們最後將使用 dd 執行完整備份。

# dd if=/dev/mapper/sdr of=/path/to/backups/raid.img status=progress

還記得我們如何建立一個比應有的稍大的 RAID 嗎?我們可以利用這個機會透過將圖像截斷到正確的大小來修正此錯誤。扇區數需要轉換為位元組:2441959424*512 = 1250283225088

# truncate -s 1250283225088 /path/to/backups/raid.img

現在fdisk -l不再抱怨尺寸不符。

相關內容