md raid5:md内部セクター番号をオフセットに変換します


8

TL; DRの要約:mdセクター番号を/dev/mdXデバイス内のオフセットに変換し、それをで調査する方法xfs_db。セクター番号はからのものsh->sectorですlinux/drivers/md/raid5.c:handle_parity_checks5()

MDの内部がわからないので、printk追加したログからの出力をどうするか正確にわかりません。

コンポーネントデバイス(ddまたはhexエディター/ビューアー)へのオフセットも興味深いでしょう。

Linux-raidメーリングリストでこれを尋ねるべきだと思います。サブスクライバーのみですか、またはサブスクライブせずに投稿できますか?


私のデスクトップでは、4つのディスクのMD RAID5の上に直接xfsがあります(LVMなし)。最近のスクラブでゼロ以外が検出されましたmismatch_cnt(mdは一度に4kiBページで動作するため、実際には8)。

これはRAID5であり、通常の動作中に!= 0が発生する可能性があるmismatch_cnt RAID1 / RAID10 ではありません。(このWikiページの下部にある他のリンクは、一部の人々にとって役立つかもしれません。)

私は盲目的にできましたrepairが、どのファイルを再構築するかを選択する機会を失う以外に、破損の可能性をチェックするファイルがわかりません。 同様の質問に対するFrostschutzの回答は、ファイルシステムの違いを追跡するために私が見つけた唯一の提案です。面倒で遅いので、最初にいくつかのファイルに絞り込むために、より良いものを使用したいと思います。


ロギングを追加するカーネルパッチ

奇妙なことに、mdのチェック機能は、エラーが見つかった場所を報告しません私は追加printkログインするには、MD / raid5.cにsh->sectorif増加することを支店mddev->resync_mismatcheshandle_parity_checks5()(小さなパッチgithubの上で公開され、もともとkernel.orgから4.5-RC4に基づいて、。)これは一般的な使用のためにOKであるために、それはおそらくする必要があります不一致が多い修理でログが殺到しないようにします(たぶん、新しい値がresync_mismatches1000未満の場合にのみログを記録しますか?)。また、ログのみでログはないかもしれcheckませんrepair

同じ関数がそのセクター番号をのエラー処理の場合にswitch出力するので、(MDの内部を知らなくても)何か有用なものをログに記録していると確信しています

変更したカーネルをコンパイルして起動し、チェックを再実行しました。

[  399.957203] md: data-check of RAID array md125
...
[  399.957215] md: using 128k window, over a total of 2441757696k.
...
[21369.258985] md/raid:md125: check found mismatch at sector 4294708224    <-- custom log message
[25667.351869] md: md125: data-check done.

現在、そのセクター番号をどうするか正確にはわかりません。あるsh->sector * 512線形アドレス内は/dev/md/t-r5(別名/dev/md125)?各コンポーネントデバイス内のセクター番号ですか(3つのデータと1つのパリティセクターを指します)?RAID5のパリティ不一致は、mdデバイスのN-1セクターが危険にさらされており、ストライプユニットによって互いにオフセットされているため、後者を推測しています。セクター0はコンポーネントデバイスの最初の始まりですか、それともスーパーブロックまたは何かの後のセクターですか?handle_parity_checks5()計算/記録する必要があるという情報がもっとありましたか?

不一致のブロックのみを取得したい場合、これは正しいですか?

dd if=/dev/sda6 of=mmblock.0 bs=512 count=8 skip=4294708224
dd if=/dev/sdb6 of=mmblock.1 bs=512 count=8 skip=4294708224
dd if=/dev/sda6 of=mmblock.2 bs=512 count=8 skip=4294708224
dd if=/dev/sdd  of=mmblock.3 bs=512 count=8 skip=4294708224  ## not a typo: my 4th component is a smaller full-disk

# i.e.
sec_block() { for dev in {a,b,c}6 d; do dd if=/dev/sd"$dev" of="sec$1.$dev"  skip="$1"  bs=512 count=8;done; }; sec_block 123456

