2011年10月27日木曜日

LVM+MB RAID

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
MotherBoardの機能を利用したRAID1を組んだのだが、どういうわけだか/dev/sdaと /dev/sdbがシンクロしないらしく、LVMのlogical volumeが読み書き不能になった。LVじゃないpartitionは大丈夫なのだが。いまどきdiskは安いのででっかくアロケートしてLVMでちまちま切り出して使うことは止めましょうかねぇ。

ともあれ、LVM関係のDocumentを読み漁ることになって、いままで概念的にしか知っていなかったLVMの実装っぽいところまで見るハメに。概念的な話なら、@ITとかにいい記事があったと思うし、結局「もう一段レイヤーをはさむ」ありがちな話なので難解ではない。

で、「ソフトウェアを分かるにはデータ構造を見よ」というありがたい教えにしたがい、メタデータの構造を調べた。Red HatのLVM metadataに関するドキュメント

「物理ボリュームラベルは文字列 LABELONE で始まります。」ということなので、ddした結果をhexdumpしgrepした。
hexdumpは不要かもしれないが、それではまわりがどうなっているのか分からんので、富豪的なアプローチをとった。

[root@livecd fromAkagi]# dd bs=512 skip=1000K count=128K if=/dev/sda | hexdump -C | grep LABEL
00100200  4c 41 42 45 4c 4f 4e 45  01 00 00 00 00 00 00 00  |LABELONE........|
00494110  3a 49 44 5f 46 53 5f 4c  41 42 45 4c 3d 6e 74 66  |:ID_FS_LABEL=ntf|
004e1120  3a 49 44 5f 46 53 5f 4c  41 42 45 4c 3d 74 65 73  |:ID_FS_LABEL=tes|
004e1130  74 0a 45 3a 49 44 5f 46  53 5f 4c 41 42 45 4c 5f  |t.E:ID_FS_LABEL_|

ddして周辺のデータを生きているfs上のfileとして持ってくる。
[root@livecd fromAkagi]# dd bs=512 skip=1001K count=128K if=/dev/sdb of=head-sdb.img
131072+0 records in
131072+0 records out

[root@livecd fromAkagi]# dd bs=512 skip=1001K count=128K if=/dev/sda of=head-sda.img
131072+0 records in
131072+0 records out

ここからの引用になりますが、

ボリュームグループ情報が含むものとしては
  • 名前と独自の識別子
  • メタデータが更新される度に上昇するバージョン番号
  • プロパティ: 読み込み/書き込み? サイズ変更可能?
  • 含まれる物理ボリュームと論理ボリュームの数量に対する管理制限
  • エクステントのサイズ(512 byte として定義されるセクターのユニットで表示)
  • ボリュームグループを構成する物理ボリュームの自由配列一覧、それぞれ以下を含む:
    • UUID:それを含有するブロックデバイスの決定に使用
    • プロパティ:物理ボリュームの割り当て可能性など
    • 物理ボリューム内の一番目のエクステントの開始点までのオフセット(セクターで表示)
    • エクステントの数量
  • 論理ボリュームの自由配列一覧、それぞれ以下を含む
    • 論理ボリュームセグメントの順番配列一覧。それぞれのセグメント用にメタデータは
      物理ボリュームセグメント、または論理ボリュームセグメントの順番配列一覧に適用 するマッピングを含んでいます。
とからしい。
実際、dumpを順番に見ていくと、こんな感じで整理できる情報が手に入る。かなり編集してあります。
PVをどっからとっているのかとか、どのように使っているのか、とかねぇ。LVを追加すると、
どんどん後ろにappendされていくようだ。たしかに、flushのタイミングがおかしくなったときに
情報が失われてしまうからね。
812000... => PV info? seq=1, empty
816000... => PV info? seq=2 on LogVolSwap
  LogVolSwap 0, 17500, on [PV0, 0]
81a000... => PV info? seq=3 on LogVolSwap, LogVolHome
  LogVolSwap 0, 17500, on [PV0, 0]
  LogVolHome 0, 25000, on [PV0,17500]

820000... => PV info? seq=4 on LogVolSwap, LogVolHome
  pv0 = /dev/md127p2
  LogVolSwap 0, 17500, on [PV0, 0]
  LogVolHome 0, 25000, on [PV0,17500]
  LogVolRoot 0, 25000, on [PV0,42500]

826000... => PV info? seq=4 on LogVolSwap, LogVolHome
  pv0 = /dev/md127p2
  LogVolSwap 0, 17500, on [PV0, 0]
  LogVolHome 0, 25000, on [PV0,17500]
  LogVolRoot 0, 25000, on [PV0,42500]
  LogVolRoot 0, 159306, on [PV0,67500]
いっぽうで、PV/PEに関する情報は
PE info
extent size=8192 (x512bytes, 4MiB)
pe_start = 2048
pe_count = 226806
なので、総合すると、すべてのPEとLEを使っていて、226806で一致している、PV0を線形に使っているので、
offsetを計算してあげれば、ddをつかってimageを作れるはず、というとことまできた。

が、offsetの計算がなんか怪しいらしく、取り出したimageのfile system ext4が壊れているかもしくは
存在しないことになってしまっている。LVMのmetadataを利用してdeviceを作ることができればもうちょっと作業が
楽になるハズが・・・。

がー、なんか手動で--maps相当をやっていたようだ。 via これ

LVM を利用していると、ディスク不良が発生した時に不良箇所がファイルシステム上のどこに相当するかを調べるのが面倒になります。具体的にはコマンド pvdisplay のオプション --maps で割り当て状況を確認し、物理ボリューム上のどの位置がどの論理ボリュームのどこに相当するのか確認しなければなりません。このため実運用では RAID 構成のストレージ上に LVM パーティションを作成する事をお勧めします。


こんなような結果が得られる。
  --- Physical volume ---
  PV Name               /dev/sdb2
  VG Name               vg_akagi
  PV Size               885.96 GiB / not usable 0   
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              226806
  Free PE               0
  Allocated PE          226806
  PV UUID               yIkDlv-9zdI-wj9A-YaGd-pKc3-8uNH-sOZhTa
   
  --- Physical Segments ---
  Physical extent 0 to 17499:
    Logical volume /dev/vg_akagi/LogVolSwap
    Logical extents 0 to 17499
  Physical extent 17500 to 42499:
    Logical volume /dev/vg_akagi/LogVolHome
    Logical extents 0 to 24999
  Physical extent 42500 to 67499:
    Logical volume /dev/vg_akagi/LogVolRoot
    Logical extents 0 to 24999
  Physical extent 67500 to 226805:
    Logical volume /dev/vg_akagi/LogVolData
    Logical extents 0 to 159305
先日書いたpython scriptでsdaとsdbを比較した結果(sda2とsdb2じゃないのがイケてない。sda1/sdb1には500Mくらいの/bootのpartitionが存在する)では174815245KiBあたりから不一致だった。PE/LE換算42554あたりから42992あたりまでおかしいので、Rootの部分がなにやらおかしなことになっていると検討がつく。Kernel Panicがおこることが説明できる。

今後の作業は
  • 無傷であると思われるDataとHomeの救済、backup

  • Rootの修復

である。sda/sdbの間でRootの部分を上書きコピーしてやる荒技もアルが、そのときはsda/sdbで食い違う部分をddして保管したのちに試みるべきだね。

0 件のコメント: