ポーズを取った後この問題、私はlinxuカーネルの動作について少し混乱しています。
まず、プロセスがファイルに文字列を書き込む方法を知っています。プロセスはプロセスが書き込むことができるバッファを取得し、バッファがいっぱいになったりプロセスがバッファをフラッシュしたりすると、バッファの内容が次に書き込まれます。データブロックファイル。たとえば、Cプログラムでを使用すると、バッファprintf
が\n
フラッシュされます。
さて、上記の投稿の状況を考えてみましょう。プロセスはファイルを開いていてここに書き込んでいますが、ファイルを削除するように指示されましたrm
。
私が理解したように、このコマンドはrm
ファイルのリンクを解除します。対応する inode とデータブロック。と表示されるため、UNUSED
ファイル名でアクセスできなくなります。プロセスがファイルを開くと、カーネルはファイルにアクセスするためのファイル記述子を作成します。
したがって、私が正しい場合、rm
プロセスはファイル記述子を介してファイルにアクセスできるため、プロセスが書き込んでいるファイルはプロセスにエラーを引き起こさないでしょう。その投稿のコメントで誰かが言及したように、私たちはまだ勝つことができますcat /proc/<pid>/fd/3
。
今私は混乱しました。cat /proc/<pid>/fd/3
inodeを介してまだファイルにアクセスでき、データがUNUSED
forとマークされている場合、rm
カーネルはファイル全体をRAMに保存します。もしそうなら、いくつかのログファイルのように、ファイルが非常に大きい場合、RAMが大量に使用されることを意味しますか?
つまり、ファイルがrm
編集されていない場合、プロセスは内容をバッファに書き込むことができ、バッファがフラッシュされると、その内容がファイルのデータブロックに書き込まれます。ただし、ファイルが編集されている場合、そのデータブロックは次のようにrm
表示されます。UNUSED
それ。ここがどこだ」それ「?
答え1
私が理解したように、このコマンドは
rm
ファイルのリンクを解除します。対応する inode とデータブロックと表示されますUNUSED
。
これがここで何が起こっているのかを理解するための鍵です。rm
カーネルは単に与えられたディレクトリエントリを削除するように要求されます。また、カーネルは、ディレクトリエントリが指すinodeが他のエントリ(他のディレクトリエントリ、開かれたファイルの説明、ファイルマッピング、ループマウントなど)で参照されなくなった場合、inodeと関連データを解放します。
したがって、カーネルは削除されたファイルのデータを保持する必要はありません。ファイルシステムがそれを保存する場所に関係なく、まだ存在します。プロセスを指すファイル記述子がある限り、そのプロセスはそのまま残り、/proc/.../fd/...
Linuxで再起動できます。