418個の不良セクタをリストするmapfile
ジェネレータがありますddrescue
。ここで、各行は次のようになります(マイナス記号は不良ブロックを示します)。
Position Size
0x1CC7C68000 0x00001000 -
debugfs
バイト位置をパーティションの相対セクタ番号に変換することで、inode番号を照会し、破損したファイルのパスを見つけるために使用できます。不良ブロックがほぼ2000個に達するので、これを手動で行うことは不可能なので、これを自動化したいと思います。debugfs
ファイルシステムで一連のコマンドを実行するスクリプトを作成する方法はありますか?
破損したセクタのファイル名を取得するために現在実行されているタスクは次のとおりです。
場所は、
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を除外し、パス名を使用して残りのncheck
inodeを解析できるようにこのプロセスを自動化したいと思います。 debugfsといくつかのシェルスクリプトを使ってこれを達成できますか?
ベストアンサー1
私は私の問題に対する解決策を見つけたと信じています。しかし、誰かがよりエレガントな解決策を思いつくことができるのか、私の解決策でバグを見つけることができるのかはまだ疑問に思います。
stdinに書き込むことができることがわかったので、出力を解析できるdebugfs
一連のコマンドを生成するだけです。debugfs
ddrescue
次の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
スクリプトは次のことを行います。
- 私が
mapfile
名前を付けたものを分析しました。ddrescue
mapfile.ddrescue
- ハイフンで終わる行だけを保持するようにフィルタリングしました。不良ブロックがある場所です。
- 私はawkを使用してスペースを分割し、場所である最初のマークを印刷します。これには、0x34A933F000などの16進数が含まれます。
Ox
プレフィックスを削除しました。- 呼び出し側が返した結果は
$(...)
forループへの入力として使用されるため、行には常に位置が含まれます。 - 私は
$(( ... ))
場所を512(セクターあたりのバイト数など)で割り、パーティションの開始位置(私の場合)を減算する式を使用して場所の計算を実行します91914240
。これは、パーティションの開始に基づいてセクタ位置を提供します。 - 各場所をスペースで区切られたリストにリンクします
$result
。 debugfs
最後に、sudoを使用して実行されるコマンドの標準入力にパイプする改行区切りコマンドのリストを生成します。このコマンドはデバイスを開きます(私の場合は/dev/sdd3
)。その後でicheck
実行され$result
、終了しますdebugfs
。
このスクリプトを実行すると、このブロックのすべての内容をdebugfs
見つけるのに長い時間がかかりましたinodes
。私の場合、出力が印刷されるまで数分間中断されたようです。
スクリプトが完了したら、結果をテキストファイルにコピーして分析します。幸いなことに、ほとんどのセクタは割り当てられていないブロックを指し、残りのセクタのほとんどは同じ少数の数を指しますinode
。行を削除<block not found>
して重複エントリを削除した後は、手動チェックを使用できるinodes
4行しか残りません。これにより、バックアップから復元しようとするファイルである4つのファイルパスが提供されます。debugfs
ncheck
背景
もともとdd
256GB SSDの内容を大きなSSDにコピーしたかったのです。dd
最後のパーティションの約45/185 GBでI / Oエラーのため中止されました。しかし、ddrescue
保存できます。99.99%運転する。最後に、上記の解決策で、残りの1700kb、つまり418個の不良セクタがどのファイルに属しているかを確認でき、4個のファイルのみが破損していることがわかりました。これで、どのファイルが破損しているかを把握し、以前のバックアップからそのファイルを復元できるため、データ復旧に対する自信が大幅に向上しました。