`lsof`は開いたファイル記述子のファイル名をどのように追跡しますか?

`lsof`は開いたファイル記述子のファイル名をどのように追跡しますか?

ファイルの名前を変更すると、lsof新しい名前が表示されることを確認しました。

これをテストするためのスクリプトが作成されましたpython

#!/bin/python
import time

f = open('foo.txt', 'w')
while True:
  time.sleep(1)

名前の変更を確認した後lsof:

$ python test_lsof.py &
[1] 19698

$ lsof | grep foo | awk '{ print $2,$9 }'
19698 /home/bfernandez/foo.txt

$ mv foo{,1}.txt

$ lsof | grep foo | awk '{ print $2,$9 }'
19698 /home/bfernandez/foo1.txt

電話番号を通じてでもよいと思いましたinode。これをテストするために、ファイルへのハードリンクを作成しました。ただし、lsof元の名前は引き続き表示されます。

$ ln foo1.txt foo1.link

$ stat -c '%n:%i' foo*
foo1.link:8429704
foo1.txt:8429704

$ lsof | grep foo | awk '{ print $2,$9 }'
19698 /home/bfernandez/foo1.txt

そして、元のファイルを削除すると、lsofそのファイルへの既存のハードリンクがまだあるにもかかわらず、そのファイルは削除されたとマークされます。

$ rm foo1.txt
rm: remove regular empty file ‘foo1.txt’? y

$ lsof | grep foo | awk '{ print $2,$9,$10 }'
19698 /home/bfernandez/foo1.txt (deleted)

だからようやく...

私の質問

lsof開かれたファイル記述子を追跡して次のことを行うために使用される方法は何ですか?

  1. ファイル名変更の追跡
  2. 既存のハードリンクについて知らない。

ベストアンサー1

  1. lsofカーネル名キャッシュの inode を使用するという仮定が正しい。 Linuxプラットフォームでは、パス名はLinuxファイルシステムによって提供されます/proc

  2. ハードリンク処理はよくある質問:

3.3.4 lsofが「正しい」ハードリンクファイルパス名を報告しないのはなぜですか?

lsofがハードリンクを持つファイルの右端のパス名コンポーネントを報告すると、そのコンポーネントはカーネルの名前キャッシュから来ることがあります。開いたファイルをカーネル名キャッシュに接続するキーは、名前が異なるハードリンクごとに同じである可能性があるため、lsofは、開いているすべてのハードリンクファイルに対して1つの名前しか報告できません。。時にはこれは観察者にとって「正しい」ように見えます。時にはそうではありません。カーネルにとって重要なファイル識別キーはデバイス番号とノード番号であり、すべてのハードリンク名で同じであることを覚えておいてください。

実際に削除されたノードの完全な表示は、Linux(および同じ説明によると、将来のバージョンのSolaris 10)にも適用されます。よくある質問)。

おすすめ記事