debugfsを使用したddrescueマッピングファイルのバッチ処理

debugfsを使用したddrescueマッピングファイルのバッチ処理

418個の不良セクタをリストするmapfileジェネレータがありますddrescue。ここで、各行は次のようになります(マイナス記号は不良ブロックを示します)。

Position      Size
0x1CC7C68000  0x00001000  -

debugfsバイト位置をパーティションの相対セクタ番号に変換することで、inode番号を照会し、破損したファイルのパスを見つけるために使用できます。不良ブロックがほぼ2000個に達するので、これを手動で行うことは不可能なので、これを自動化したいと思います。debugfsファイルシステムで一連のコマンドを実行するスクリプトを作成する方法はありますか?

破損したセクタのファイル名を取得するために現在実行されているタスクは次のとおりです。

  1. 場所は、ddrescue mapfileディスクの先頭に基づいてバイト単位です。まず、512で割って位置をセクタ番号に変換してから、パーティションの開始セクタ位置を減算します。

    パーティションの最初のセクタ: 91914240 不良ブロック位置: 0x1CC7C68000 小数点: 123610759168 絶対セクタ位置: 123610759168/512 = 241427264 パーティションの相対ブロック 4-9 13024

したがって、不良セクタは149513024パーティションの起動に基づいています。debugfsこれで、次を使用してインデックスノードを見つけることができます。

$ debugfs
debugfs: open /dev/sdd3
debugfs: icheck 149513024
Block       Inode number
149513024   1183169
debugfs: ncheck 1183169
Inode   Pathname
1183169 /username/foo/bar/baz

debugfsブロック位置リストをに渡し、そのブロックをinodeに解析し、inodeをフィルタリングしてマッピングされていないinodeを除外し、パス名を使用して残りのncheckinodeを解析できるようにこのプロセスを自動化したいと思います。 debugfsといくつかのシェルスクリプトを使ってこれを達成できますか?

ベストアンサー1

私は私の問題に対する解決策を見つけたと信じています。しかし、誰かがよりエレガントな解決策を思いつくことができるのか、私の解決策でバグを見つけることができるのかはまだ疑問に思います。

stdinに書き込むことができることがわかったので、出力を解析できるdebugfs一連のコマンドを生成するだけです。debugfsddrescue

次のbashスクリプトは、というmapfile.ddrescue名前のファイルがによって生成された現在のディレクトリに存在すると仮定しますddrescue

for line in \
    $(cat mapfile.ddrescue | \
      grep -e "-$" | \
      awk -F" " '{print $1}' | \
      awk -F"0x" '{print $2}'); \
do \
    position=$(( 16#$line / 512 - 91914240 )); \
    result="$result $position"; \
done; \
echo -e "open /dev/sdd3\nicheck $result\nquit\n" | sudo debugfs

スクリプトは次のことを行います。

  1. 私がmapfile名前を付けたものを分析しました。ddrescuemapfile.ddrescue
  2. ハイフンで終わる行だけを保持するようにフィルタリングしました。不良ブロックがある場所です。
  3. 私はawkを使用してスペースを分割し、場所である最初のマークを印刷します。これには、0x34A933F000などの16進数が含まれます。
  4. Oxプレフィックスを削除しました。
  5. 呼び出し側が返した結果は$(...)forループへの入力として使用されるため、行には常に位置が含まれます。
  6. 私は$(( ... ))場所を512(セクターあたりのバイト数など)で割り、パーティションの開始位置(私の場合)を減算する式を使用して場所の計算を実行します91914240。これは、パーティションの開始に基づいてセクタ位置を提供します。
  7. 各場所をスペースで区切られたリストにリンクします$result
  8. debugfs最後に、sudoを使用して実行されるコマンドの標準入力にパイプする改行区切りコマンドのリストを生成します。このコマンドはデバイスを開きます(私の場合は/dev/sdd3)。その後でicheck実行され$result、終了しますdebugfs

このスクリプトを実行すると、このブロックのすべての内容をdebugfs見つけるのに長い時間がかかりましたinodes。私の場合、出力が印刷されるまで数分間中断されたようです。

スクリプトが完了したら、結果をテキストファイルにコピーして分析します。幸いなことに、ほとんどのセクタは割り当てられていないブロックを指し、残りのセクタのほとんどは同じ少数の数を指しますinode。行を削除<block not found>して重複エントリを削除した後は、手動チェックを使用できるinodes4行しか残りません。これにより、バックアップから復元しようとするファイルである4つのファイルパスが提供されます。debugfsncheck

背景 もともとdd256GB SSDの内容を大きなSSDにコピーしたかったのです。dd最後のパーティションの約45/185 GBでI / Oエラーのため中止されました。しかし、ddrescue保存できます。99.99%運転する。最後に、上記の解決策で、残りの1700kb、つまり418個の不良セクタがどのファイルに属しているかを確認でき、4個のファイルのみが破損していることがわかりました。これで、どのファイルが破損しているかを把握し、以前のバックアップからそのファイルを復元できるため、データ復旧に対する自信が大幅に向上しました。

おすすめ記事