From owner-freebsd-users-jp@freebsd.org Mon Dec 14 01:39:21 2015 Return-Path: Delivered-To: freebsd-users-jp@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2C3AEA42615 for ; Mon, 14 Dec 2015 01:39:21 +0000 (UTC) (envelope-from hrs@allbsd.org) Received: from mail.allbsd.org (gatekeeper.allbsd.org [IPv6:2001:2f0:104:e001::32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.allbsd.org", Issuer "RapidSSL CA" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 0833A1736 for ; Mon, 14 Dec 2015 01:39:19 +0000 (UTC) (envelope-from hrs@allbsd.org) Received: from alph.d.allbsd.org (p1141-ipbf2205funabasi.chiba.ocn.ne.jp [114.148.196.141]) (authenticated bits=56) by mail.allbsd.org (8.14.9/8.14.9) with ESMTP id tBE1ctaD036681 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) (Client CN "/C=XX/ST=Some-state/L=Some-city/O=Some-org/CN=alph.allbsd.org", Issuer "/C=XX/ST=Some-state/L=Some-city/O=Some-org/CN=alph.allbsd.org"); Mon, 14 Dec 2015 10:39:06 +0900 (JST) (envelope-from hrs@allbsd.org) Received: from localhost (localhost [IPv6:::1]) (authenticated bits=0) by alph.d.allbsd.org (8.15.2/8.15.2) with ESMTPA id tBE1cp0s033999; Mon, 14 Dec 2015 10:38:55 +0900 (JST) (envelope-from hrs@allbsd.org) Date: Mon, 14 Dec 2015 10:37:24 +0900 (JST) Message-Id: <20151214.103724.2126919077244353026.hrs@allbsd.org> To: mojimoji528@yahoo.co.jp Cc: freebsd-users-jp@freebsd.org From: Hiroki Sato In-Reply-To: <20151204161307.A4FC.60E52F2C@yahoo.co.jp> <20151204180446.A504.60E52F2C@yahoo.co.jp> References: <20151204161307.A4FC.60E52F2C@yahoo.co.jp> X-PGPkey-fingerprint: BDB3 443F A5DD B3D0 A530 FFD7 4F2C D3D8 2793 CF2D X-Mailer: Mew version 6.6 on Emacs 24.5 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Multipart/Signed; protocol="application/pgp-signature"; micalg=pgp-sha1; boundary="--Security_Multipart(Mon_Dec_14_10_37_24_2015_559)--" Content-Transfer-Encoding: 7bit X-Virus-Scanned: clamav-milter 0.98.6 at gatekeeper.allbsd.org X-Virus-Status: Clean X-Greylist: Sender DNS name whitelisted, not delayed by milter-greylist-4.4.3 (mail.allbsd.org [133.31.130.32]); Mon, 14 Dec 2015 10:39:12 +0900 (JST) X-Spam-Status: No, score=5.5 required=13.0 tests=CONTENT_TYPE_PRESENT, ISO2022JP_BODY,JOUHOU,RCVD_IN_AHBL,RCVD_IN_AHBL_PROXY,RCVD_IN_AHBL_SPAM, RCVD_IN_PBL,RCVD_IN_RP_RNBL autolearn=no autolearn_force=no version=3.4.0 X-Spam-Level: ***** X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on gatekeeper.allbsd.org X-Mailman-Approved-At: Mon, 14 Dec 2015 01:41:26 +0000 Subject: [FreeBSD-users-jp 95626] Re: =?iso-2022-jp?b?bmV0c3RhdCAbJEIkRxsoQiBDTE9TRUQgGyRCJCwbKEI=?= =?iso-2022-jp?b?GyRCST08KCQ1JGwkayRzJEckOSEjISMhIyEjGyhC?= X-BeenThere: freebsd-users-jp@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Discussion relevant to FreeBSD communities in Japan List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Dec 2015 01:39:21 -0000 ----Security_Multipart(Mon_Dec_14_10_37_24_2015_559)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit もじもじ wrote in <20151204180446.A504.60E52F2C@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 ----Security_Multipart(Mon_Dec_14_10_37_24_2015_559)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEABECAAYFAlZuHVQACgkQTyzT2CeTzy1fZACghS2qEsOfuBEZpGs3JE3hJM0G m0QAn2cPjZXy+SlosS3kdlu4v1bsK/K2 =QWoz -----END PGP SIGNATURE----- ----Security_Multipart(Mon_Dec_14_10_37_24_2015_559)----