次のページ 前のページ 目次へ

Ext2fs Undeletion mini-HOWTO  〜Ext2Fsでのファイル復活の方法〜
**************************************************************


by Aaron Crane <aaronc@pobox.com>
v1.0, Sat Jan 18 1997
日本語訳
吉川雅英 <kikkawa@m.u-tokyo.ac.jp>

もくじ
========

0.  はじめに
1.  どうしたらファイルを消さずに済むか
2.  どのくらいファイルを復活させることができるのか?
3.  では、どうやって、ファイルを復活させるのか?
4.  ファイルシステムのアンマウント
5.  iノードを直接変える準備
6.  データを他の場所に書き込む準備。
7.  消された i ノードを見つける。
8.  詳しく i ノードを調べる。
9.  データブロックを復活させる。
10. i ノードを直接いじる。
11. 将来的には、こうしたことはもっと簡単にならんのか?
12. こうしたプロセスを自動化するツールは何か無いのか?

付録
----

A.  出版社マーク Colophon
B.  クレジット
C.  参考文献
D.  合法性


0.はじめに
==========

この mini-Howto は、 ext2 ファイルシステムで消去したファイルを如何にして取り
出すかということについてヒントを提供するものです。また, 最初にはファイルを消
去しないようにするにはどうしたら良いかということもある程度書かれています。

このドキュメントは、 rm を使っていて、ちょっとした事故にたった今あってしまっ
た人に役に立つように書きました。しかし、そうでなくてもこのドキュメントを読ん
で欲しいと思います。いつの日か、ここに書かれた情報で危うく難を逃れることがで
きるかも知れませんから。

この文書は、一般的な Unix ファイルシステムについて、少々の知識を想定していま
す。しかし、ほとんどの Linux ユーザーには理解できると思います。もし、あなた
がまるっきりの初心者だとしたら、 Linux においてファイルを復活させるには、少
なくとも現状では、かなりの技術的な知識と忍耐が必要だということは覚えておいて
ください。

ext2 ファイルシステムから消去されたファイルを復活させるためには、そのファイ
ルが入っている raw デバイスにアクセスできなくてはなりません。一般には、これ
は root でなければならないことを意味します。また `e2fsprogs' に含まれる 
`debugfs' も必要です。これは、あなたの使ったディストリビューション(訳注:
Slackware, RedHat, Debianなど)からインストールされているはずです。

どうしてこの文書を書いたのかって?それは、私自身が、 root で `rm -r' を実行
するなどという、まったく馬鹿げて破壊的なことをしたからです。私は 97 個の 
JPEG ファイルを消してしまい、それは私にとっては不可欠で、しかも決して他の所
からは復活させることができないものでした。いくつかの有用な tips(付録 B, `ク
レジット'を見よ)と多大なる忍耐によって、私は 91 個のファイルを無傷で復活さ
せることができました。五つのファイルについてはどうにかその一部を復活させるこ
とができました。(いずれの場合も中に入っている絵の内容を見るには十分でした。)
たった一つだけ見ることができないものがありました。しかし、1024 バイト以上は
無くなっていないという自信はあります。(しかし、運の悪いことにそれはファイル
の最初の部分だったのです。もし JFIF ファイルフォーマットについて何も知らなかっ
たら、あがきまわって、ろくな結果は出なかったでしょう。)

後で、ファイルを復活率についての議論することにします。


1. どうしたらファイルを消さずに済むか
=====================================

Linux は MS-DOG ではないということは肝に銘じておいてください。 MS-DOG
(Windowze95 も含めて)では、ファイルを復活させることは、かなり簡単にできます。
「オペレーティングシステム」(この言葉を広い意味で使っていますが。)には、こ
のプロセスを自動化するユーティリティーさえついてきます。 Linux には当てはま
りません。

では、法則1(最重要命令です、もしやってくれるならね)は、

     *** バックアップを取ること ***

です。どんな事情があっても。私自身良くこんな事を言えたものだとは思うのですが。
お金がないのであれば仕方がありませんが、(学生であっても、一種の臨時収入があ
るでしょう?)まともな Linux のユーザーなら、バックアップデバイスを買いに行っ
て、きちんとしたバックアップスケジュールを計画し、それを守るべきです!。詳し
くは、 Frisch (1995) を見てください。

では、バックアップがない場合はどうするか?(あるいは、バックアップがある場合
でも:重要なデータに関する限りは、帯を締め、神経を引き締めておくのは、悪いこ
とではありませんから。)

重要なファイルについては、パーミッションを 440 (あるいはそれ以下)にしておき
ましょう。自分自身での書き込みを不許可にすることで、'rm' も消去の前に明白な
確認を必要とします。(しかし 'rm -r' でリカーシブにファイルを消すときには、
だいたい初めの一つか二つの確認をしてから、 rm を中止してもう一度 'rm -rf' と
やりますけどね。)

特別なファイルについては、不可視ディレクトリにそのファイルのハードリンクを作
っておくというのも良い方法です。前に何度も /etc/passwd を消した(つまり、シ
ステムが半壊してしまった)ことがあるシステム管理者がどのようにしているかを聞
いたことがあります。これに対する方法は、(root 権限で)次のようにしておくこと
です。

    # mkdir /.backup
    # ln /etc/passwd /.backup

このファイルを完全に消そうとしたら結構めんどうです。もし

    # rm /etc/passwd

としたら、

    # ln /.backup/passwd /etc

とすれば、もとに戻せます。もちろんこれでも、ファイルを上書きするような事態に
は助けにはなりませんから、いずれにしろバックアップを取ってください。

'rm' を 'rm -i' のシェルエイリアスにするか、それと同じ働きをする関数にするよ
うに主張する人も居るでしょう。(これで、ファイルを消すときに、いつも確認を取
るようになります。)個人的には、あるソフトが思ったとおりに動かないのには耐え
られないので、そういう風にはしていません。それに遅かれ早かれ、問題に直面する
ことになります。なぜならシングルユーザーモードだとか、他のシェルを使った時だ
とか、他のマシンを使ったときなどはいつもの 'rm' はそこには無いのですから。も
し確認をとるにしても、自分が(ディレクトリツリーの)何処にいるのかわすれたり、
ファイルを多く消しすぎることは十分考えられます。同様に、いろいろなスクリプト
だとかプログラムで 'rm' を置き換えることは、私の考えからいうと、とても危険な
のです。

もう少しましな方法としては、リサイクル可能な消去ができるパッケージを使うこと
です。これに関して詳しくは Peek, et al (1993) を見てください。


2. どのくらいファイルを復活させることができるのか?
===================================================

復旧率は場合によります。 Linux のように高級な、マルチタスク、マルチユーザー
のシステムにおいての問題は、いつ誰がディスクに書き込もうとしているかがわから
ないことです。ですからオペレーティングシステムがファイルを消すようにした後で
は、その消されたファイルが使用していたブロックは、新たなファイルのための格好
の的になるのです。(これは Linux の一般的な原則の一例です。ツールとか、カーネ
ルはユーザーが間抜けではないと仮定しているのです。)一般的に、一生懸命働かさ
れているマシンほど、ファイルの復旧可能性は低くなります。

また、ディスクがフラグメンテーションしているかどうかは、ファイルの復旧の難度
に大きく影響します。削除したファイルが、非常にフラグメンテーションしているパ
ーティションにあると、ファイルの全体を読み込むことは、ほとんど不可能でしょう。

もしあなたのマシンが、私のようにシングルユーザーのワークステーションであれば、
(私のなど、まだネットワークにさえつながれていませんけど。来年にはつながると
いいなあ)そして、ファイルを消したその瞬間に頻繁にディスクをアクセスする仕事
をしていなければ、先にあげたのと似たような復旧率であろうと思われます。私は 
94% 近くのファイルを無傷で復旧させることができました。(しかもファイルはバイ
ナリーファイルなんですよ!)もし 80% 以上復活することができれば、結構満足な
んじゃないかと思うのですが、如何ですか?


3.  では、どうやって、ファイルを復活させるのか?
================================================

