1. ホーム
  2. c++

[解決済み] proc/ ファイルを解析しても大丈夫ですか?

2022-04-28 12:06:23

質問

をパースしたい /proc/net/tcp/ しかし、それは安全ですか?

のファイルをどのように開き、どのように読めばよいのでしょうか? /proc/ 他のプロセス(またはOS自体)が同時に変更することを恐れてはいけないのでしょうか?

解決方法は?

一般的には、ノーです。 (だから、ここの答えはほとんど間違っている。)それ かもしれない どのようなプロパティが必要かによりますが、安全でしょう。しかし、ファイルの一貫性について多くを仮定すると、コードにバグが発生しやすくなります。 /proc . 例えば と思い込んでいたことに起因するこのバグは /proc/mounts は一貫したスナップショット .

例えば、こんな感じです。

  • /proc/uptime 全原子 他の回答で誰かが言っていたように -- しかし Linux 2.6.30以降のみ これは2年も前のことです。 つまり、この小さな些細なファイルでさえ、それまではレースコンディションの対象でしたし、現在でもほとんどのエンタープライズカーネルではレースコンディションの対象になっています。 参照 fs/proc/uptime.c は現在のソース、または アトムを作成したコミット . 2.6.30以前のカーネルでは open というファイルを作成します。 read をちょっとだけ表示し、後で戻ってきたときに read というように、最初の作品と矛盾した作品が出来上がります。(これは今実演したところです。試しに自分でやってみてください)。

  • /proc/mounts の中にあるアトミックな read システムコールを使用します。 だから、もしあなたが read ファイル全体を一度に取得すると、システム上のマウントポイントの一貫した単一のスナップショットが得られます。しかし、もしあなたがいくつかの read システムコール(ファイルが大きい場合、通常のI/Oライブラリを使用し、この問題に特別な注意を払わない場合、まさにこのことが起こります)を使用すると、レースコンディションにさらされることになります。一貫したスナップショットが得られないだけでなく、起動前に存在し、存在しなくなることのないマウントポイントが、表示されるものから消えてしまう可能性があります。1つのアトミックであることを確認するために read() を見てください。 m_start()fs/namespace.c を実行し、マウントポイントのリストを保護するセマフォを取得し、それを m_stop() が呼び出されたときに呼び出されます。 read() が行われます。 何が間違っているのかを見るには 昨年のこのバグ (上記リンクと同じもの) を淡々と読み込むような高品質なソフトウェアで /proc/mounts .

  • /proc/net/tcp という質問ですが、それよりもさらに一貫性がありません。 それは テーブルの各行内にのみ原子 . これを見るには、次のようにします。 listening_get_next()net/ipv4/tcp_ipv4.c established_get_next() で、各エントリに順番にロックがかかっているのを確認してください。 行から行への一貫性のなさを実証するための再現コードが手元にないのですが、そこには一貫性を持たせるようなロックはありません(他のものも)。 ネットワークはしばしばシステムの超多忙な部分なので、この診断ツールで一貫性のある表示をするのはオーバーヘッドに値しないのです。

もう1つは /proc/net/tcp のバッファリングは、各行でアトミックです。 seq_read() を読むことができます。 fs/seq_file.c . これにより、一度 read() の部分は、行全体のテキストがバッファに保持され、次の read() は、新しい行を開始する前にその行の残りを取得します。同じメカニズムが /proc/mounts を複数回実行しても、各行がアトミックに保たれます。 read() が呼び出される仕組みであり、また /proc/uptime はアトミックな状態を維持するために新しいカーネルで使われています。このメカニズムでは ではなく はファイル全体をバッファリングします。これは、カーネルがメモリの使用について慎重であるためです。

のファイルのほとんどは /proc は、少なくとも /proc/net/tcp というのも、ほとんどの場合、同じように、各行には、提供する情報の1つの項目に関する一貫した画像が表示されるからです。 seq_file を抽象化したものです。 として /proc/uptime しかし、この例からわかるように、いくつかのファイルはまだ seq_file 2009年の時点では、まだ古いメカニズムを使っていて、そのレベルのアトミック性が確保されていないものもあるはずです。このような注意事項が文書化されることはほとんどありません。あるファイルについて、唯一の保証はソースを読むことです。

の場合は /proc/net/tcp これを読んで、一行一行を解析することは可能です。しかし、一度に複数の行から何か結論を出そうとすると -- 他のプロセスやカーネルに注意してください その間にバグが発生している可能性があります。