2013年8月2日金曜日

Bad file descriptor の修復に失敗した話

先日、FreeBSD をインストールした古いノート PC で chronium をビルドしていたら、気がついたら、別に電源コードが抜けたとかバッテリーが切れたとかもないのに、ビルド途中に電源まで完全に落ちてしまっていました。
仕方ないので、一回 make clean して、続きをやろうとしたところ、恐らく落ちた時点でコンパイル中だったと思われるディレクトリが clean に失敗している様子。

改めて、該当ディレクトリに移動して、rm -rf work で work ディレクトリを手動削除しようとしたら、

ファイル名 : Bad file descriptor
...
ディレクトリが空じゃないので削除できません

のようなエラーメッセージが・・。

調べてみたら、この Bad file descriptor というのは、あまり例のないエラーのようで、関連する情報がほとんどなかったのですが、ファイルが壊れてしまった時に出るエラーメッセージのようです。

そこで、壊れてしまっているファイルを全部消そうと、該当ディレクトリで rm * しても、その一つ上で rm -rf ディレクトリ名 にしても、全く消すことができません。

マルチユーザモードで fsck -y しても、なぜか修復されず、シングルユーザモードで fsck -y / では、一旦修復しました!といわれるのに、ls -l するとやっぱり、ファイル名 : Bad file descriptor と表示されてしまいます。

これはもうクリーンインストールするしかないとは思ったのですが、調べた情報の中で、clri(8) を使ったら壊れた部分を消して修復可能なのではないか、という話があり、実行例もないようなので、ダメ元で、clri(8) を試して見ることにしました。

ちなみに、clri(8) は、man の情報によれば、fsck で適切に処理されないファイルを削除する、ものだそうです。

壊れたファイルが /path/to/hoge/hoe/hoehoe.txt の場合は、こんな感じになります。

% ls /path/to/hoge/hoe
hoehoe.txt : Bad file descriptor

本来であれば壊れたファイルの i ノード番号を取得して該当ファイルだけを削除したいところですが、Bad file descriptor なファイルの場合、既に i ノード番号すら取得できない状況のため、壊れたファイルの入っているディレクトリを削除してみることにします。

clri(8) は、マルチユーザモードでは実行できなかったため、シングルユーザモードで、

# df
Filesystem  1K-blocks     Used   Avail Capacity  Mounted on
/dev/ada0p2  23352220 12784608 8699436    60%    /
devfs               1        1       0   100%    /dev
# cd /path/to/hoge 
# ls -i
2899285 hoe <-壊れてないディレクトリ(中身のファイルは壊れてる)
# clri /dev/ada0p2 2899285
# fsck -y /

実行自体は、とりあえず、正常に終了しました。

それで、結果的にどうなったかというと・・

# ls
hoe : Bad file descriptor

なんということでしょう。
さっきまで、一応壊れていなかった hoe までもが壊れてしまったのです。
試しに、この一つ上の hoge でも試してみたら、hoge も壊れました・・。

そのため、結局このあと必要なファイルのみバックアップして、クリーンインストールしました。

単にわたしがうまくいかなかっただけで、うまくいくことも、もしかしたらあるのかもしれませんが、 crli(8) では Bad file descriptor は修復できない、と思ってたほうがいいのかもしれません。
やるなら、被害が拡大することを前提に、どうしようもないときだけ試してみるほうがよさそうです。

0 件のコメント:

コメントを投稿