原則的には、raw パーティションデバイスからデータを見つけ出して、それをオペレ
ーティングシステムに対して、もう一度見えるようにすることです。そのためには基
本的に2つの方法があります。一つは、現存のファイルシステムの削除されたファイ
ルの i ノードをいじって、 'deleted' のフラグを除いてしまい、データが魔法のよ
うにもとの場所に戻ってくることを期待するものです。もう一つの方法は、もっと安
全ですが時間がかかります。データがパーティションのどこにあるのかを見つけ出し
て、新らしいファイルに書き出す方法です。

以下 4 章から 6 章では、データを復旧する前にやるべきことを解説しています。
7 章から 10 章までは、実際にどのように復旧するのかを説明してあります。


4.  ファイルシステムのアンマウント
==================================

どんな方法を使うにせよ、消去したファイルの入っているファイルシステムをアンマ
ウントすることから始まります。マウントしたファイルシステム上では、どんな急用
も、絶対にやってはいけません。このステップは、ファイルを消してから*できる限
り早く*行わなければいけません。

もっとも簡単な方法は次の通りです。消去したファイルが /usr パーティションにあ
るのなら、

    # umount /usr

を実行してください。しかし、 /usr にあるいくつかのものを利用可能にしたいでしょ
う。ですから、読み込み専用で再マウントしてください。

    # mount -o ro,remount /usr

もし消去したファイルがルートパーティションにある場合には、 mount が /etc/mtab
に書き込まないようにオプションとして `-n' を与えなければなりません。

    # mount -n -o ro,remount /

こうやっておいても、他のプロセスがファイルシステムを使っている可能性は捨てき
れません。(このため umount できずに `Resource busy' というエラーを吐きます。)
このためにファイルやマウントポイントを使っているプログラムに対してシグナルを
送るプログラムが存在します。 `fuser' です。 /usr パーティションに対して試し
てみてください。

    # fuser -v -m /usr

これで、関係するプロセスのリストが出ます。もし皆重要なものでなければ、

    # fuser -k -v -m /usr

のようにしてプロセスに SIGKILL (プロセスを確実に殺すシグナル)を送ることが
できますし、あるいは、

    # fuser -k -TERM -v -m /usr

として、それぞれのプロセスに SIGTERM(プロセスを正常に終了させるシグナル)を
送ることもできます。


5.  i ノードを直接書き換える準備
================================

私のアドバイス? この方法は使わない方がいいですよ。こうした復旧のためにはそ
んなに低レベルでファイルシステムをいじり回すのは、賢い方法とは思えません。

また、他にも問題があって、それぞれのファイルの最初の 12 ブロックだけしか復旧
できる保証はありません。ですから、もしそれよりも長いファイルを復旧させるので
あれば、他の方法を使わなくてはなりません。(しかしセクション 11 を見ると、
"将来これがもっと簡単になるか?"ということについて追加情報が書いてあります。)

もしそれでもこの方法しか無いとお思いでしたら、私としては raw パーティション
を違うパーティションにディスクイメージとしてコピーして、それから、そのファイ
ルを loopback デバイスを使ってマウントした方が良いと思いますよ。具体的には次
のようにします。

    # cp /dev/hda5 /root/working
    # mount -t ext2 -o loop /root/working /mnt

しかしこのためには 'mount' の最新バージョンが必要になります。(そうで無くて
も、 2.6 以降の mount を使うべきですけど。なぜなら 2.6 以前のバージョンのも
のは、セキュリティーに関係するバグがあり、普通のユーザーに root 権限を許して
しまうからです。メジャーなディストリビューション、 Debian, RedHat, Slackware 
ではバージョン 2.6 にアップデートされていますけど。)

loopback デバイスを使っていれば、もしファイルシステムを完全に壊してしまって
も(実際、良くあることですし。)、もう一度 raw パーティションからコピーしな
おせばいいのですから。


6.  他の所にデータを書く準備
============================

どこかに復旧用のパーティションを確保しなければなりません。運が良ければ、シス
テムにはいくつかのパーティションがあると思います。多分ルート、 /usr、 /home
などです。これらの中からならどれを選んでも問題はありません。そのうちの一つに
新しいディレクトリを作ってください。

もし root パーティションしか無くて、すべてのものをそこに置いている場合には
(私もそうでした。やっと再パーティションニングするまでは。)、ことはちょっと
ばかり厄介です。多分、使用可能な MS-DOG や Windoze パーティションがあります
よね?あるいは ramdisk ドライバをカーネルに組み込んでいるか、あるいはモジュー
ルとして持ってますか? ramdisk を使用するには(カーネルが 1.3.48 よりも新し
いと仮定して)、次のようにします。

    # dd if=/dev/zero of=/dev/ram0 bs=1k count=2048
    # mke2fs -v -m 0 /dev/ram0 2048
    # mount -t ext2 /dev/ram0 /mnt

これで 2MB の RAM ディスクボリュームができて、 /mnt にマウントできます。

ここでちょっとした注意:もし、自動的にモジュールをロードしたり、アンロードす
るのに `kerneld' を使っている場合には、 RAM ディスクから不揮発性の記憶装置に
コピーするまでは ramdisk を unmount してはいけません。 もし unmount すると、 
`kerneld' はモジュールをアンロードできるものだと思ってしまいます。(しばらく
待ってからですが。)そして一度このようなことが起こると、メモリーは他のカーネ
ルの他の部分に使われてしまって、何時間も苦労して復旧させたデータを失ってしま
うことになります。

もし `superfloppy' のようなリムーバブルの装置を持っているのでしたら、復旧用
のパーティションの場所としては多分良い選択です。もしそれも無ければ、フロッピー
を使わなければいけないでしょう。

