説明
私は 6 台の SSD ドライブを含む IMSM RAID 5 アレイを持っています。数か月前にドライブの 1 つが故障し、まだ交換できていません。(はい、私は時々怠け者だとわかっています。どうか私を批判しないでください。) しかし、私はすでに RAID からそのドライブを削除しました。
しかし昨日、別のドライブが故障したようです。アレイが組み立てられません。BIOS でさえ RAID の構築に失敗するため、何も起動できません。しかし、よく調べてみると、ドライブは正常のようです。dd を使用してアクセスし、バックアップを作成できます。しかし、先頭に MBR レコードがあるようです。何らかのプロセスが RAID スーパーブロックを MBR テーブルで上書きした可能性があります。その場合、データはまだそこにあります。mdadm
正しいメタデータを判断できればよいだけです。考えてみると、同じことが「故障」したとされる最初のドライブにも起こった可能性があります。まだ読み取り可能だったからです。しかし、当時は調査しませんでした。
それでも、私は現在、アレイを再構成してそのデータにアクセスする方法を見つけようとしています (可能であれば)。チャンク サイズ、ドライブの正確な順序、および RAID レベルはわかっています。これで十分な情報ではないでしょうか?
いくつかの情報
まず最初に、dd
( という名前sd[a-e].backup
)を使用して残りの5つのドライブのイメージを作成しました。また、 を使用してすべてのドライブを調べ--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 Rapid Storage 形式になっています。レイアウトやデータ オフセットなど、より詳細な知識が必要だと思います。IMSM のデフォルトが何であるか、どこで見つけられるかはわかりません。しかし、もっと重要なのは、mdadm のメタデータ形式が IMSM よりも多くのスペースと大きなスーパーブロックを使用し、メタデータを保存するときにデータを上書きすることを心配しています。IMSM を使用してアレイを再作成することもできるのでしょうか。または、メタデータを外部に保存できるかもしれません。簡単に言うと、mdadm を使用して IMSM アレイを手動で再作成する方法がわかりません。
StackExchange のその他の質問
答え1
ユーリカ - はじめに
そこで、データに再びアクセスする方法を見つけました。残念ながら、 を使用してアレイを再作成することはできませんでしたmdadm
。問題は、IMSM では最初にコンテナーを作成する必要があることです。しかし、コンテナーは不足しているデバイスを受け入れません。元の 6 台のハード ドライブがすべて必要なのですが、現時点では 5 台しかありません。また、仮想ハード ドライブは RAID コントローラーに接続する必要があるため、使用できません。さらに、mdadm
ボリュームを作成するとすぐにドライブの同期が開始されるかどうか、またどのように開始されるかはわかりません。ただし、 を使用する方法を見つけましたdmsetup
。すべてのファイルに再びアクセスできます。
ドライブを動作させるために複数のバックアップを実行しているときに、アレイの一部ではなくなった 1 つのドライブが IO エラーで時々故障することにも気付きました。これらのエラーは の呼び出しの 3 回に 1 回程度しか発生しなかったため、バックアップは作成できました。IO エラーの 1 つがdd
発生するとすぐに、ドライブは 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
はハードドライブです。sdX
をsda
、sdb
などに置き換えます。出力ファイルはof=/path/to/backups/sdX.img
書き込まれるイメージを指します。ここでもsdX
適切に置き換えます。status=progress
は、現在の進行状況を stderr に印刷するように dd の GNU バージョンに指示するだけです。
ループデバイスを作成する
次にループデバイスを作成します。バックアップイメージを使用する場合、ブロックファイルとして認識されることを確認します。これは必ずしも必要ではないかもしれませんが、いずれにしても、読み取り専用フラグを使用しているため、イメージが読み取り専用になることを保証します。-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 の場合)、RAID がいくつのセクターにまたがっているか、RAID のチャンク サイズとレイアウトは何か、ドライブがアレイに追加された順序は何かを調べる必要があります。
アレイの一部であり、メタデータが添付されているドライブが少なくとも 1 つある場合は、それを使用して必要な情報のほとんどを取得できます。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
これは、これがアレイ内の 3 番目のドライブであることを意味します。(スロット番号は 0 から始まります。) また、Disk## Serial : [...]
スロット番号のヒントも示します。
Disk02 Serial : S21PNSBG710576N
すべてのドライブに対してこのコマンドを実行します。有効な結果が得られるドライブについては、スロット番号を書き留めます。
アレイの最初のドライブを判別するのに使用できる別のトリックがあります。RAID はバイトではなくチャンクで書き込まれるため、最初の 32 kiB は最初のドライブにあります。次の 32 kiB は 2 番目のドライブにあります。以下同様です。つまり、最初のドライブにはパーティション テーブルの開始を含む十分なセクターが必要です。つまり、先頭に MBR があるはずです (保護 MBR で始まる GPT を使用している場合でも)。mdadm --examine
メタデータがない場合でも、既に は MBR が見つかったことを示しています。ただし、 を使用することもできますfdisk -l
。
私の場合、メタデータから 4 つのドライブのスロット番号を見つけることができました。5 番目のドライブには MBR が含まれていたので、それが最初のドライブであることが自動的にわかりました。6 つのドライブのうち 5 つがあればアレイを起動するのに十分です。十分な数のドライブの正確なスロット番号がわからない場合は、この方法が成功するまでさまざまな組み合わせを試すことができます。
つまり、ドライブ、つまりループ デバイスの正しい順序は次のようになります。
スロット | ドライブ | ループデバイス |
---|---|---|
0件のコメント | /dev/sdb | /dev/ループ2 |
1 | ない | - |
2 | /dev/sda | /dev/ループ1 |
3 | /dev/sdc | /dev/ループ3 |
4 | /dev/sde | /dev/ループ5 |
5 | /dev/sdd | /dev/ループ4 |
最後にレイアウトについて考えてみましょう。残念ながら、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
は、実際のドライブまたはその他のソースにマップされる仮想ハード ドライブを作成するコマンドです。これらのマッピングは複数のセクションで構成され、各セクションは異なるドライブにマップできます。この場合、必要なセクションは 1 つだけで、メタデータを手動で提供する RAID にマップしています。
しかし、まずは数字について話す必要があります。先ほど決定したように、私の場合のチャンク サイズは 32 kiB でした。ただし、dmsetup
セクターが必要です。ほとんどの場合、1 つのセクターは 512 バイトに相当します。安全を期したい場合は、を使用してセクター サイズを確認できますblockdev --getss /dev/sdX
。私の場合、これは を意味します32 kiB / (512 bytes/sector) = 64 sectors
。配列内のデータのサイズはセクター単位で既にわかっています (つまり、2441959424)。しかし、問題があります。デバイスが 6 台あります。ストライプごとに 1 つのパリティ チャンクがある場合、チャンクの数は 5 で割り切れる必要があります。しかし、セクターの数は 5 で割り切れません。私の場合、少なくともチャンクあたりのセクター数は割り切れます。しかし、それが保証されているかどうかさえわかりません。データは最後のストライプの途中で停止しているようです。残念ながら、dmsetup はこれを許容しません。つまり、5 つのドライブと 64 セクターで割り切れる最も近い整数に切り上げる必要があります (これらの数値は状況に応じて調整してください)。私の場合、これは 2441959680 です。つまり、fdisk
ドライブ サイズが間違っていることと、バックアップ テーブルが見つからないことに関するエラーが表示される可能性があります。ただし、dd イメージを切り捨てることでこれを修正できます。
table.txt
次に、 1 つのセクションに 1 行が含まれるファイル (例 ) を作成します。
<start> <size> raid <raid layout> 2 <chunk size> nosync <num devices>[ - /dev/loopN|-]*num_devices
まず、開始とセクター単位のサイズを指定する必要があります。次の引数は、これが RAID であることを示します。RAID レイアウトについては、前のセクションの表を参照してください。次の引数の「2」は、RAID の 2 つの特別なパラメータを意味します。1 つ目はチャンク サイズです。2 つ目は同期を防止します。その後、最初にデバイスの数を指定し、次に各デバイスのメタデータとデバイス パスのペアを指定して、ドライブを記述する必要があります。メタデータを提供したくないので、そのことを示すためにダッシュを使用します。デバイスがない場合は、メタデータもデバイスも利用できないことを示すために 2 つのダッシュを記述します。RAID レベルで許可されている場合は、少なくとも 1 つのデバイスを省略することをお勧めします。1 つのドライブに不良データが含まれている可能性があるとすでに疑っている場合は、そのドライブを選択します。
たとえば、私の場合、ファイルは次のようになります。2 番目のデバイスがないことに注意してください。
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 テーブルがある場合に表示される 2 つのエラーについては心配しないでください。サイズの不一致とバックアップ テーブルの欠落は、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
サイズの不一致について文句を言うことはなくなりました。