closeがEINTRを返したらどうするべきか
- kosaki55tea
- 26491
- 82
- 87
- 8
@koie アプリケーション層のプロトコルで結果を確認することにして、close()の結果は気にしないってのが実用的な気がします。>たいてのプロトコル
2013-10-30 12:26:11@nalsh 基本はEINTRだけリトライすればよくてEBADFはバグなのであきらめて、ってことになるでしょうか。hpuxはしらんです。たぶんもう触ることはなさそうだし。
2013-10-30 12:27:02@koie @nalsh いや、EINTRでリトライする必要があるのはHP-UXだけで、他のOSでは、そもそもリトライしちゃだめ(ディスクリプタが無効化されてるし、multithreadプログラムだとraceがあるし)ってことなのでは?
2013-10-30 12:28:54そういえば、ファイルサーバのプロセスをデーモン化するときにfdをcloseしまくってたら、プログラム中にfprintf(stderr,...)でログを吐くコードがあってfd=2がディスクデバイスになっててファイルが静かに壊れていったという話を聞いた。
2013-10-30 12:29:54@nalsh @koie たぶんHP-UXだけですよね>close(2)がEINTR返したときにリトライする必要があるOS。他にあるのかしら?
2013-10-30 12:32:10@koie @n_soda HP-UX以外では、まだ書き込み終わってないけど、fd table的にはクリアしちゃったよん、という意味。これを聞いてリトライできないじゃん困るというアプリはfsync使えボケ攻撃が待っている
2013-10-30 12:32:58@koie close(2)がEINTRを返した時にディスクリプタが無効化されるOSでは、カーネルがあとで勝手に処理をリトライしてくれて、資源も解放されると思います。されなかったらカーネルのバグ扱いでしょう。
2013-10-30 12:33:49@n_soda @koie いやリトライなんかされてねーと思いますよ。そださんがさっき出してくれたリンク見るとそんな感じのこと書いてある
2013-10-30 12:35:26@koie POSIXにはEINTRも載ってますよ: http://t.co/QAdGs6mHYx マニュアルで抜けてる理由は、ブロックデバイスはEINTR返さないせいのような。でもintrないしsoftマウントしているNFS先にfsync(2)したらEINTRが返るかと。
2013-10-30 12:37:35HP-UX 以外(?)では close(2) は fd が無効になることを保証しているらしいけど、なんで EINTR の場合もそうなのかは不思議でならない。close 処理は完了していないけど、fd は無効な状態ってことかな? https://t.co/TsItWqDmh6
2013-10-30 12:37:48しかし posix_close()とか、出来ても絶対だれも使わないと思う。さすがに手遅れだと思うし、対処も場当たり的すぎる
2013-10-30 12:41:47@kosaki55tea (あ、ちゃんと読んでないのがバレた) リトライするかどうかは、クローズが実際に起こす動作によるような。NFSの場合、カーネル内のダーティなバッファを解放する必要があるので、最終的にリトライが起きるんじゃないでしょうか?←コード読んでないです
2013-10-30 12:43:42@kosaki55tea @tanaka_akr なるほどLinuxのclose(fd)でEINTRでリトライは無駄というか有害ですか。
2013-10-30 12:45:22@kosaki55tea HP-UXが滅ぶ→OpenGroupが現状追認 という結果になりそうな。もしItaniumが続くならHP-UXも存続するでしょうけど、その可能性って…
2013-10-30 12:45:39@n_soda 必要? closeでflushするのはただの習慣であって必須ではありませんよ。HAHAHA。という確信犯にしか見えないのですが
2013-10-30 12:45:47@kosaki55tea NetBSDの場合、close(2)でflushしているのはNFSv3の場合だけで、v2の場合は、その後のバッファ管理に任せてますね。(実はそこだけは読んでから書いたのです^^;)
2013-10-30 12:47:30@n_soda @koie Linuxだとクラウドストレージだの分散ファイルシステム用のFUSEでできたファイルシステムが大量にありますが、エラー処理が甘いのが多いので…
2013-10-30 12:51:31@n_soda Linuxの場合バージョンによらずfsyncしてるだけなので、プロトコル上何回も往復してる途中のどこかでEINTR返すとそれがそのままユーザー空間まで漏れますね。その場合はカーネルのflusher threadがflushしてくれるまでカーネルに滞留しそう
2013-10-30 12:52:01@nminoru_jp @koie FUSEの場合も、close(2)がEINTRを返した時にはfdは無効化されてるでしょうから、対策としてはclose(2)のリトライではなく、fsync(2)しとくとか、ユーザーに通知するとか、open(2)からやり直すとかではないでしょうか。
2013-10-30 12:57:59