Togetter/min.tを安心してお使い頂くためのガイドラインを公開しました。
編集可能

closeがEINTRを返したらどうするべきか

カーネルハッカーたちがcloseの仕様について辻斬りでバッサリするスレッド
47
中村 実 @nminoru_jp

世の中には二通りの人間がいる。close()の復帰値を確認する人間としない人間だ。

2013-10-30 10:04:21
KOSAKI Motohiro @kosaki55tea

@nminoru_jp 確認したところでたいていは手遅れで復旧不可能だけどね

2013-10-30 10:08:30
中村 実 @nminoru_jp

@kosaki55tea どうなんでしょう。close()がEINTRで返ってきた場合にリトライをかけないとリークが発生することがあります。FUSEでできた変なネットワークファイルシステムを使っている場合なんて特に。

2013-10-30 11:26:30
鯉江 @koie

@nminoru_jp closeがエラーになったら異常系に飛ばしてました。EINTRリトライは考えてなかったっす。異常系処理でcloseするときもEINTRリトライはしないといけないなぁ。やばいなぁ。

2013-10-30 11:29:17
Tanaka Akira @tanaka_akr

@nminoru_jp @kosaki55tea close(fd) が失敗した時に fd が生きていることがあるのですか。以前 NFS の quota でテストして close が失敗したときには fd は死んでいたので、close が失敗したらどうしようもないと思ってました。

2013-10-30 11:32:07
KOSAKI Motohiro @kosaki55tea

@tanaka_akr @nminoru_jp Linux限定だと 1) fd table のクリア 2) f_op->flush() という順でエラーが起きる可能性があるのは2だけ、かつVFSのflushはNFSぐらいしか使ってないので、EINTR無視でいいはずです

2013-10-30 11:39:38
KOSAKI Motohiro @kosaki55tea

@tanaka_akr @nminoru_jp 他のOSはしらないけど、EINTRでfdがクリアされてるかどうか不定のOSがあったらバグだと思う。しかしPOSIX的にはEINTR返ってきたらfildesの状態は unspecified なのだな。腐ってやがる・・・・

2013-10-30 11:41:39
KOSAKI Motohiro @kosaki55tea

@tanaka_akr @nminoru_jp なので、ものすごく保守的に考えるとEINTRではリトライ、すでに閉じ済みだったら次はEBADFが帰ってくるはず。という仮定をすることになる・・・・のかなあ?めんどくさくてやってられないが

2013-10-30 11:42:51
Tanaka Akira @tanaka_akr

fd の確保・解放と、資源との接続・切断が分離されていないのは Unix の design error だと思う。

2013-10-30 11:43:54
Tanaka Akira @tanaka_akr

@kosaki55tea @nminoru_jp EBADF を期待しちゃうと signal handler で fd が allocate される可能性が。

2013-10-30 11:44:48
KOSAKI Motohiro @kosaki55tea

@tanaka_akr @nminoru_jp ああ、ほんとですね。やっぱり規格のミスだよなあ。これ

2013-10-30 11:45:24
成瀬 @nalsh

@nminoru_jp @kosaki55tea 下手にリトライかけると新しく割り当てられた他人のfdを解放してしまう恐れがあるので、その変なネットワークファイルシステムの方がおかしいように思います

2013-10-30 11:52:23
KOSAKI Motohiro @kosaki55tea

@nalsh @nminoru_jp Linuxの場合closeが返ってきた時はfdが無効化されてるが保証されてるのでリトライは100%意味がなく、たとえFSがバグっていたと仮定してもリトライは変な気がします。あとNFSもEINTR返すからEINTR自体はバグではない

2013-10-30 11:59:38
KOSAKI Motohiro @kosaki55tea

@nalsh @nminoru_jp むしろNFSもEINTR返すなよって気はするけどな。わたしは

2013-10-30 11:59:59
Tanaka Akira @tanaka_akr

そういえば、socket も linger で close 時の error があったような...

2013-10-30 12:02:22
成瀬 @nalsh

@kosaki55tea @nminoru_jp ちなみにFreeBSDもfd無効化保証していますね

2013-10-30 12:03:04
成瀬 @nalsh

@tanaka_akr FreeBSDはECONNRESETを返すことがありますな

2013-10-30 12:03:32
SODA Noriyuki @n_soda