4つのraidコンポーネントすべてから4kのゼロを取得しているので、私はそうではないと思います0^0 == 0。それで、正しいパリティになるはずですよね?

mdでセクターアドレスを使用することに言及した他の場所はsync_minsync_max(sysfs内の)とです。 linux-raidリストのNeil Brownが、セクター番号がのドライブの故障についての質問に答えhdrecover、Neilはフルディスクセクター番号をMDセクター番号として使用しました。そうじゃないですか?mdセクター番号は、パーティションが含まれている完全なデバイスではなく、コンポーネントデバイス(その場合はパーティション)に関連していませんか?


XFSファイル名への線形セクター:

mdセクター番号がRAIDデバイスではなくコンポーネントのものであることに気づく前に、読み取り専用でそれを使用してみましたxfs_db

XFSが特定のブロックをどのように使用ているかを見つける方法に関するDave Chinnerの非常に短い提案は、私にはまったく機能しないようでした。(不一致のセクターでなくても、デバイスの末尾を超えてはならないため、一部のセクターでは何らかの結果が予想されます)

# xfs_db -r /dev/md/t-r5 
xfs_db> convert daddr 4294708224 fsblock
0x29ad5e00 (699227648)
xfs_db> blockget -nv -b 699227648
xfs_db> blockuse -n       # with or without -c 8
must run blockget first

え?ここで何が悪いのですか?これは別の質問になると思います。質問したり、この部分への回答を他の場所で見つけたりした場合は、これをリンクに置き換えます。

私のRAID5は基本的にアイドル状態であり、書き込みアクティビティnoatimeはなく、読み取りも最小限です(したがって、読み取りでは書き込みは行われません)。


私のセットアップに関する余分なもの、ここでは何も重要ではありません

私のファイルの多くはビデオまたはその他の圧縮データであり、データが正しいかどうか(ファイル形式の内部チェックサム、またはエラーなしでデコードされるかどうか)を確認する効果的な方法を提供します。チェックするファイルが分かれば、この読み取り専用ループバックメソッドは実行可能になります。しかし、カーネルがチェック中に必要な情報を持ち、簡単にログに記録できる場合、最初に不一致を見つけるためにファイルシステム内のすべてのファイルの4方向差分を実行したくありませんでした。


私の/proc/mdstatバルクデータ配列:

md125 : active raid5 sdd[3] sda6[0] sdb6[1] sdc6[4]
      7325273088 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU]
      bitmap: 0/19 pages [0KB], 65536KB chunk

これは、3台の東芝3TBドライブのパーティションと、パーティション化されていないWD25EZRSグリーン電源(低速)ドライブにあり、別の東芝と交換しています。(mdadm --replace冗長性にギャップのないオンラインでの使用に使用しています。1つのコピーの後に、問題を検出するために前後にRAIDの状態をチェックする必要があることに気付きました。そのとき、不一致を検出しました。長い間使用されている可能性があります。 、ほぼ1年前にいくつかのクラッシュが発生したため、古いログがなく、mdadmはデフォルトでこれに関するメールを送信しないようです(Ubuntu 15.10)。

私の他のファイルシステムは、3つの大きなHD(および/ var / tmpのRAID0)の以前のパーティションから作成されたRAID10f2デバイス上にあります。RAID5は大容量ストレージ専用であり、/homeまたはではありません/

私のドライブはすべて正常です。SMARTエラーカウントは0で、すべてのドライブのすべての不良ブロックカウンターで、短い+長いSMARTセルフテストに合格しています。


回答がないこの質問のほぼ重複:


printk内の数値が配列に対するセクターである場合、ストライプ幅で除算し、開始オフセットを追加して、コンポーネントデバイスに対するセクター番号に変換する必要があります。iirc、データを常にオフセット0で開始しないmdadmメタデータ形式を使用している場合、それが開始するオフセットがの出力にリストされますmdadm -E /dev/xxx
psusi

また、データの場所を見つけて不一致を確認でき、破損しているファイルの整合性をチェックする方法がある場合でも、データがファイルに属している場合でも、データが解放されている可能性があることに注意してください。スペースまたはfsメタデータ)、パリティも間違っている可能性が高いため、各データドライブを順番にマスキングすることで得られる可能性のある答えはどれも正しくありません。
psusi

