web-dev-qa-db-ja.com

削除されたファイルの再リンク

不要なファイルを削除してしまうこともあり、長時間実行されているプロセスではファイルが開いたままであり、/proc/<pid>/fd/Nをキャッチしてデータを回復するだけでは不十分です。素晴らしいのは、lnにいくつかの魔法のオプションを実行して削除を「取り消す」ことができれば、iノード番号(lsofで回復)に再リンクできるようにすることです。

これを行うためのLinuxツールは見つかりませんでした。

あなたは何を手に入れましたか、serverfault?

EDIT1:/proc/<pid>/fd/Nからファイルをカットするのに十分な理由は、まだファイルを開いているプロセスがまだファイルに書き込んでいるためです。削除すると、ファイルシステム名前空間からiノードへの参照が削除されます。私が欲しいのは、参照を再作成する方法です。

EDIT2: 'debugfs ln'は機能しますが、生のファイルシステムデータをフロッブするため、リスクが高すぎます。回復されたファイルもまた、狂ったように矛盾しています。リンク数がゼロで、リンクを追加できません。 /proc/<pid>/fd/Nを使用してfsを破損することなくデータにアクセスできるので、私はこの方法のほうが嫌です。

34
mbac32768

素晴らしいのは、lnにいくつかの魔法のオプションを実行して削除を「取り消す」ことができれば、iノード番号(lsofで回復)に再リンクできるようにすることです。

この素晴らしさは、ln-L|--logicalを最初に逆参照する/proc/<pid>/fd/<handle>オプションを使用して、 v8.0 (GNU/coreutils)でlnに導入されました。だからシンプル

ln -L /proc/<pid>/fd/<handle> /path/to/deleted/file

削除されたファイルを再リンクするには十分です。

17
tnimeu

すでに多くのことを理解されているようですので、詳細は省きます。 iノードを見つける方法はいくつかあり、通常はSTDOUTをcatしてリダイレクトできます。 debugfs を使用できます。次の中でこのコマンドを実行します。

ln <$INODE> FILENAME

ファイルシステムのバックアップがあることを確認してください。おそらく後でfsckを実行する必要があります。まだ書き込み中のiノードを使用してこれを正常にテストしましたが、逆参照されたiノードへの新しいハードリンクを作成するように機能します。

ファイルがext3で開いていないファイルとリンクされていない場合、データは失われます。これがどれほど一貫して本当であるかはわかりませんが、私のデータ回復の経験のほとんどはext2での経験です。 ext3 FAQから:

Q:ext3パーティションから削除されたファイルを復元(復元)するにはどうすればよいですか?実際にはできません!これは、開発者の1人であるAndreas Dilger氏が次のように語っています。

Ext3がクラッシュ後にリンク解除を安全に再開できるようにするために、ext3は実際にはiノードのブロックポインターをゼロにしますが、ext2はブロックビットマップでこれらのブロックを未使用としてマークし、iノードを「削除済み」としてマークしてブロックを残しますポインタのみ。

あなたの唯一の望みは、削除されたファイルの一部を "grep"し、最善を尽くすことです。

この質問には関連情報もあります:

Linuxサーバーで大きなファイルを空白のファイルで上書きしました。既存のファイルを復元できますか?

13
Warner

あなたが見たようなdebugfsの方法は実際には機能せず、再起動後にせいぜいファイルが(ジャーナルにより)自動的に削除され、最悪の場合、ファイルシステムをゴミ箱にして「死の再起動サイクル」を引き起こす可能性があります。正しい解決策(TM)は、VFSレベルで削除の取り消しを実行することです(これには、事実上すべての現在のLinuxファイルシステムを操作するという追加の利点もあります)。システムコールウェイ(flink)はLKMLに現れるたびに撃墜されたので、最善の方法はモジュール+ ioctlを使用することです。

このアプローチを実装し、かなり小さくてクリーンなコードを持つプロジェクトは、fdlink( https://github.com/pkt/fdlink.git ubuntu maverickのカーネルでテストされたバージョンの場合)です。これを使用すると、モジュール(Sudo insmod flink_dev.ko)を挿入した後、「./ flinkapp/proc // fd/X/my/link/path」を実行するだけで、望みどおりの結果が得られます。

また、動作するvfs-undelete.sourceforge.netのフォワードポーティングバージョンを使用することもできます(自動的に元の名前に再リンクすることもできます)が、fdlinkのコードはよりシンプルで、同じように動作するため、私の好みです。

8
pktoss

今日も同じ問題に遭遇しました。私が思いつくことができる最高のものは走ることです

% tail -n +0 -f /proc/<pid>/fd/<fd> /path/to/deleted_file

プロセスが終了するまでtmux/screenセッションで。

3
nickray

私はあなたが望むことを正確に行う方法を知りませんが、私がすることは次のとおりです:

  • ファイルを開くRO別のプロセスから
  • 元のプロセスが終了するのを待ちます
  • 開いているFDからファイルにデータをコピーする

理想的ではありませんが、可能です。もう1つのオプションは、(linkコマンドを使用して)debugfsをいじってみることですが、実動マシンではそれはちょっと怖いです!

3
Bill Weiss

Sleuthkit icatを使用します。

Sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file
1
Isaac

興味深い質問です。面接官は就職の面接で同じ質問をしました。私が彼に言ったのは、これを行う簡単な方法はなく、一般に時間と労力を費やすだけの価値はないということです。私は彼に、この問題の解決策は何だと思っているのか尋ねました...

  1. ファイルが削除されていても表示されるので、lsofを使用して、プロセスのディスク上のiノード番号を見つけます。重要なのは、ファイルがまだ開いていることです。
  2. ファイルシステムデバッガーを介して、これに基づいてファイルシステムから情報を抽出します。
1
mdpc

ツールを威嚇することなく、私のために働いた迅速な解決策:

1)/ procを直接調べて、process + fdを見つけます。

ls -al /proc/*/fd/* 2>/dev/null | grep {filename}

2)次に、@ nickrayと同様の手法で、pvがスローされます。

tail -c +0 -f /proc/{procnum}/fd/{fdnum} | pv -s {expectedsize} > {recovery_filename}

完了時にCtrl-Cが必要になる場合があります(ls /proc/{procnum}/fd/{fdnum}はファイルが存在しないことを通知します))。ただし、バイト単位で正確なサイズがわかっている場合は、pv -Sを使用してファイルを終了することができます。カウントに達しました。

0
xenoid