web-dev-qa-db-ja.com

開いているファイルハンドルは、死んだときにどこに行きますか?

ファイルハンドルが開いている間に削除されたファイルはどうなりますか?

MPlayer で再生中にビデオファイルを削除でき、それでも最後まで再生できると思って以来、これについて疑問に思っていました。どこからデータを取得していますか?それはまだハードドライブから来ていますか?ファイルを削除すると、RAMにコピーされましたか?

それがまだハードドライブ上にある場合、プログラムの実行中にファイルシステムがいっぱいになると、本質的に未割り当ての領域から読み取りを行うとどうなりますか? RAMにバッファリングされている場合、バッファをフラッシュするとどうなりますか?

ファイルがNFS共有にある場合はどうなりますか?サーバーに保存されていますか? (それはセキュリティリスクではありませんか?開いているリモートファイルハンドルのトンによるDoSですか?)

lsof -n |grep '(deleted)'を実行すると、興味深い結果が得られる場合があります。共有ライブラリファイルをスワップアウトするパッケージをアップグレードする場合、それらのライブラリを使用していた実行中のプログラムは、何も変更されていないかのようにそれらを使用できます。

ボーナス質問:この状況で死者からデータを取り戻す方法はありますか?

15
amphetamachine

Iノードへのハードリンクはもう存在しませんが、iノードはディスク上に残ります。これらは、ファイル記述子が閉じられると削除されます。それまでは、ファイル名/ハードリンクを必要とする操作を除いて、ファイルを通常どおりに変更できます。

debugfsおよび同様のツールを使用して、iノードの内容を回復できます。

カーネルは、iノードへの参照をカウントして参照を行います。 ファイル記述子をclose()するとどうなりますか? に対する私の答えを参照してください。

開いているファイルを削除することは、単にファイルを開くことほど効果的なDOSメカニズムではない可能性があります。開いているファイルのulimitは、このDOSの試みに対するある程度の保護を提供します。削除されているかどうかに関係なく、開いているすべてのファイルに適用されます。

5
BillThor

ファイルへのすべての参照が消えると、ファイルはファイルシステム上でのみ消去されます。名前と開いているハンドルの両方が参照としてカウントされます。ファイルがプログラムで開かれている限り、ファイルは削除されませんが、ほとんどのシステムでは、ファイルの名前を再作成することはできません。

データはまだドライブ上にありますが、ファイルはリンクカウント0としてマークされています。システムがクラッシュした場合、次回の再起動時にfsckはデータを削除する必要があることを認識します。これは、削除されていないファイルよりもサービス拒否につながることはありません。

私の知る限り、ストックLinuxシステムでファイルへのリンクを再作成することはできませんが(debugfsまたは同様の方法でファイルシステムドライバーをバイパスする以外)、内容を簡単に復元できます:cat /proc/12345/fd/42ここで、12345はファイルを開いているプロセスIDであり、42はファイル記述子番号です。

NFSを介して、一部のクライアントでまだ開いているファイルを削除すると、NFSサーバーはサーバー上のファイルの名前を変更しますが、すべてのクライアントがファイルを解放するまでファイルを削除しません。私の経験では、新しい名前は.nfs…ですが、名前がすべてのNFS実装で同じかどうかはわかりません。