rmで消してしまったファイルの復活方法
rmで消してしまったファイルは基本的に二度と復活しない。 しかし、昨日とうとうやってしまった。まず最初にPCのHDDがクラッシュ。 なんとか復旧させたが自分のアドレス宛てのメールボックスだけどうしても 復旧できない。
だがこういう時のために、メールのバックアップを取るまでメールサーバーの スプールに延々とメールを溜め込んできた。確か4000通分くらいはあったと思う。 こいつを持ってくれば修復はすぐ終わる。
と思ったのが甘かった。復旧を急ぐあまり、ついdatulaの初期設定を忘れ 「サーバーのメールは消去する」のままPOP3に繋いでしまった。
ガリガリというすごい音を立てて、スプールは一瞬にして消えた。
しかしそれでも、消えてしまったスプールを諦めるわけにはいかない。 rmで消えたファイルは二度と戻らない。これは基本的に正しい。 ディスクのどこの領域にどういうファイル名でデータが入っていたか という情報を、多くのUNIX系のシステムはrm一発で全て忘れてしまう。 ただ、データそのものまで消去してしまうと時間の無駄なので、 データ本体はHDDに残ったままになっていることが多い。
ただ、消えたファイルのデータがどこに行ってしまったのか見極める 方法がないだけだ。
メールの場合、テキストファイルである上にRFCによる定義で多くの特徴を持っている。 ファイルシステム上のファイルは分割されてバラバラに保存されていることが多いが、 メールの場合は1通が短いのでその可能性も少ない。しかも実行プログラムなどと違って 一部が欠損していてもなんとか読むことができる。
ここは、ディスクのイメージを取って、無理矢理データを吸い出すしかないだろう。
とりあえず、これ以上/usr/にデータを書き込まれないよう、 /usr/を強制アンマウント。そしたらtelnet接続が落ちてしまった。当たり前か。
getty本体が消えたせいかコンソールも動かなくなってしまったので、 Ctrl+Alt+Del連打でリブート。ちゃんとsyncとかはしてくれたみたいなので 特に心配はない。やっぱりこういう作業はシングルユーザモードじゃないと無理か。
で、Boot: で-sを打ち込みシングルユーザモードで起動。
ifconfig inet 210.428.74.xx netmask 0xfffffff0
とりあえずNFSを使うのでifconfigしてネットワーク接続する。
mount /var
等をして、/usr/以外のファイルシステムをマウント。しかし、lessとかviとか 使えないと結構きつい。/stand/の中のコマンドだけでなんとか凌ぐ。
mount_nfs -S 210.448.74.xx:/usr /lroot
として、バックアップ先の別マシンの/usrを/lrootにマウント。
別マシン上では、予め/usr/tmpにパーミッション0777のディレクトリを掘っておく。 そうしないとNFSからはPermission Deniedで書き込みができない。
dd if=/dev/sd0xxxx of=/lroot/tmp/dumpall.dmp
これでバックアップ実行。ifに指定するデバイス名は、/etc/fstabを見て判断する。
とりあえずここまでで、/usr領域のフルダンプを別マシンに取ることができた。 しかし、/var/じゃなくて/usrなのが痛い。 sendmailの頃なら/varだったのでせいぜい100MBくらいでよかったのだが、 今度は/usrだから1.5Gくらいある。しかもsendmailと違って1ファイルずつ 保存されているので、ファイルシステムのあちこちにメールが散らばってい ることになる。
ダンプ先のマシンにログインして'From: '辺りでgrepかけると 何件か引っかかってくれる。あとはダンプが終わるのを待って、Perlスクリプトを 作ってメールに見える部分を切り出してやるだけだ。
結局この方法で、大多数のメールを救出することができた。
ちなみに、このディスクイメージは、FreeBSD(うちのは2.2.8)の場合、
vnconfig -c /dev/vn0c ./fulldump.dmp mount -r /dev/vn0c /mnt
とすることで、/mntにマウントすることができる(linuxだと、mountコマンドにloop を指定するようだ)