他に必要なものとしては、パーティション装置の真ん中から、必要なデータを読み出
すプログラムです。いざとなれば `dd' がこの仕事をしてくれます。しかし例えば、 
800 MB パーティションの 600 MB 目を読み出すような場合、 `dd' は最初の 600 MB 
を無視はしますが、それをどうしても読みにいってしまいます。これにかかる時間は
ばかにはなりません。私の解決方法は、パーティションの中間の読み出しをするプロ
グラムを書くことでした。 `fsgrab' という名前のプログラムです。以下に 
uuencode+gzip+tar 形式のファイルでソースを置いておきます。使い方、インストー
ル方法とコピーライトも入れてあります。次のようなコマンドを打つだけで手に入れ
ることができます。

    $ uudecode < Ext2fs-Undeletion-mini-HOWTO
    $ gzip -dc fsgrab.tar.gz | tar xf -

訳注:Ext2fs-Undeletion-mini-HOWTOのところは今読んでいるファイル名に
     置き換えてくださいね。

begin 644 fsgrab.tar.gz
M'XL(`$-JR#("`^Q;WW/;1I+VZT[='S'EETA5#"/+L;V)GRB)LGDK40I)Q='C
MD!B26(,`%P-(YG]_7W?/``.2<O:N*O=P=:K-RB(&,_V[O^YI+MVJ-/.?7OV5
M/_KGLP_OWNE76NL/[^7WFY]_YM_^YTSK]^?OS\_>OSM[=XZG9Q_>OGNEW[WZ
M7_BI765*K5\94Q;Y=]?9TKWZ/_>S%/U?WMT_CL:?_IHSWIR=O??Z/J+_G]^>
M?7@?]/_V_.T'/#U_<W[^2I_]O_[_\I^__8UT\&G\H#\-Q\/)X$;?/US<C"XU
M_AN.IT,E"_#S._A/BUR?]_1_UKG5;W[YY8U2^K+8[LITM:[TR>4I/OS[+SU^
MI*]+:_6T6%;/IK3ZNJCSQ%38H*='^:*O](L_[S^\T[?&.3UXLCU]:3;S,DU6
M^.?M0)^=OWF+`QZF`Z6'3[;<%:`D=7IKRTU:53;15:$7($F;/-%)ZJHRG=>5
MU5@[Q_$;>IA:IW2QU-4:;V;IPN;.ZJ18U!N;5SV-]7JQ-ODJS5<ZK6C[O*BT
MR;+BV29]!9&P3.Y+"]HR"R'HV=J&G9Q>%J7>%*[2+G!/_R76I:M<**S,5WSX
M;'9Z5]2E6D)42;&A)V[-ZT$\DP#FJK[6%SO0G5>E<:"OPEFL,)O;TF3ZOI[C
M:'7C&0&Y:5[9/)&C5K4I#?ZV?)3^WE'T3`6:?_P12S9$IZNQC`YMV,$1M)89
MA5A`H]/L'WV21.I4ES0=2#/;;0;AT^$L']:![5J*:BWE!Q=),&=N3+[3!=XI
M];8L$+DV^GE=T,YUM2Y*!REM8`=8J6HGZ@-))]-B8_UK+UEEA[E%`7.!^.8[
M%81]D\Y+4^[T"YREN:NL2?JG6C\6M5Z8G)G=:2&&1>\I=M!@4?3):KZL;:Z?
M(=BM-5])&BS50$F/'A%%I5W:LB1V(`&OP![9I-J6.!\<WF'[XY2Y`]N+=6HJ
ML@JU-D^BX<@Z(M\1ESF@3Y]XVRE7;`J*_0EF\(2C=;JDK?5SZM:GO>8H\+*P
MZ1-M4I<+VCJ!9DH6V,K"URH57H31XL_H55KC+;5CC7@=QJ=!XT*HI$URG=MG
MH3?(_:,84=CN:UX\-_LF!>WI:&?(V;%V9@6]6ME%):[#4<ZQ5G(;R;*T)*D%
M69&3[2&,>9HH&"N%)Q*FS=G5_2&R$Q%.)NV^RJ."M%*2XY;,H*SJJYF\TSD%
M+NTR4_'F"UM6!@QCQ18/TWF:I57JXQ#M+!)51S4:2[)'%'GQ;XHD79+YLBBN
M\<!^,YMMAD5^Q='M7+U8:Q-$#EFM+;F=PE]5RAQSS-!+BXWX'.1?O4J]_<$Z
M4FR50S@45UHIL%S)C339:E^\C-_=,V>\LF,'ZS6F%ID7GJK(\K#/`";1T.'6
M,`FLV01C0%:A&,2[BL'@7VFI@FK(A^TQ*X'=5VM=/4.GE=VZ7_7)FU/.2Y(J
MNU*'6:J3\U/(#W[NS23*3,_K%$(E&3E^F-D5W)PSGN.,[%->+]8P]OR)TQ"K
M,3Z/J1YD#A(B75A#&N/PB7CK6:%=R5G`D!@\>V,P>&]PB@5N0Q:NR7`!IO+$
M-:J0<)H7>+^D++3C(YF[3K*!(D;+@QS#Q*<<A_'YQM(I-G.2#+9`"'A$>.+9
M*A\M7&Q!(->K#,0\!^-@`PHYG4XLH)(T-UD/9PA+E&0@"*3V#>?2LDCJA9#!
M282T"^ND#1":,U(]:2':2_E\]`,6;.N*,XR8RS4]SG8]/B0.3T12M0:D0.K&
M64CW),L**82Y]\EQ2X\KRK.P.XJM'$&>BC3A\Q.*CJ5PC`06S($R(YS3B-";
MS$E,I'F2/J5)343I8LZ!1`YI\`P\/M<6MKE@;^,\M&ZWP6^D(0L4O>O[H`F;
M('.!FMEX6.(;DQ"8T8O,&D\A1.`9$O>;-Q@J$=/TIO6#AQL4Y?$QR;U99QB8
M]0,&VY+^&\_E_%2`0XF:M"<Y"CCHM>'+V[H2:UL(&E@6A/;ZZC_4GP)D/)T-
M)[=3/1A?Z<N[\=5H-KH;3_7UW43[LJJGKT;3V61T\4"/>.'MW=7H>G0YH`^(
M^+,^(Z=C4,F;(PL;'`B.>2[*KSXR$#*$VIPR)!K*O=O,>'LEHVC#SKK(*+DX
ML_/0=@,$"JFW<2-1=9-_1(8!)Q^'%WT1^^M[H>\UT+.%X'J*,4M#/J>%B`>B
MGN,>;/(ULS(WXLU\<MA-;2SRG+8ILQP]H3UH7Y":/D%CL"_>18AO&<[,\Z_B
MTRG3`LYQK*SU8O/FW-E9;XN2S8#!1$]Y`IH:@CB@^!Z;C`LAM\G-"<4.XI\U
MIC+X9FU6)+*3SXB,"`1+B+C7O$`',GA?9#6!=SJBJ,G6`6G]XUP%S>C7\>FO
M"7D.*91[S^`09Y($H(#=Q.G7R!VOX2@#A/<G`0B%ERL!JY?\HL,D@TD"GBU"
M%NOPYO!10BRCLKIR*;L\,BAV#Z9B*%HN55GG!Z+W03D@'9OT/&+CW1!'$0:*
M3?R*BL!ZD1/<7O*!I%O.`1Q&TXHSHCXP-!5./D$8M%N"7CE7)8A81-S<`I]S
MX`*?1R@^[:LO`G!T8V1E37";]G)T2L@[#9-)8243O.D+B#&[?Z=@#5C-;_.#
MBW$,J3<&UP2;TYP]9(,L4`.(P?D0YFV+?Q6)9ILNZJ)VF9R.F,.Q'+:+3[;D
MZ$@P8((Q@B<R7J5:3_.1QS.QR$RZ@51`=,C\'_57:[?D$F0!'MTI><V%C$7X
MA\KC3B24RH^8-W-G<YQ"N0R\-5LK6L,@LJT/(R#0%1T,@5D)@<V?HTQ60+N"
MV]K54%6C):ET&+QZ'(-0N]XY.$?F[5J<.91K<I(`O)W?Q7B<6&Q]A"&>&W@4
MX2]*NM]"91Y`,UO.>6LY'M_QCL)5>=Q@0L3TD4U)9,.*FO/B1LA],13W?"X5
M.XV!)H?V;B#T`5X?2253S]P;9>8%M7<.[!*F`<"]L5:,1+AP-LKCORIN'IG3
MM@A8F-I)!=%@QF6:2?I<0+8L6/!([NU-CO=P%%?9IT.-R?*6F",[A`B44+7E
M#4]6]86.^0$=;)LD@&;;2%X0CO<L7]HBIM,VSTC._)0!6%DU:9T_<Y+JB*^]
M$.@5RWOP>PR[BR4501U$A1AA_"F&I!#LF5(4>V-:)LTN9$`O(8&0^H7]Q6F`
M[HWH0Z+/85>,*X%J$^G-<'5`[:G24!I"G/',(]`BP$8UH8B2;)0?4I>64FJ(
MPN019'K\>K0A@\0T]P11CZE,D&E+BA9<&(*ZE()\24H!4"*#%GO*\Z)&=*$F
MH$_"[!2=B*>/1CS#&_@/7JY]3@C3HG[I!036V(?W`J&C>>&T;5AP=XT]/H+U
M8O%!VJPNWF'?87P:M5D6\A=MI[G8+?13:I_W8B+OTB*\D^&WA>5P]2LEV$[*
MKIS-EJ'G&'0`VG@+RG6<TAM+$.%+ER#OB+PG0:P3@0(WAPCA7W5:2@M&=MS;
MK'\*Y![Z)KQV(TT%[LGY;-+8*Y_9N@<7HRHE+(#G!F6@=M8W7EA`5$[R*P*&
M7G3-'N<EZCW,B0[CBAR[<2N7H%')"+'%';3867@?V1D=X#S>VT#&3U2'5>0)
ML0^*9@GQL(OVJ(_%O>J6SP*IK2&?76DO('&_P[B]HZGI7%?-"VK/Z)S91%+!
MVQQZN,:4$".E2>HZ247M)Q4.K#'@]$E+]@A%H7\K1"'5E8`T@-MVB-1Y`@("
M&$8-\8U:XE[UBE1;^F,"R*PY6T@[!!]P\2ELE79ER@3)@/6/E_0SI6EICLWP
M8B^Z)B!*N?]>-0'3RXF3$0&CJ/_'0-55*FX=89E4=R7=:``%,+'2","ZCQI:
M6G/AT![%Y8VRWVPIY6]HG$EOB%H8V5%A1P5440+.9=3-".64.PH%P/,HI](B
ME=N<#44ZLUJ1E,*VON81/D@JQS92^UB+`R1_^!TD<DI_&_U49#4U]9>H>EU5
ME"BL?$QO^1/LVT:A>1GB7T2=A$VV::I2CF:YM]^'ZOLL[%-/):0DTP!_SD\I
M1Q7S?U)/)?3`H;U%77&\(41V)/^J:?"X-TS#N684]1*(0C"@EIGW*6EI0`(M
M?AHLD).W!%=@OXTVZ+/,<JXKI:?,B7`#SP""^I&2.1$I`*HM0GK>YX/71DV%
M[R!!R35==EC!7GD+[%9L3)G"_NO0&&J;A)1T!(U]A`A[#2([Y,PT_L20NZ>?
M3);*=I!9ANA<<?]-^-I94_)%35M6,$#B@+#K>4#N$51.UUG2@,[E0H^!D;_A
M"A4"93];!JSM!1?;:X^SL,B>=]B7>)2C]Y73T0,#/TG`_YX.7I:_</(_T,'B
M)>M*<Q*!1(JH9F5\ZA,S*TAR_]X]U`LL$T;A[IG)0$LN\<S#&']M*^V!);</
M<T*B%"E1MAVT.T(;@9(>O=_0%V.M/W=>YK<!J*:Q.BK+(9=2VCMZ6L]#=IB+
M]`%="+ET+LB6;5"1CIC0PM>"HHY-DSEI$5W&^4YMMS*#//E&])J+AIAHZ<@U
MKB^G*SY=C@SW,0=TX7,<4E.ME+95"RJ[K'9<F1CGBD4:&F)P`4.&;Y=IGDJO
ME>HLOU[B<)ENY4:9$K8*^8N(2WV?C&$/=<BSS,3`H>4(7'Z&XI](Z(3ME-M:
MUK@-8+9WP$_L+GS%1UG#]^/H-H\O!YM63P-JX]=.J&R7=J'?&3*:<P6B2$^G
MK2=LS#\9`6Q@T8Q.3X1#HO@KS-AF`DT<A?%3SZ%"CBJE:'4[5P&Z<9.)`F^7
M?ZJ4(-4Z9]S"-#='*0_;C?=0;C1WI8<DOSQ`"]'N!+$B#Z#;&M\G8T,'?0J[
M\]%^((/1L?%7T6P-W*;VJ#:\I0FN(S03E7L;'%A?@-L,1GDS/*@9YSMU#%9V
MHB1=4A`^KE?K*+:G_L9<FIR;+8JF:*@DVF2O710)@VX-M/ZYQ0QD1=((DG8-
MZC]NH@M^C5%+!TLHL52R7OMM2XU<+J!\J@_A/((J=)M)#298Q;92C'&>&0T6
M+Q[_\ND4/^E>26R0[XI,36F@\LF,LDA*BNS<>QXA2S5^&`1,$)HOA9K@*CTK
M%D:X9F?U4H8(""WJ"3;W;V%R(2W;\9N&,'8=5A.5-Q2+`P&H!^FB"_];UIE$
MEBPU*!X9[KT3U87R+JXVR22WU5X-YE)J2H;+:38=/V[!P;9AGT`QFSC=8:ZH
MQ)>V;?<JU[?T$,)?4`SU@RJW?_<ALS=4\9I0E95\2;=.YVDEK?K,/#>W][Y0
M/.1']D%R*>AN>KZ3BS'N5W0`]E[S_L0W&%]LLI]*<X<N'!>-U<CYQC=U.SJN
M&,#2-35U',.8T7_G8D\H;LA7>T+<*W'\J,/[OMRC5.G&>H#R/:C_)QQWAAKV
M',@;/Y7(P1M#2%/A(MD_D4D1<>)N+S&ZX`]TP;LY%E5TG6U?N`P-(Q0^/*7(
M#+YSN:Q+OJ_J#)SX&JQMJO^@FV+3!U<?`-BN(8HU7W'U5=>3_(2*H"14MOC_
M!>FI]4!_I12%8^9CKR+[T->CI21V;J?`19N;`4H"J-K_62<K[N4)2(FJ4[ES
M5D"BE'%L6+3T^@SW!]2OT2=RV[Q)_6RAOZ^&N];6G?949(4,AEF.;`AD.R=^
M_H68$JJ`_!B1H%P.![>1^C3D:1KU@YM4'NDW1^SY2$^NV\27*5U0\Y/.;5+C
MR^_*R(6??Z+7XYY^X=&XHZD=F)=+-W4&-[5R6207&,@A*X\KVZBOXFN;:%K/
M0I?<?H]>\ZG_0(D$O8-AON![_MK_<#+)!.TVTS-%G0F0DQE1718[E`F['WFD
M('+N"">$4Q#\!/86/(93-!=L_HHE05I8T(@&M^V;OU!&,JH`'\(B1QXN+/S(
M)QD#J`KBG4-(!)ZE$17G.5XVIV!(-^HE):VF'<1*_@[Y@N&B2Y^#AA3^N;89
M(6DIAFF2+A>GM(SR)/7R%N2,BSHSB+1IN:@WCJ.V1+BYR=H0;N/MHTE4)4W)
M<)\2%D77$GN3JWZ`,A<34O&Q=(,ZZK3<MG7)$>Q(SPV:J7U^YK_$ZZ/I$]>.
M55"C'Z:Z\]TS;M>%03W?JY/&05KM_&V0XFZVK/S8/7QM?$5#W$44AEL^/TE#
M3*]*OV,8PVP+[(Z*!?3WFOZJ2LGT*9)(BM_*>$:P_BVWY$E@6M^R'FV!]>U(
MCEK17`?<6J*./Z8IQ9_I"K_D.TB:[CL@R28J6#N'+E^3\#2BC^=%+@UOQX&3
MYUH64<UF`);XI8^^B5IOF^M>'J+Z*2ER44""[)/P9"F/6FFW9ILA,,CIO=,L
M:&@-]+7!R!,IXR?-O(0/@SX32B!>%RECPMF>U\1FRB-Q1"B=0MU]'G!Z]D7B
M'&*P3^(`<WN8K22KNNJP[TA%Q-_[X7)MOT_QDY]ZW8M8J8O&)^CZ(`R'<F%4
M4M#RU2G92FO]\UU[LQ77Z1*C6SAR,$M$49%++]>AX[`,X(ANDD3Z#F0$4/?*
MTO+MFF_0.RQ&0R_(:W(7IR00-ZST9#335-U7.U\'D'9.SB!@@U)`M8*0T%$[
M?X!-*"7F<CFU,))=HU@,D%_`@^F*Q'%`CTB$G\,J0X/17S_.BV1WM)W\2Y\G
M85X<12=)A>F+TCZE?'LK*J>AYB?Y(H937O<OC*0+!B`42^Z$WV!O2KS%>[#S
MD&$BPZ<4W$&[VZ8ECZV'-I,CQ_5OR-<CB$+@3AI=P`N)A8EE'.)EX(B/:"8H
MY9H#AL@CD`RN_6:D*NJO4K^15`@=UV":XF)8D=>;N2W;^=!0&W,W9\G5^M[:
M@T)"0F4T4.<S[6L*WC2H588=7O?:*HY3=IC1:)OG40.U"ZC#D%BX(0Q$%668
M&N@<%13<CNF1.:@CYG#`>WNA(4+8'1/!WB79KIEA*0+.#Z]0;7J<FF/?R9#1
MI;-^`(]A!C7R#L8*!_,G/`LG\3>>0G7^_J[CP7N@6BR-[XC)Q6PW/R@_0T_P
MO:VD/31LLD!S'QF'N3^1_-YQ+_GK1_X*1[&QY&1.<3YHFHRNF7CV7].@),9R
MYQX&/`\FG[2TT,CXJC`9>S?[7OD4S$Y@`4).+>.\>+]M`O!'X1L^G>_-R$[%
MIFAJ=OKFC\PV)`@P/HTTKZPDGF2[]JM.XSO]93"9#,:S1];_F[Z^&%X.'J9#
M/?L\U/>3NT^3P:T>3<-4[)6^G@R'^NY:7WX>3#X->[1N,J05\5XT(QMM@%5W
M_/?PC]EP/-/WP\GM:#;#;A>/>G!_C\T'%S=#?3/X`FD._[@<WL_TE\_#L;JC
M[;^,0,]T-J`71F/]93*:C<:?>$,:Q)V,/GV>Z<]W-U?#"4_K_H33^45]/YC,
M1L.I`AV_CZZZ3+T>3$'V:_UE-/M\]S!KB"?F!N-'_8_1^*JGAR/>:/C'_60X
M!?\*>X]N0?$0#T?CRYN'*QX$OL`.X[L9Y`3.0.?LCD43UH;=00SV5[?#">0W
MG@TN1C<C'$F3P]>CV1A'\'SQ0"B_?+@9@(F'R?W==$C]&Q(A-H'`)Z/I/_1@
MJKQ@?WL8-!M!NMCC=C"^9$7M*9+8U8]W#Y0UP/?-%2U080$):JBOAM?#R]GH
M=Z@7*W',].%VZ.4]G;&`;F[T>'@)>@>31ST=3GX?79(<U&1X/QA!_#0C/9G0
M+G=CB2WG?5(>K&3X.]G`P_B&N)T,?WL`/T<L@?88?(*UD3`CO:LO(QQ.&MI7
M?H]?P8-6^8\PHSM].WB4P>Q';QX@LYG<[EH%C**USL'%'<G@`O2,F"P00@(A
M%5T-;@>?AM.>:HR`C_;#Y#T]O1]>CN@?>`[3@ZYO1"KPHM\>2(OXP&^B!U`G
ML49VZ%5&/DBV-@XV@K/W_?*D/7O/_L@N;NZF9&PX9#;03#%^7PQI]60XAKS8
MG0:7EP\3N!:MH#=`S?0!SC8:LU(4\<O>/)I<!7]B.>OKP>CF87)@8SCY#B*D
M+=G6&H4$(YN>]M@&].@:1UU^]MK3':]]U)^ABHLAE@VN?A]1Y)%S%'QA.O(R
MN?,[>#ER8./OFH(_7G]D@)]F_P=;&LY)O_U*35S*`P.N2:7/.F,4@`\?*>R.
M`7E\KG-DQSX_)DBO6;%%BO:8J)VFC+[EYF?U?,I<\;=`7*50B4BSK'9-%I("
MS]?=5#A02X$[TVLJ-`3ZR+0[9Z*T4MV,()FP^=H.C2=U6IS1%T*;*^/01`S?
MBPN-V:HR_N*I!4C-2&\17YD2BN&"R)DEL484-V]OPF*>\N.;)GKB;UKH?K#Y
MRJA\#T4F!P$3GNS.WUP!PCL/UOZKO6MO3MO8XO??[*?80G(M,8"QX\13,)XZ
MF"2^<4W&=MKF]F:(`&$8@\0@<$-3W\]^SVNE%<:OQ$WO=+23&0MI]YQ]G\?^
MSB:!'!.0!TD1C6A`[A12[\R9/VGRN5@IR(%6'XCS2D]"LH,(D$-X/FKHG(\>
M*,81I3MTDD`A=[`_J;S!#5@=L`8J&YY3,>D.6"!]#8+?8TB11[.`L.&[1&LY
MK'JQ`/I$`"4_*3Z[S)5L4RN(*#7:M3C",37&K`$G`6*,HIRMAGRNBC9.T-E1
M2G>,$7O7*TM),`6'DQLFA\F!&%%QTDAI]ZH.75[=`?9QK)AB`T3VS*27C>(%
MBPH&L\B0$3!JC(#'C<@(^5H<A2''A>3B'1%JT,`Z0=E&$LNR&CKW#J+ZQ*=9
MHN(@HVN,.1HJBN1%6RN2IJ-SW9[5"9@BA16YGK!`)*RCS*0O:VC3PDR_20VF
M\LNQ_<4[AO!C,`KBE-`K8,-"T'/&VRVA"3BR$A5D']%ITS"`^G,((.C[L,L-
M1^SJ3"$T4HC4HMD+32")A]TVC4&\H^$Y[YR*`(^0CW:BB*,H4MA66#"^(*A>
M!:!47[`V;Z;S<VC:BK6;7KE72G?!>I"8T;T7)ZU#T#8.W]N:<HUF@`R^GBU@
M.G^D:-7?ULK)(EA>_8F<H8W?'R$?[->ES8`H2.Q4["\R)EC-9M==LRM29JC*
M8#%!PX[.M1*4MZD?U2$N+;/51-JFHDE2=N.U\6:M/AVER.E'PH^.BB/T:B[0
MH8%G;'0"#'89>12L8*>559/8)?;,TVKO^&H<`LE2%VIP3HZ,L1_,H</\<50J
MX:Y-QG,T'_));ASC+U$CTE@"XV'X,67Q8?\(%U#,,9'N,?Q82H_]J:LY=GNJ
M(C391WRV$3""'0^7,7`N<<8E(3>Y)#+%Z!K#O@HP-#[B",W7@DSW$#<Q&8&(
M(-04E<%IRO$5[\-%V%L$OEG1*/\ZBY@1XX&2"M`*06U$-EQA#H0^6O-\#0_$
M"",(JS'B$-Y("S(%@2^1&SO1@-F_L#;ZM=<]]Z>TX>TP=`2#O6&6G"Y@I87!
M;E%O@%XV'8[H]A%44/A#$6_HB(8FINLGF$'BR;UFDXW]*G)2E/@T</[8XTO>
M#&5%OL:7#,3':E-[*_+P4'8:XIDT;C9TE43LE%$&#TX1F;C)LV2BXT:N"2@5
MA.:R.5J>]"C&H2@A;IQ&O"G\9F"A)HR[!\J;B9A9<;N%6GV[Q55GYC^R]/>X
M_XG_E+M_WOU/E6OO_WJ^M?W4W/^T5=FNH`]@:VL[N__I6Z3U@C9CKTLEDE*=
M48C2CO%Z@7;\3[--EU&:,>+P<!C,/RE=@']Z#WM.-T`9]O4.=6/WATG8"3^5
M85O?E4P?F<M:,1%S8HER<-@2TWDPQG,:$\<GAYX(Z2U<4:^^?TXW3FW;%1&N
M#V$;D7Y4^'K3*'$U`[4OM8RN6$5(;(5AM+KY][2,;*N(!OK>AM$*HP@)W=TN
MNL4F0F)ILX@;_M5VD643(;W[FD4WF$34D3=;1;JPKE1><,=Z9Q[`L/7*@UWK
M':R(=53+HZ77L]XP3+_J=X/9Z$HN4!.NO/.F9_A.45!L5].E(GUO!GWC4!@]
MA3OH0G\,32^7RZYNM[V9S*=V6SL.6W#:H9"\/BS*HMYT$?8X]4%G"URWEJ)=
MP$@11%"'7>U$P]_]-MACD$=AK-8T$';2Z^UA<!&RMM,FTZV-NFHMKBT&`=+1
MKJXCW^A\.(&G2LS1;D'/IQNJZCJW#H_K@YZWD8LSS@.#W0S,5@A50ZJ5S:UY
M+=4]:AYAW)&#SZ[Z3&94GUL/+9K!AC$M*G8TYMYAUJI^$NE?2QW]XK#5>'-R
M\._F!_C9U8W6NZ-3?(STR9N#M_"TW_SIH-'\\)\@9PB(M`0"I8'UNM2I)M3X
M$AD\S?U=L'#6MDV-J2'RWIN/.,X,VV33ZE:Y*GQ0-F?%6;9F,AN]WA(!NW14
MI=I?4QB')%VX8A<>5"64D];:P!]-P-B*L-.L7-PK'`Y-8RB5(KF1)AX/+10W
M@W#C7"K>_!DFYJ5"J(XBZ+!#4:?3LVY1)E4!?ER824`1QA-8)_U>C5Z$_7X;
M[P.<@]A"&ZX=^?YY+<X++ZAO.:9*UD)OV*.W16,3\6=FUYGW:TIBI]&WZ3C`
M#V8I"'!\<+AJ6*>BSG6JW6I4'>1<5W]7U\W62U<]BF!O`^F+Q>#79_4((0]Z
MK;-6Y<Z*(I",??H.5(#(DWFNJ/\9KPCH#\K7@2I"2Z1X]Y;B-"]6%XUN*8KS
M9W7)@2DIRW$YETR+FS-=\F`PWV'0TSLTO"X6E^T">_-7_OI!.A_S#R/8!A=X
MPQ=DE@TS]P06`^P`*"#)_A-0^@AGHX;LY!#"(D*HWP,&((MA9C&_HFZUC_=;
M1X?OW5K,JH_5JEALR%L1K,VXJ-04>3\9$R=^8YC(O`-.#DU(%W8IW"@+VAY6
M$]B'&E9=CZ@$<(ZG;5&?-)MOVB?-4ZMFDA]JI__XPY2&R29EEGL&:?9!8ON]
MZZM*"[M.*\U%$80[RHJ:PDJ`7+8LD;(F@UE'D(O^4%N@5%$G&4TSXKS2D/@W
M-X5RIYO"V\]-33$>C;HH#,Z&L#?$+?XFK[`W/X%[G#EAS^12O`U/EK@H_R[3
M`KV@5DI=V;<X"TI.DR-PK9G^W635U*.<B/L8^Z"++;@65B4FRY50-VD5IB9>
M&S1G!%L*?WC!IT/.A0?[ZG@F3);EK:91R=V^FQ/1*Z6I'A>>^>ZU,6K<B5_X
MGT!-AF6+3?H[V?\_>N<^J@I_P?W/>O/IUF9R__?6!MG_VQN9_?\M4IY\L70\
MBHYCG@XJK_*WF?68Y:&,^OS=;'ID^5`6??XA#?K\`]KS^57F_*J6?XTQGW\@
M6S[_@*9\?LF2QS8_J!V??U`S/G_KV>;;X^;+@U_JZ_-HNHX2<J1>'!SM'QS7
M'SO\R5WO#`.E8!B.ZJ6?\4"E]+/:;[YX]ZI>:FVJ1O.7T^.]NFJ\/-Q[=5)_
M_)D^7>K'G[$$_N4<EZK1J)]UNPJ#5:IF"2MQZX75V,&G'D&1QJ4&@Q,>B.IE
M\E$*Q-G#.'LHKY(O"D'N`2C4I>E8E_JZ\%]=*(?:*^,DZN(PFEK@+.7,!(P/
MT(2BL.TJZ@WJT9G\U&#ZEL8:_Y\(X`?]HDMG]$=8/W:X\URERF]?MX[>"ST=
M,^";R)F:*I^\>PD]W#RI9F<4=Y'_Q\V]_1^;?Q*/6^3_QK/-;9'_SYX^JSQ'
M?.GV9B63_]]N_._O^E>WJ`<J):[H$HXHON8<K3\$@`GXGW!6!+5@G!;==D%5
M46+14@@Z;=.F3(+UESJ'R?6@(/^(9-'(-87JB`$_TU$UD.`[;>!YZ"%^Y-BZ
M)TS5K<3F1\$<>=`S"AS<<9-?J$4I14X^)<6D:^_C[C-E2@.EOL37I52+4><J
MKOQ7^P?5%W@%U?U]@2KQ`'HI]Q]>-Y5<]+$T-*<$36%P#^=:8V5H:*(SP2*%
MT4WT2YQ*^W:P`<<MI^BN3$H9188FJ5SM;'%+:&8'XUG*4I:RE*4L92E+6<I2
0EK*4I?^S]#\$XBC-`'@``$H9
`
end


このプログラムは私にとっては、完全に働きはしますが、プログラムがどのように働
こうと私は責任を取らないことを警告しておきます。

このプログラムは、まったく、単に動くというためだけの継ぎ接ぎプログラムです。
無保証であることについて、詳しくは中にある `COPYING' (the GNU General Public
Licence) の `No Warranty' セクションをご覧下さい。


7.  消去されたiノードを見つける。
==============================

次のステップは、ファイルシステムの中で、どの i ノードが最近解放されたかを調
べることです。この仕事は `debugfs' で行うことができます。ファイルシステムの
入ったデバイス名を後につけて `debugfs' を立ちあげてください。

    # debugfs /dev/hda5

もし i ノードを直接書き換えたかったら、 `-w' オプションを加えて、ファイルシ
ステムへの書き込みを許可してください。

    # debugfs -w /dev/hda5

'debugfs' は、削除された i ノードを 'lsdel' コマンドで見つけ出します。ですか
らコマンドプロンプトで

    debugfs:  lsdel

のように入力すれば、随分と待ってディスク装置を磨き回してから、長ったらしいリ
ストがお好みのページャー($PAGERの値)にパイプ出力されます。きっとこのコピー
を何処かほかのところにセーブしたいと思うでしょう。もし 'less' があれば '-o'
とタイプして、出力ファイルの名前を入力してあげれば良いわけです。さもなければ、
なんらか他の方法で出力するようにアレンジしなければなりません。以下を試してみ
てください。

    debugfs:  quit
    # echo lsdel | debugfs /dev/hda5 > lsdel.out

さて、消去した時間、サイズ、タイプ、パーミッション番号、所有者によって、どの
i ノードがあなたの欲しいものなのかを探さなければなりません。幸運にも 5 分前
に消した、ばかでかいファイルだということで見つけることができるかも知れません。
もしそうでなければ、しらみつぶしにリストを調べなければなりません。

もし可能なら i ノードのリストを紙にプリントアウトした方が良いと思いますよ。
その方が楽ですから。


8.  i ノードの詳細を調べる
=======================

Debugfs では `stat' コマンドで、 i ノードについての詳細をプリントすることが
できます。復旧リストの中にある i ノードに対して `stat' コマンドを使ってみて
ください。例えば i ノード番号 148003 を調べようとしたら、次のようにしてみて
ください。

    debugfs:  stat <148003>
    inode: 148003   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
    User:   503   Group:   100   Size: 6065
    File ACL: 0    Directory ACL: 0
    Links: 0   Blockcount: 12
    Fragment:  Address: 0    Number: 0    Size: 0
    ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
    atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
    mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
    dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
    BLOCKS:
    594810 594811 594814 594815 594816 594817
    TOTAL: 6

もし沢山のファイルを復旧しなければいけない場合には、この作業を自動化したいと
お思いでしょう。その為には 'lsdel' の i ノードリスト中の復旧させたい i ノー
ドのリストが 'list' にあるとすると、以下のコマンドを実行してください。

    # cut -c1-6 list | grep "[0-9]" | tr -d " " > inodes

これで、リストの中から一行につき一つのの番号を抜き出して 'inodes' にセーブす
ることができます。この方が後々の処理に便利ですから。それから、

    # sed 's/^.*$/stat <\0>/' inodes | debugfs /dev/hda5 > stats

とすると、 'stats' というファイルにに 'stat' コマンドの結果が全部入ります。


9.  データブロックの復旧
==========================

この部分は、非常に易しかったり、あるいはまったく逆かも知れません。復旧させよ
うとしているファイルの大きさが 12 ブロック以内であれば、データの入っている全
ブロック番号がその i ノード内に収められています。つまりその i ノードに関する
'stat' の出力から、全ブロック番号を読み取ることができるわけです。 'fsgrab' 
コマンドを使って、データを出力するのはきわめて単純な仕事です。先ほどの例をつ
かって、もう一度ここに示すと

    debugfs:  stat <148003>
    Inode: 148003   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
    User:   503   Group:   100   Size: 6065
    File ACL: 0    Directory ACL: 0
    Links: 0   Blockcount: 12
    Fragment:  Address: 0    Number: 0    Size: 0
    ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
    atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
    mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
    dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
    BLOCKS:
    594810 594811 594814 594815 594816 594817
    TOTAL: 6

このファイルは 6 ブロックでできています。正しい順番で新しいファイルに出力す
るためには、名前を 'recovered.001' として、

    # fsgrab -c 2 -s 594810 /dev/hda5 > recovered.001
    # fsgrab -c 4 -s 594817 /dev/hda5 >> recovered.001

のようにすることです。 recovered.001 の終わりの部分には多少ゴミが混じるかも
知れませんが、まあ、それほど重要ではないでしょう。

もちろん、何個かのブロックが既に上書きされてしまっているかもしれません。そん
な時は、運に見放されたとしか言いようがありませんね。そのブロックはもう永遠に
戻ってきません。(もっと早く unmount していたら良かったのに!)

問題はファイルが 12 ブロックよりも大きな場合です。ここでは Unix ファイルシス
テムの構造については、あまり説明しません。ファイルのデータは'ブロック'と呼ば
れる単位に保存されています。これらのブロックは順に番号がつけられています。ファ
イルはまた、'i ノード'というものも持っていて、そこに owner とか、 permission 
とか、 type などの情報が保存されています。ブロックと同じように i ノードも順
に番号が振られていますが、これはまったく別の並びです。ディレクトリエントリは、
ファイルの名前と i ノードの番号からなっています。

パーミッション情報などの情報を保持している様に、 i ノードはファイルのデータ
の入っている位置も保持しています。ファイルの先頭の 12 ブロックについては、そ
の入っている位置を示す番号はその i ノード自身に含まれています。これらは 
direct ブロック(直接ブロック)です。そして i ノードは 'indirect block(間接
ブロック)' (ここには追加の直接ブロックの入っている場所を示す番号が記録され
ています。)の番号も保持しています。また i ノードは二重間接ブロック(これは、
間接ブロックの入っている位置を示す番号が記録されています。)の番号を保持して
いることもありますし、三重間接ブロック(ここには、二重間接ブロックの入ってい
る場所を示す番号が記録されています。)の番号を保持していることもあります。

もう一度読んでみてください。複雑ですよね、でも、重要でもあるのです。

現在のカーネルでは( 2.0.27 まではそうです。)残念なことにファイルを削除した
ときに、間接ブロックの部分をゼロにしてしまうようになっています。ですから 12 
ブロックよりもファイルが長い場合には、必要とする全ブロックの番号を見つけ出す
ことができる保証さえも無いのです。

今までのところ私がたどり着いた唯一の方法は、ファイルがフラグメンテーションし
ていないと仮定することです。フラグメンテーションしていたら大変です。ファイル
が間接ブロックを使っていて、フラグメンテーションしていない場合の配置は以下の
ようになっています。

    #Blocks   内容
    12        データ (直接ブロック)
    1         間接ブロック
    256       データ (間接ブロック内のブロック)
    1         二重間接ブロック
   [1         二重間接ブロックによる間接ブロック
    256       データ
   ] (256 回繰り返し -- 二重間接ブロック内の間接ブロック一つずつに付き一つ)
    1         三重間接ブロック
  [[1         二重間接ブロック
    256       データ
   ] (256 回繰り返し -- 三重間接ブロックによって指定された
                        二重間接ブロック内の間接ブロック一つずつに付き1つ)
  ]  (256 回繰り返し -- 三重間接ブロックによって指定された
                        二重間接ブロック内の間接ブロック一つずつに付き1つ)

わかりやすいと良いのですけれど。もし、ファイルが 268 ブロック以下であれば、
かなり復旧の見込みがあります。 12 ブロックのデータブロックがあり(その番号は 
i ノード自身の中に書いてあります)、その後に間接ブロックがあり、(その内容は
ゼロにされています)その後にもう 256 ブロックのデータブロックがあります。も
しファイルがそれ以上の長さである場合には、一つ二重間接ブロックを足してくださ
い。その後 256 データブロック増える毎に、間接ブロックを一つと、データブロッ
クを 256 個加えてください。もしそれよりもファイルが大きな場合には、だいたい
ファイルがフラグメンテーションしていると思うのですけれど、しかし同じ様な事を
さらに大きなファイルに適応する方針は明らかだと思います。

ここではブロックサイズとして標準的な値である 1024 バイトを仮定していることに
注意してください。もしブロックが大きければ、いくつかの値が変わります。とくに
各ブロックは 4 バイトなので、各間接ブロックに入っているブロック番号の数はブ
ロックサイズ÷4 になります。ですから 256 という数字が表に現れたら、それをブ
ロックサイズ÷4 に読み替えてください。


10. i ノードを直接操作する
=============================

この方法は、表面的にはより易しい方法です。しかし先にも述べたように、 12 ブロッ
クよりも長いファイルには使えません。

復活させようとする i ノードそれぞれについて、 usage countを 1 に設定し、 
deletion time を 0 に設定する必要があります。これは `debugfs' の `mi'
(modify inode) コマンドで実行することができます。上記の i ノード 148003 を書
き変えている時の出力例を示します。

    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]

つまり削除の時刻を 0 にして、リンクカウントを 1 にし、他のフィールドについて
はリターンを押しただけ、ということです。ここからわかる様に、もし沢山のファイル
を復旧させなければいけないとしたら結構厄介ですが、しかしなんとかやってやれな
いことは無いでしょう。もっと格好よくやりたければ 'Recycle Bin'のあるグラフィ
カルな 'operating system'でも使うんですかね。

[ところで 'mi' の出力は、 i ノードの中で 'creation time' フィールドについて
も出力していますが、これは嘘です!あるいはせいぜい言っても誤解の元です。実際
には Unix ファイルシステム上では、ファイルがいつ生成されたかはわからないので
す。 `struct stat' のメンバーである `st_ctime' は、 i ノードが変わった時刻を
示しています。つまり最後に i ノードのどこかが変わった時刻を示しているのです。
さて、今日のレッスンはおしまい。]

私が使っているのよりも新しいバージョンの debugfs には先に示したようなフィー
ルドのうちいくつかは無くなっているかも知れません。(特に `Reserved1' と 
fragment フィールド(のうちいくつか)は)

一旦 i ノードを変えたら、 'debugfs' を抜けて、次のようにしてください。

    # e2fsck -f /dev/hda5

これで様々な役に立つ情報が表示され、どの障害を治すべきかについての質問がされ
るでしょう。 'summary information' に関する質問と、あなた自身が変えた i ノー
ドについての質問には全部 'yes' と答えてください。他の部分についてはあなたに
お任せしますが、たいていの場合は 'yes' と答えておいて構わないでしょう。 
'e2fsck' が終わったら、ファイルシステムをもう一度マウントしてください。消去
されたファイルは '/lost+found' ディレクトリに入っています。(ですからそのパー
ティションを /usr にマウントした場合には、 /usr/lost+found を見に行ってくだ
さい。)そうしたファイルは i ノードの番号にしたがって名前がつけられています。
やらなければいけないことは、内容からファイルの名前を割り出して、ファイルシス
テムツリーの中で適切な場所に戻すことです。

実際には 'e2fsck' を使えば、 /lost+found にしか復旧したファイルを置けないわ
けではありません。 'debugfs' を使って、復旧しようとする i ノードに対してファ
イルシステム内にリンクを張ることができます。 i ノードを変えた後に 'debugfs' 
の 'link' コマンドを使って、次のようにします。

    debugfs:  link <148003> foo.txt

こうすると 'debugfs' にとってのカレントディレクトリに 'foo.txt' というファイ
ルが作られます。それでもなお 'e2fsck' を実行して、 summary information とブ
ロックカウントやその他もろもろを直さなければいけませんけど。


11. 将来的にこれがもっと簡単になるか?
===================================

はい。実際のところ、もう存在はしています。私の聞いたところによると、最新の開
発版 2.1.x においては間接ブロックをゼロにしないそうです。 1996 年 12 月の初
めにおいては(私が一番最近に linux-kernel list をおってみたときですが)、も
う一つ 2.0.x 製品版カーネルを作って、そこではファイル削除のときに間接ブロッ
クを触らずにおこうとしようという話もありました。いったん Linus と他のカーネ
ルハッカー達がこの限界を克服したら、手で i ノードをいじらなければいけないと
いう不満の大部分は解消されるでしょう。


12. このプロセスを自動化する道具はあるか?
=================================================

なんと、あるのです。残念なことに、その道具も先ほどのマニュアルで i ノードを
操作するときと同じ問題に直面しており、間接ブロックは復旧させることができない
のです。しかし、その問題も近い将来解決される様子なので、こうしたプログラムが
どうなっているか注意しているのは価値あることだと思われます。

ネット上で誰かが、 Scott D. Heavner の `lde' について述べていました。正直な
ところ、私はこれをファイル復旧の自動化の道具として使うことはお勧めできません。
どちらかというと、フルスクリーン版の `debugfs' と言ったところでしょうか。し
かし特定のタイプだとか、特定の中身のファイルを探すことができると言った特徴も
持っています。また xia (だれか使っている人います?)と minix ファイルシステ
ムに対しても働きますから、今日ではこれが大きなセールスポイントだと私は思うの
ですが。
URL:
    ftp://sunsite.unc.edu/pub/Linux/system/Filesystems/lde-2.2.tar.gz

(もっと新しいバージョンのものがある可能性は十分にありますけど。-- 私は 14
か月も前の CD-ROM アーカイブで見つけたので。)

GNU Midnight Commander 'mc' は*本当*に実用になるもののように思えます。これは、
フルスクリーンのファイルマネージメントツールで、 'NC' と呼ばれる MS-DOG 上の
フルスクリーンファイルマネージメントツールに基づいています。 'mc' は Linux 
コンソール上や xterm の中でのマウス操作をサポートしており、 tar ファイルの中
で仮想的なファイルシステムを構成して、 cd (訳注:change directory)すること
などができるようになっています。その仮想ファイルシステムの一つに ext2
undeletion の機能があります。とても使いやすいようなのですが、残念ながら私は
自分自身ではこのプログラムを一度も使ったことがないのです。--私は、古き良き時
代のシェルコマンドの方が好きなのです。当然ですが、このプログラムをコンパイル
する時には `--with-ext2undel' をつけて configure を実行しなければいけません。
またその時には `e2fsprogs' に付いてくる開発環境用ライブラリとインクルードファ
イルが必要になります。一度プログラムができてしまえば、 `cd undel:/dev/hda5' 
と命令して、 `directory listing' で消去されたファイルのリストが見られると聞
いています。

最新の開発途中でないバージョンは多分 3.2.11 です。カーネルと同様、開発途中の
バージョンはハッカーでない人にはお勧め*できません*。以下のURLのうちのどれ
かから入手可能です。

    ftp://sunsite.unc.edu/pub/Linux/utils/file/managers/
        (may be an older version)
    ftp://ftp.nuclecu.unam.mx/linux/local/
    ftp://ftp.nuclecu.unam.mx/linux/local/devel/
        (unsupported, developmental, alpha versions)
    ftp://ftp.cvut.cz/pub/mc/
        (European mirror of public and alpha releases)

(訳注:最近の 3.5.x でも undel に関しては大きなバグがあったとのことですので、
できるだけ ftp://ftp.nuclecu.unam.mx/linux/local/devel/ から最新のを持ってき
たほうがいいではないかとおもわれます。)

また以下の website も参照してみて下さい。

    http://stekt.oulu.fi/~jtklehto/mc/

私の印象では 'mc' の開発者たちは、次の公式リリースに関してとても興奮している
ようです。このバージョンでは多分、カーネルの側で間接ブロックがゼロになってし
まわないように考えた結果も反映されることになりそうです。


A.  Colophon((本の背や表題紙につける)出版社マーク)
==================================================

私は時間の許す限りと、興味深いことがある限り、この文書を定期的に改訂していこ
うと思っています。つまり、私としては読者の方々からの意見をお聞きしたいという
ことです。もっとわかりやすく書けないかって?もう少し簡単にできないかって?自
動化する新しいツールは何か無いかって?誰がJFKを殺したかって?

なんでも構いません。もしこの文書に関してとか、そのほかの事に関して何か意見が
ありましたら、私 <aaronc@pobox.com> に一言お伝えください。(訳注:日本語訳に間
違いやわかりにくい点などありましたら kikkawa@m.u-tokyo.ac.jp までお伝えくだ
さい。)


B.  謝辞
===========

    "If I have seen farther than others, it is because I was standing
    on the shoulders of giants."
                    -- アイザック ニュートン
  (もしかりに私が他の人よりも秀でていたとしても、それは
         私が巨人の肩に立っていたというだけの事である。)

この mini-Howto の大部分は comp.os.linux.misc に Robin Glover
<swrglovr@met.rdg.ac.uk> さんが投稿したものから得ています。寛大にもそのアイ
デアをこの mini-Howto に書き直すことを許可してくださった Robin さんにお礼を
申し上げます。


C.  文献
================

Frisch, ョleen (1995), `Essential System Administration', second edition,
    O'Reilly and Associates, Inc., ISBN: 1-56592-127-5.

Glover, Robin (31 Jan 1996), `HOW-TO : undelete linux files
    (ext2fs/debugfs)', comp.os.linux.misc Usenet posting.

Peek, Jerry, Tim O'Reilly, Mike Loukides et al (1993), `Unix Power Tools',
    O'Reilly and Associates, Inc./Random House, Inc., ISBN: 0-679-79073-X.


D.  合法性
==========

MS-DOG と Windozeはトレードマークではありません。この名前に似た商用の製品が
あるかもしれませんけど、それはまったくの偶然です。

Unix は商標ではありません。商標でなくなってからすでに相当の時間が経っ
 ています。さあ、目を覚まして花の香りを味わって下さい!

'Linux' という名前のトレードマークとしての現状については、弁護士によって協議
されているところで、これは某 Walter R. Della Croce が、この単語に対して明ら
かに無効なトレードマーク登録を行った為です。しかし、私はこの名前をネット市民
の公共財産として以外の名前として存在を認めることは断固として認められません。
もし Linus が Linux をトレードマークとしたいというのであれば、自分自身でそ
うしていたでしょう。(訳注:この問題はどうやら解決したようです。詳しくは、
http://www.iplawyers.com/text/linux.htm をご覧下さい。)

このドキュメントの著作権は Aaron Crane <aaronc@pobox.com>(1997 年)にありま
す。そのままの形で、著作権表示などを含んであれば自由に流通してくださって構い
ませんが、著者か Linux ドキュメンテーションプロジェクトのコーディネーターの
許可無しに改変することはできません。一部だけの利用は、批評の為か引用のために
一言一句そのままにコピーするのであれば認められます。このような場合には、そ
れぞれの章は適当な引用とともに使ってください。ただし、著作権表示は必要ありま
せん。

著者はこのドキュメントのコピーを販売する者に対しては、そのドキュメントがコン
ピュータで読むことのできるメディアの形であろうが、紙の形であろうが、自発的
に著者か、 Linux HOWTO コーディネーターに知らせてくれるようお願いしますが、
必ずしも要求はしません。

(訳注:原文もそのまま載せておきます。)
This document is Copyright ゥ 1997 Aaron Crane <aaronc@pobox.com>.  It may
be freely redistributed in its entirety, including the whole of this
copyright notice, but may not changed without permission from the author or
from the Linux Documentation Project Co-ordinator.  Dispensation is granted
for copying small verbatim portions for the purposes of reviews or for
quoting: in these circumstances, sections may be reproduced in the presence
of an appropriate citation but without this copyright notice.

The author requests but does not require that parties intending to sell
copies of this document, whether on computer-readable media or on paper,
inform him or the Linux HOWTO Co-ordinator of their intentions.

Linux HOWTO のコーディネーターは Greg Hankins  <gregh@sunsite.unc.edu> です。

訳注:また、このFAQの和訳の作成にあたり、中野さん@成蹊大、菊谷 誠さんの
      協力を得ました。

次のページ 前のページ 目次へ