@psusi:ありがとう、はい、ファイルの一部ではない可能性があります。私の文章を本当に不器用にすることなくそれを表現するのは困難でした。興味深いことに、おそらくどの再構成も正しくない可能性があります。どちらの方法でも、おそらくどこかに壊れたファイルがあることを知るだけでなく、名前を変更するファイルなどを知っておくと、はるかに幸福になり.damagedます。
Peter Cordes

回答:


2

TL; DR sh-> sectorは、データセクションの開始後の物理ディスクのセクター数です。


セットアップ

以下に、簡単なテスト設定を示します。

  • / dev / raidme / rd [0-3]、2GBデバイス
  • / dev / md127はこれら5つのraid5として作成され、xfsとして初期化され、ランダムなデータで埋められます

次に、ゼロ以外のブロックを取得して上書きします

# dd if=/dev/raidme/rd0 bs=1k count=1 skip=10240 | hexdump -C | head
...
# dd if=/dev/zero of=/dev/raidme/rd0 bs=1k count=1 seek=10240
...
# dd if=/dev/raidme/rd2 bs=1k count=1 skip=10240 | hexdump  -C | head
1024 bytes (1.0 kB, 1.0 KiB) copied, 8.6021e-05 s, 11.9 MB/s
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400

アレイを停止/再構築してdm / mdキャッシュがフラッシュされていることを確認し、次を確認します。

# mdadm --stop /dev/md127
# mdadm --assemble /dev/md127 /dev/raidme/rd*
# echo check > /sys/class/block/md127/md/sync_action
# dmesg | tail
...
[ 1188.057900] md/raid:md127: check found mismatch at sector 16384

ディスク上でブロック

では、最初に、16384が書いたものと一致することを確認しましょう。私の襲撃は、512Kのストライプを持っている私が作ったので、必ず私が一致しやすいように整列何かを書いて、我々はで書いた1024*10240すなわち0xa00000

パッチは情報を提供しますが16384、1つ注意すべき点は、データが0から始まっていないことです。

# mdadm -E /dev/raidme/rd0 | grep "Data Offset"
    Data Offset : 4096 sectors

それもそうだprintf "%x\n" $(((4096+16384)*512))と言い0xa00000ます。良い。


mdでブロック

それがmdの終わりにある場所を取得するために、実際にはより簡単です。それは単にセクター時間で与えられた位置number_of_stripesです。たとえば、私には4つのディスク(3 + 1)があるため、3つのストライプがあります。

ここでは、16384*3*512たとえばを意味し0x1800000ます。ディスクを十分に満たしたので、ディスクを読み取って1kのゼロを探すだけで簡単に確認できます。

# dd if=/dev/md127 bs=1M | hexdump -C | grep -C 3 '00 00 00 00 00 00'
... some false positives...
01800000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
01800400  6b a8 9e e0 ad 88 a8 de  dd 2e 68 00 d8 7a a3 52  |k.........h..z.R|

xfsでブロック

涼しい。それがxfsのどこにあるか見てみましょう。16384*3is 49152(daddrはセクター番号をとります):

# xfs_db -r /dev/md127
xfs_db> blockget -n
xfs_db> daddr 49152
xfs_db> blockuse -n
block 6144 (0/6144) type data inode 2052 d.1/f.1

確かに、ゼロはそのファイルにあります:

# dd if=/mnt/d.1/f.1 bs=1M | hexdump -C | grep -C 3 '00 00 00 00 00'
...
03680000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
03680400  6b a8 9e e0 ad 88 a8 de  dd 2e 68 00 d8 7a a3 52  |k.........h..z.R|