@nalsh @kosaki55tea @nminoru_jp http://t.co/UIcazQ3wUV みると、だいたいどのOSも、EINTR返した時には既にfd無効化済みみたいですね(Solarisもそうみたい)。リトライが必要なのはHP-UXっぽい。

2013-10-30 12:09:38
KOSAKI Motohiro @kosaki55tea

@tanaka_akr 今手元にあるソースだとlingerのときの処理は返り値無視してるのでerrorはユーザ空間まで伝搬しないように見えるけどなあ

2013-10-30 12:11:33
SODA Noriyuki @n_soda

@nalsh @kosaki55tea @nminoru_jp あとAIXはmanにfdが無効化されてると明記されてるとありますね。HP-UXは逆にリトライが必要と明記されているという。Solaris 9のmanにはunspecifiedとありますが実際には無効化済みなのかしら

2013-10-30 12:12:02
Tanaka Akira @tanaka_akr

@kosaki55tea 体験したわけじゃなくて、本で読んだ記憶があるという話です。Stevens だった気がする。

2013-10-30 12:13:18
SODA Noriyuki @n_soda

@koie リトライすると、かえって @nalsh さんが書いてた race condition によるバグが増えるので、リトライするなら #ifdef hpux が必要ってことなんじゃないでしょうか。

2013-10-30 12:19:47
成瀬 @nalsh

@n_soda @koie closeのrace conditionはデバッグ大変なので安易にリトライすると大変ですよ……

2013-10-30 12:21:45
鯉江 @koie

@n_soda 見落としてました。ちゃんとmanpageにかいてありますねEINTR以外はdeallocated。じゃぁcloseするまえにfsyncするのは必須ってことですかね、ファイルシステムのばあいは。ソケットだと上のレイヤ―で確認したほうが簡単かなぁ。

2013-10-30 12:23:34
SODA Noriyuki @n_soda

@nalsh @koie 発生したら関係ないファイルに間違えて書くとかありうるので、デバッグ大変だけじゃなく、データ失うとかいうヤバいバグに…

2013-10-30 12:23:56
残りを読む(38)

コメント

狐謡 @Towa_towa_to 2013年10月30日
なにこのルー大柴の集団w
3
KOSAKI Motohiro @kosaki55tea 2013年10月31日
. @Hiroki_Sato 先生のSUSの規格ステータスの見方に関するコメントを追加しました
0
KOSAKI Motohiro @kosaki55tea 2013年10月31日
むしろルー大柴の集団っておもしろすぎるので布教したい。
0
Takanori Watanabe @takawata19 2013年10月31日
ファイルをcloseするとEINTRがreturn valueになることがあるのデース。
0
KOSAKI Motohiro @kosaki55tea 2013年10月31日
イーインタがリターンヴァリュでクローズなのデース。 #ルー大柴集団
0
藤枝和宏 - ぱんなこった@佐鎮 @kfujieda 2013年10月31日
ギークがルー大柴をイミテイトすると金剛になってしまうのデース!
0
Tsuyoshi CHO @tsuyoshi_cho 2013年10月31日
クライアントアプリ(すぐ終了)ならプロセス終了にまかせてもいい...?ただ、システムの構造に密接なサービスとかでないなら、特定のOS、ファイルシステム(の実装)に依存しないほうがいいと思うけど。どのシステムでもFSの実装なんて変ってしまう可能性はあるんだし。
0
SODA Noriyuki @n_soda 2013年11月1日
tsuyoshi_cho EINTRを返した場合の対処に「特定のOSに依存しない方法」は存在しないです( HP-UXの仕様が他と異なるため)。あとfdを無効化するか否かはFSより上のレイヤで実装されてるので、OS同じならFSには依存しないかと。
0
SODA Noriyuki @n_soda 2013年11月1日
tsuyoshi_cho なお、すぐプロセス終了ならOSに依存しません。いずれにせよ、書き込みが成功しているか否かはclose(2)以外の手段で調べるべきですし。あと、ローカルファイルシステムならEINTRがそもそも返りません。
0
Tsuyoshi CHO @tsuyoshi_cho 2013年11月2日
n_soda なるほど...了解です。まあそれでも、特定の実装(どのレイヤだって改良で変化しうるし)には依存しないようにしたいなー
0