概要 |
コマンドラインから rm コマンドで削除したファイルの復活方法を解説します.
|
---|---|
検証環境 |
Ubuntu 12.04 x86_64 ファイルシステム: ext4 |
備考 |
ここで説明する方法は ext4 または ext3 のみに適用可能なものです.
ext2 では mc (GNU Midnight Commander)というファイラーの Undelete files 機能を使うことで回復できる可能性があります.参考:@IT 削除したファイルを復活するには |
削除したファイルを格納していたパーティションを unmount
するか read-only にしてください.
[備考: これを容易にするため,OS本体とユーザーデータを格納するディレクトリ(home
ディレクトリ)を別パーティションにしておくことをおすすめします.
ルートディレクトリと /home
が同じパーティションに格納されている場合,パーティションのアンマウントが難しくなり,ファイルを回復できる見込みは薄くなります.]
/home
を unmount
する場合,下記のとおりです.
カレントディレクトリが /home
の下になっていると
devide is busy
エラーになってしまいますので,この例では先にカレントディレクトリをルート(/
)に移動しています.
$ cd / $ sudo unmount /home
/home
を read-only にする場合,下記のとおりです.
2つ目の mount
コマンドは remount
したパーティションが read-only になっていることを確認するためのものです.
ro
と表示されれば read-only になっています.
read-only になっていることを確かめるために実際に書き込んでみるというような勝負をすべきではありません.
$ sudo mount -o remount,ro /home $ mount /dev/sdc2 on /home type ext4 (ro,errors=remount-ro)
ここまで実施すれば,ファイルが(ここで紹介する方法で)復活できるか,そうでないかは確定します. [復活させたいファイルが画像ファイルや音声ファイルなど“ある種の特徴”をもっている場合,ディスク上の全セクタを走査して“ある種の特徴”に合致するデータを見つけ出すというヒューリスティックな方法で復活できる可能性があります. 詳しくは「PhotoRecによる削除済みファイルの復元」を参照してください.]
復元したいファイルが /dev/sdc2
に格納されていた場合,下記のように実行します.
$ sudo extundelete /dev/sdc2 --restore-all WARNING: Extended attributes are not restored. Loading filesystem metadata ... 14905 groups loaded. Loading journal descriptors ... 32420 descriptors loaded. Searching for recoverable inodes in directory / ... 7232 recoverable inodes found. Looking through the directory structure for deleted files ...
復元したファイルはデフォルトではカレントディレクトリの
RECOVERED_FILES
ディレクトリに格納されますので,十分な容量があるディレクトリで実行してください.
この例では /dev/sdc2
上の復活可能な削除済みファイルすべてを復元しています.
それでは多すぎる場合,オプションで,ある時刻以降に削除したファイルのみ,あるパスの下にあったファイルのみを復元するように指定してください.
日時指定の例 |
$ date --date='2012-01-01 00:00' '+%s' Sun Jan 1 00:00:00 JST 2012 $ sudo extundelete /dev/sdc2 --after `date --date='2012-01-01 00:00' '+%s'` |
---|---|
パス指定の例 | sudo extundelete /dev/sdc2 --restore-files 'home/hatai/f.txt' |
ext4/ext3 上のファイルの復元は ext2 の場合より格段に難しいです. ユーザーからファイル削除の指示がでるとファイル本体を格納していたブロックやその inode,ディレクトリエントリに“未割りあて”(unallocated)のマークがつきますが,ext2 では inode 上に記録されている,ファイル本体を格納していたブロックのアドレスやファイルサイズの情報は(まだその時点では)残っています. しかし,ext4/ext3 では inode 上のファイル本体を格納していたブロックのアドレスやファイルサイズの情報がすべてクリアされてしまうのです. したがって,未割りあてになっている inode を強引に読んで目的のファイルを復元してしまうという方法がとれません.
そのため,ext4/ext3 では,(1)ファイルの特性を使って復元するか[例えば JPEG ファイルは仕様上 0xFFD8 ではじまって 0xFFD9 で終わることがわかってるため,この情報を頼りに復元することができます],(2)ジャーナルのログエントリを利用して復元するかの2通りしかなく,かつ,いずれも ext2 の場合より復元できる確率も低く,精度も悪くなります.
(1)の手法をつかった復元方法については「PhotoRecによる削除済みファイルの復元」を参照してください.
ここでは,extundelete
が使っている(2)のジャーナルを解析による復元方法を説明します(といってもたいした役にはたちませんが…).
debugfs で ls -d
コマンドを実行すると,現在存在するファイル(allocated files)と削除済みのファイル(unallocated files)の情報が得られます.
debugfs
で見たときに <> で囲まれて表示されるのが削除されたファイルの inode です.
$ sudo debugfs /dev/sdc2 debugfs 1.42 (29-Nov-2011) debugfs: ls -d 2 (12) . 2 (12) .. 11 (20) lost+found 18874369 (16) mirror 61865985 (32) bak <14> (20) .f.txt.swp 12 (4004) f.txt (END)
ジャーナル ログをみるには logdump -i
を使います.
ここでは削除済みの <14>
のログ エントリをみたいので下記のように指定します.
debugfs: logdump -i <14> Inode 14 is at group 0, block 1057, offset 1664 Journal starts at block 0, transaction 13933
上記のように素っ気なく表示された場合は,もうダメです.何も情報がなくて,これ以上進めないでしょう. 下記のように表示された場合は,いちおう情報は残っているのですが,この場合も inode の i_extra_isize が不正になっているため,過去の Blocks が取得できず,やはりダメです.
debugfs: logdump -i <14> Inode 14 is at group 0, block 1057, offset 1664 Journal starts at block 1, transaction 13934 FS block 1057 logged at sequence 13934, journal block 3 (flags 0x2) (inode block for inode 14): Inode: 14 Type: bad type Mode: 0034 Flags: 0x0 Generation: 0 Version: 0x00010000:00000000 User: 0 Group: 0 Size: 0 File ACL: 0 Directory ACL: 0 Links: 0 Blockcount: 0 Fragment: Address: 0 Number: 0 Size: 0 ctime: 0x00000000:08000000 -- Thu Jan 1 09:00:00 1970 atime: 0x00000000:4dc24c5f -- Thu Jan 1 09:00:00 1970 mtime: 0x4e2f0607:4dc24c5f -- Wed Jul 27 03:23:03 2011 crtime: 0x4dc24c5f:00000000 -- Thu May 5 16:06:07 2011 Size of extra inode fields: 33152 invalid inode->i_extra_isize (33152) Blocks: No magic number at block 9: end of journal.
私が試してみた限りでは extundelete
による復元の成功率は極めて低いものでした.
ext4 のジャーナルの理解が不十分なので結論は出せませんが extundelete
で復元できる可能性は低いと考えてよさそうです.
特殊な例になりますが,削除したファイルを開いているアプリケーションが残っている場合,そのアプリケーションがつかんでるファイルをコピーすることでファイルを救出する方法もあります.
例えば,動画が収録されている
f.iso
というファイルを再生中に f.iso
を rm
した場合,下記のように
lsof
(list open files)で開いているファイルの情報を得て,コピーすることができます.
この例では gvfsd-arc
というプログラムが開いている /home/unsync/f.iso
をコピーしています.プロセス番号が
10764,ファイル ディスクリプターが 9 なので /proc/10764/fd/9
が目的のファイルになっています.
$ lsof |grep iso gvfsd-arc 10764 hatai 9u REG 8,34 2340454400 13 /home/unsync/f.iso (deleted) $ cp /proc/10764/fd/9 x.iso
[1] | extundelete |
[2] | PhotoRecによる削除済みファイルの復元 |
[3] | Why Recovering a Deleted Ext3 File Is Difficult... |
[4] | ext4の徹底調査(by IBM) |