そのファイルを上書きすると、ゼロも/ dev / raidme / rd0の正しいオフセットで削除されます(別のファイルで上書きするだけです)。/ dev / raidme / rd0に再度書き込んだ場合(アレイを再度停止/開始したことを確認してください)、ゼロは元に戻ります。いいね。

ただし、もう1つの問題があります。ストライプサイズがここ(512k)と同じである場合、処理できるブロックは1つではありませんが、1.5 MBのデータが破損している可能性があります...多くの場合、単一ファイルですが、xfs_dbに戻って確認する必要があります。以前のiノードは2052でした。

xfs_db> inode 2052
xfs_db> bmap
data offset 0 startblock 256 (0/256) count 17536 flag 0
data offset 17536 startblock 122880 (0/122880) count 4992 flag 0
data offset 22528 startblock 91136 (0/91136) count 3072 flag 0

ここでのブロックのサイズは4096バイトです(を参照xfs_info)。したがって、1.5MBは384ブロックです。破損したセグメントはブロック6144から6528で、このファイルの最初のセグメント内にあります。

他に確認することは、ブロックを手動で抽出し、チェックサムが正確に一致しない場所を確認することです。


最後にあなたのパッチについて、私はmd開発者ではありませんが、ex-mdadm raid5ユーザーとして私はかなり興味を持っていました。少しプッシュするのは間違いなく価値があると思います。あなたが言及したクリーンアップは役に立つかもしれません、そしてパッチを提出したら開発者がいくつかのコメントを持っていると私は確信していますが、heck mdはこれらのエラーについてより詳細にする必要があります!


ええと、その下にあるブロックデバイスの位置を指摘してくれてうれしいです。私の場合、printf '%#x\n' $(( (259072+4294708224 )*512 ))isですが0x20000000000、これは明らかに偶然ではありません。(それは正確に2TiBです。grub-installやある種のMBRのことからいくつかの悪意があると思います)。影響を受けるファイルを見つけるためにMDデバイス内のオフセットを調べているだけなら、これに気付かなかったでしょう。(ところで、この%#x形式では0xプレフィックスが追加されます。)
Peter Cordes '22

xfs_dbmust run blockget firstあなたの例に従って、私がちょうど(質問に投稿したのとまったく同じように)しましたが、とだけ言います。blockget -v -n -b 12884124672特定のブロックを与えるために使用したとしても。私が使用ddし、hexdumpしかし、実際にそのブロックの不一致があることを発見します。3つはすべてゼロで、4つ目は1 kBで1つの1ビットが512kストライプに設定されています。(冗長性をチェックするために実際にXORブロックを行う方法を見つける必要がなかったので非常に便利です。)
Peter Cordes '22

daddr最初に(blockgetの前に)使用すると、エラーメッセージは表示されず、blockget -v -nおよびからの出力がまったくありませんblockuse -v -n。問題がある場合、xfsprogsは3.2.1ubuntu1で、Linux 4.2.0-36-generic(パッチを当てた-rcカーネルではありません)を使用しています。私のFSはを使用crc=1 isize=512しています naming =version 2 bsize=4096 ascii-ci=0 ftype=1
Peter Cordes '22

とにかく、この回答は、コンポーネントデバイスとmdデバイス上の不一致ブロックの場所を正しく識別します。機能しないのは、XFSブロック->ファイル名の部分だけです。これは、実際には別の質問です。理論的にはfind -exec xfs_bmap -vpl {} +、既知のブロックを含むファイルを探すために使用できます。
Peter Cordes

1
残念ながら、xfs_dbにログジャーナルを無視させる方法(たとえば、100%の一貫性がない場合でも強制的にブロックゲットする)、またはumount / mountが実行するようにログを「フラッシュ」して、xfs_dbを幸せにする方法は知りません。 ..ええ、そうです、何かをこだわりたくない限り、再マウントできるようになるまで少し待つ必要があるかもしれません。私を最新の状態に保ち、そのパッチのアップストリームを試すことを忘れないでください:)
Asmadeus
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.