もじもじ <mojimoji...@yahoo.co.jp> wrote in <20151204180446.a504.60e52...@yahoo.co.jp>:
mo> 仮にそうだとしても、そもそも CLOSED が表示されるのはなぜ mo> なんでしょうか。 CLOSED はそもそも表示される可能性がまったくないものでは ありませんが、FreeBSD 7 以降は、それ以前より表示される可能性が 高くなっています。これは、TCP 通信時に使われる構造体の メモリ領域の確保の方法が、4.4BSD で使われていたものから 変更されたからです。 socket API で通信を行なう場合、ファイル記述子、ソケット、 IP プロトコル制御ブロック、TCP プロトコル制御ブロック、のように、 通信の各層で使われる構造体がカーネルに順番に確保されます。 4.4BSD の場合、それぞれの構造体は必要がなくなった時点で解放されます。 たとえば、アプリケーションが通信終了時にファイル記述子を close した時、ソケットやプロトコル制御ブロックの構造体は、 すぐには解放されません。FIN の交換など、プロトコルで要求される 終了シーケンスが終って、初めて解放されます。 逆に、先に通信相手から FIN が送られてきて TCP 接続が 切断された場合、FIN 交換が終った時点でTCP プロトコル制御ブロックの 領域が、先に解放されます。 FreeBSD 7 には、この細分化されている構造体の確保・解放を、 ある程度まとめる変更が入りました。 7.0 以降では、たとえば、TCP 通信が FIN を交換して終了シーケンスを 完了していたとしても、ファイル記述子を close しないと TCP プロトコル制御ブロックが解放されません。 この状態の時、netstat の結果に CLOSED として現れます。 「CLOSED が見えることがほとんどない」とよく説明されているのは、 前述したとおり、4.4BSD ではファイル記述子が close されてないとしても、 FIN を交換した時点で TCP プロトコル制御ブロックが 解放されるようになっているからです。 この変更の動機は、FreeBSD が SMP に対応してカーネル各部が 並列処理されるようになったことにより、相互に関連する構造体の 参照・確保・解放にかかるコストが大きくなったためです。 構造体同士はポインタで参照されているので、確保・解放には排他制御が必要です。 そのような相互参照があると、構造体へのアクセスのたびにロックが発生して 性能が低下してしまいますし、領域が本当に確保されているのかどうかを 確認したり、確保できなかった時のエラー処理などがかなり複雑になります。 そのため、頻繁に使われる組み合わせについては、不要になってもすぐに 解放しないようにしました。 これにより多くの排他制御を省くことができるようになりましたが、 その一方で、メモリの使用量が少し増えることと、構造体解放までの 時間が長くなるという副作用が観察されるようになっています。 ただし、実用上、TCP 接続が切断された後に、ソケットを close しないで 放置するという状況は考えにくいので、まともに書かれているプログラムなら、 やっぱり CLOSED はすぐに消えます。 7.0 が出た直後くらいから、「CLOSED が出て消えない」というレポートが いくつかあがっていました。調査の結果、ほとんどがアプリケーション側の バグが顕在化したことによるものでした。 users-jp 95621 にはログなどの症状に関する生情報がないので 何とも判断できませんが、Courier IMAP 同じ問題を抱えているのかも知れません。 CLOSED が出ている状態の netstat と、sockstat の出力を 並べて比較してみてください。1 個のCLOSED 状態の接続について、 対応する sockstat の行の FD のカラムにファイル記述子の数値が 出ていて、かつ CLOSED を発生させているアプリケーションを 終了させた時に、すぐに CLOSED が全部消えるのであれば、 TCP 接続断後の close() に失敗していて、 記述子がリークしている可能性が高いのではないかと思います。 FreeBSD 7 以降では、socket をオープンした時の 記述子を正しく close しないと、切断後の TCP 接続が CLOSED のまま残るからです。 過去にあった典型的な例は、close() の引数に閉じるべきでない記述子が 指定されていて少しずつリークしていたものの、リークによる メモリ使用量が小さく、記述子数の上限に引っかかることもなかったので 長い間気づかれていなかった、というものでした。 close() の戻り値をチェックしないプログラムが多いので、この手の バグは気づかれにくいようです。 -- Hiroki
pgpeFtFFFlo7R.pgp
Description: PGP signature