概要 | コマンドラインから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) |