11. i-node を直接いじる

この方法は、表面的には、先ほどよりもずっと簡単です。しかし以前も触れた通り、 12 ブロック以上の大きなファイルに対しては役に立ちません。

復旧したいファイルそれぞれに対して、usage count を 1 に設定し、deletion time を 0 に設定します。これには debugfsmi (modify i-node) コマンドを使います。例として、これまでと同じく、 i-node 148003 を使って、i-node の変更処理を説明します。

  debugfs:  mi <148003>
                            Mode    [0100644]
                         User ID    [503]
                        Group ID    [100]
                            Size    [6065]
                   Creation time    [833201524]
               Modification time    [832708049]
                     Access time    [826012887]
                   Deletion time    [833201524] 0
                      Link count    [0] 1
                     Block count    [12]
                      File flags    [0x0]
                       Reserved1    [0]
                        File acl    [0]
                   Directory acl    [0]
                Fragment address    [0]
                 Fragment number    [0]
                   Fragment size    [0]
                 Direct Block #0    [594810]
                 Direct Block #1    [594811]
                 Direct Block #2    [594814]
                 Direct Block #3    [594815]
                 Direct Block #4    [594816]
                 Direct Block #5    [594817]
                 Direct Block #6    [0]
                 Direct Block #7    [0]
                 Direct Block #8    [0]
                 Direct Block #9    [0]
                Direct Block #10    [0]
                Direct Block #11    [0]
                  Indirect Block    [0]
           Double Indirect Block    [0]
           Triple Indirect Block    [0]

上記で、著者は deletion time に 0 を、link count に 1 を設定し、それ以外 のフィールドではそのままリターンキーを押しました。復旧したいファイル がたくさんある場合、この方法は確かにちょっと面倒ではありますが、 まあなんとかなると思います。 こうした方法を野暮だと思うのなら、かわいい 「ゴミ箱」アイコン付きのグラフィカルな "オペレーティングシステム" の方を とっくに使っているはずでしょうから。

ところで、mi コマンドの出力には、Creation time という フィールドがあります。これはウソです! (少なくとも誤解の素です。) 実際には、UNIX ファイルシステムではファイルの 作成時を知ることはできません。構造体 stat のメンバ である st_ctime は、i-node の更新時間を示す ものです。つまり i-node 内の何らかの情報が最後に変更された時刻を示している わけです。と、まあ、この話はここまで。

著者が上記の例で使った debugfs よりも新しいバージョン を使う場合は、例題で示したフィールドのいくつかが省略されるかもしれない ので注意してください(特に、Reserved1 と fragment フィールド (のいくつか) は省略されるようです)。

i-node の変更が済んだら、debugfs を終了して、以下のように してください。

  # e2fsck -f /dev/hda5

これには次のような意味があります。すなわち、削除されていたおのおのファイル は既に文字通り復旧しているのですが、まだディレクトリエントリには表示されない 状態です。e2fsck プログラムはこの状態を検出して、 そのファイルシステムの /lost+found ディレクトリ内に 個々のファイルのディレクトリエントリを追加するようになっています。 (したがってパーティションが通常 /usr にマウント されるのだとすると、ファイルシステムが次にマウントされた際に、復旧ファイルは /usr/lost+found に現れるわけです。) ここまで来れば、 あとはそのファイルの中身からファイル名を割り出して、そのファイルを ファイルシステムツリーの適切な場所に戻すだけです。

e2fsck を実行した際には、各種情報が出力されると同時に、 どのダメージを修復すべきかの質問が表示されます。"summary information" もしくは変更した i-node に関する事柄が表示された場合は、すべて yes で 答えてください。それ以外の質問については読者の判断にお任せしますが、 通常はすべての質問に yes で答えておくほうが無難です。e2fsck コマンドが終了したら、ファイルシステムを再マウントできます。

実は、e2fsck を使ってファイルを /lost+found に出現させる以外の方法もあります。debugfs を使えば、そのノードに対するリンクをファイルシステム内に 作成できるのです。i-node を変更した後で debugfs 作成することが可能です。i-node を変更した後で、debugfslink コマンドを使います。

  debugfs:  link <148003> foo.txt

これによって、debugfs コマンドが正しいと判断した ディレクトリ内に foo.txt という名前のファイルが 作成されます。この foo.txt というファイルが、読者の 求めていたファイルとなるはずです。ただこの場合でも、e2fsck を使って、summary 情報や block count 等を修復する必要があります。