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


33

ときどき人々はすべきではないファイルを削除しますが、長時間実行されるプロセスではファイルが開いたままになります/proc/<pid>/fd/N。恐ろしいことに、lnにマジックオプションを実行して削除を「元に戻す」ことができれば、inode番号(lsofで復元)に再リンクできます。

これを行うためのLinuxツールは、少なくとも大まかなグーグルでは見つかりません。

何がありますか、serverfault?

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

EDIT2:「debugfs ln」は機能しますが、生のファイルシステムデータをフロップするため、リスクが高すぎます。復元されたファイルも一貫性がありません。リンクカウントがゼロであり、リンクを追加できません。/proc/<pid>/fd/Nfsを破損せずにデータにアクセスするためだけに使用できるので、この方法はさらに悪くなります。

回答:


14

lnにマジックオプションを実行して削除を「元に戻す」ことができれば、iノード番号(lsofを使用して回復)に再リンクできます。

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

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

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


7
これは機能しません。ファイルが削除されると失敗します。
Random832

1
いいえ、できません。私は定期的にこれを使用して、削除されたがまだ開いているファイルを復元します。ただし、新しいファイルが削除される直前のファイルシステム同じファイルシステム/path/to/deleted/file上にあることを確認する必要があります。そうでない場合、実際に失敗します。(で古いパスを取得できます)ls -l /proc/<pid>/fd/<handle>
tnimeu

2
この種の機能(この質問と回答を参照)は、セキュリティリスクとして特に拒否されました[特権プロセスを中心とした仮想セキュリティスキームに対して、所有しているがそれ以外の方法ではアクセスできないファイルへの読み取り専用ファイルハンドルをプロセスに与える]; 私はそれを試してみました(ただし、関連するシステムコールを直接使用する小さなCプログラムを使用)が、うまくいきませんでした。
Random832

7
もちろん、ソリューションを投稿する前にこれをテストしましたが、その時点で実際に機能していました。私が気付いていなかったのは、それtmpfsがファイルシステム上でのみ動作し、例えばでは動作しなかったことですext3。さらに、この機能は完全に、2.6.39で無効に見てしまったコミット。したがって、このソリューションはカーネル2.6.39以降では動作しなくなり、以前のバージョンではファイルシステムに依存します。
tnimeu

7
@tnimeu ln -Lは私には機能しません。削除されたファイルがあり、元のパスに再リンクしようとしました。ln私に与えますln: failed to create hard link /my/path/file.pdf => /proc/19674/fd/16: No such file or directory。しかし、私は例えば成功することができますcat /proc/19674/fd/16
ユージンベレソフスキー

13

あなたはすでに多くのことを理解しているように聞こえるので、私は余分な詳細には触れません。inodeを見つける方法はいくつかあり、通常はcatしてSTDOUTをリダイレクトできます。を使用できますdebugfs。次の範囲内でこのコマンドを実行します。

ln <$INODE> FILENAME

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

ファイルがext3の開いていないファイルとリンク解除されている場合、データは失われます。これがどれほど一貫して真実かはわかりませんが、データリカバリの経験のほとんどはext2を使用したものです。ext3 FAQから:

Q:ext3パーティションから削除されたファイルを復元(削除の取り消し)するにはどうすればよいですか?実際、できません!これは、開発者の一人であるアンドレアス・ディルガーが言ったことです。

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

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

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

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


コメントは、うまいことではないので削除したい。
mdpc

1
削除されたがまだ開いているファイルの場合、iノード内のポインターがゼロになるとは思わない。また、debugfsで「ln」を使用する代わりに、「undel」を使用して、iノードの参照カウントが正しく更新されるようにします。
マークワーグナー

私はそのように暗示するつもりはありませんでした。そうではありません。パフォーマンスをテストしました。言語を明確にしました。
ワーナー

賢いが、私のファイルシステムを破壊する。:)
mbac32768

これは、説明するシナリオの唯一のソリューションです。rwがマウントされ、アクティブに書き込まれている低レベルでファイルシステムを操作すると、ほとんどすべてのシナリオで破損が発生する可能性があります。
ワーナー

8

あなたが見たdebugfsの方法は実際には機能せず、せいぜい再起動後にファイルが(ジャーナルのために)自動的に削除されます。適切なソリューション(TM)は、VFSレベルで削除取り消しを実行することです(これには、現在のすべてのLinuxファイルシステムで作業するという追加の利点もあります)。システムコールの方法(flink)はLKMLに登場するたびに撃downされているため、最良の方法はモジュール+ ioctlを使用することです。

このアプローチを実装し、適度に小さくクリーンなコードを持つプロジェクトはfdlink(ubuntu maverickのカーネルでテストされたバージョンのhttps://github.com/pkt/fdlink.git)です。これを使用すると、モジュール(sudo insmod flink_dev.ko)を挿入した後、「./ flinkapp / proc // fd / X / my / link / path」を実行するだけで、必要な処理を実行できます。

また、機能するvfs-undelete.sourceforge.netの転送ポートバージョンを使用することもできます(また、元の名前に自動的に再リンクすることもできます)が、fdlinkのコードはよりシンプルで、同様に機能するため、私の好みです。


3

あなたが望むことを正確に行う方法はわかりませんが、私がすることは:

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

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


debugfs linkコマンドは、このユースケースをまったくサポートしていません。
mbac32768

tldp.org/HOWTO/Ext2fs-Undeletion-11.htmlは、そうすることを提案しています。試したことはありませんが、それは理にかなっているようです。
ビルヴァイス

link私のテストでは動作しませんでしたが、動作しましlnた。
ワーナー

3

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

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

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


2
受け入れられた答えのように、元のファイルへのリンクが機能するはずです。
クリスS

1
この質問に対する受け入れられた答えはありませんが、あなたはどれに言及していますか?
ハマンサミュエル

これ>には、削除されたファイルへのリダイレクト()が必要ではありませんか?
ncasas

1

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

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

/ proc / <pid> / fd / Nからデータを正常に抽出できますが、それは私がやろうとしていることではありません。
mbac32768

1

Sleuthkit icatを使用します。

sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file

これは、オペレーティングシステムのファイルシステム機能をバイパスし、ディスクバイトを直接解析することで機能します。
フリム14

0

威圧的なツールなしで、私のために働いた迅速なソリューション:

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}

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.