同じ「オープンファイル記述」を共有するファイル記述子が何であるかを確認します。

同じ「オープンファイル記述」を共有するファイル記述子が何であるかを確認します。

これを行うと(Bourneのようなシェルで):

exec 3> file 4>&3 5> file 6>> file

ファイル記述子 3 と 4 は、3dup()から 4 が編集されているため、同じことを共有します。ファイル説明を開く(同じ属性、ファイル内の同じオフセット...)。プロセスのファイル記述子5と6は別の場所にありますが、ファイル説明を開く(たとえば、すべてのファイルに独自のポインタがあります。)

これでlsof出力で見ることができる内容は次のとおりです。

zsh     21519 stephane    3w   REG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    4w   REG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    5w   REG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    6w   REG  254,2        0 10505865 /home/stephane/file

次の方法を使用することをお勧めしますlsof +fg

zsh     21519 stephane    3w   REG          W,LG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    4w   REG          W,LG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    5w   REG          W,LG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    6w   REG       W,AP,LG  254,2        0 10505865 /home/stephane/file

(Linux 3.16では)fd 6には異なるフラグがあるため、異なる必要があります。ファイル説明を開く1つはfd 3、4、または5にありますが、これではfd 5が別の場所にあることはわかりません。ファイル説明を開く。を使用すると-oオフセットも表示できますが、同じオフセットが同じであることを保証するものではありません。ファイル説明を開く

非侵襲的に把握する方法はありますか?外部ですか、それともプロセス自体のファイル記述子ですか?


1. 1 つの経験的な方法は、1 つのファイル記述子のフラグを変更fcntl()し、結果として別のファイル記述子のフラグが更新されることを確認することですが、これは確かに理想的または完全な方法ではありません。

答え1

Linux 3.5以降では、次のことができます。kcmp(2):

KCMP_FILE

  • ファイル記述子が存在することを確認してください。idx1進行中PID1同じオープンファイルの説明を参照してください(参照:オープン(2)) ファイル記述子としてidx2進行中PID2。同じオープンファイル記述を参照する2つのファイル記述子が存在する理由は次のとおりです。繰り返し(2)(そして同様)フォーク(2)、またはドメインソケットを介してファイル記述子を渡します(参照:Unix(7))。

マニュアルページは、OPが要求したユースケースの具体的な例を提供します。このシステムコールを実行するには、カーネルをsetにコンパイルする必要がありますCONFIG_CHECKPOINT_RESTORE

答え2

比較するのは、struct fileファイル記述子が指すポインタです。 (カーネル内にはtask_structスレッドごとのデータ構造があります。これには、他の構造へのポインタが含まれていますfiles_structそれこの構造には、それぞれ1つを指すポインタ配列が含まれており、検索オフセット、パブリックフラグ、およびその他のフィールドがありますstruct filestruct file)

files_structいくつかの侵入的なツールを使用する以外に、ユーザーがポインタを表示する方法がわかりません。たとえば、SystemTapにPIDが提供されている場合は、そのPIDを見つけてポインタにtask_struct従うことができます。しかし、パッシブを探しているなら、これはまさにそれだと思います。 Dellでツールをリリース長いしばらくしても、KME(Kernel Memory Editor)として知られているこのプログラムは、必要な操作を実行できるリアルタイムカーネルメモリ用のスプレッドシートに似たインターフェースを提供しましたが、64ビットに移植されたことはありません。 (試してみましたが、うまくいかず、理由はわかりません。)

役に立たないと思う理由の1つは、そのポインタも表示されないためですlsof(ただし、+fLinuxではなくシステムのオプションを確認してください)。理論的には、すべてのフィールドを比較し、両方の構造がstruct file同じと見なすことができますが、それでも別々のopen(2)呼び出しから来ることができます。

見てpファイルSystemTapスクリプトのアイデア。アドレスを印刷するように変更すると、struct file解決策が得られます。また、確認することができます_pid.stpで開かれたファイルその中には巡回できる関数があるからfiles_structです。ファイル記述子テーブル、struct fileオブジェクトの表示...

あなたが達成したいものが何であるかを尋ねてください。

答え3

以下はLinux関連のソリューションです。 /proc/self/fd は、現在のプロセスでファイルハンドルを開くシンボリックリンクディレクトリです。リンク値を比較するだけです。子プロセスを使用すると、子プロセスはpid依存のシンボリックリンクであるため、異なる/proc/selfを持つため、より複雑になります。 /proc/$$/fd を使用してこの問題を解決できます。ここで$$は希望のpidです。

関連情報