Path: sran265!katsu From: katsu@sran14.sra.co.jp (WATANABE Katsuhiro) Message-ID: Date: 27 Mar 93 19:23:45 Organization: Software Research Associates, Inc.,Japan In-reply-to: yas@softlab.is.tsukuba.ac.jp's message of 16 Mar 93 10:02:03 GMT Newsgroups: fj.unix Followup-To: fj.unix Subject: Re: File System Full Distribution: References: <1993Mar16.100203.29422@iris.is.tsukuba.ac.jp> フォローの遅さなら jp で十指に入るであろう渡邊@SRAです。 記事 <1993Mar16.100203.29422@iris.is.tsukuba.ac.jp> で yas@softlab.is.tsukuba.ac.jp (Yasushi Shinjo) さんいはく > From article , > by isii@lsidiv.kawasaki-steel.co.jp (ISHII Sin'ichi): > > ファイルシステムがフルになった検出について、 > > 多くのメイル&フォロー、どうもありがとうございました。 > > > 方法2 > > statfs() のメンバ f_bavail をチェックする。 > > この方法は、非常に厳しい条件では、失敗することがあります。 > > たとえば、write() する前に、statfs() で1Mバイト空いている > ことを確認したとしても、次の瞬間に誰かがその残りの1Mバイト > を全部食いつくす可能性があります。逆に、write() した後に、残 > り容量が十分あることを確認したとしても、それは、誰かがファイ > ルを消したためにできたものかもしれません。つまり、write()し > た時には、f_bavail が 0 だった可能性もあります。  検査と書き込みの間の原子性(不可分性)が保証できないという以前に、 そもそも statfs() の f_bavail による検査自体にも問題があります。 f_bavail は、直感的なファイルシステムの空きとは異なる概念を表現しており、 この分だけ自由自在に write ができるわけではありません。  少し詳しくいうと、 (a) statfs() の結果 f_bavail が x であれば、それ以降 x fragments 分を 越えてファイルを拡張するような write() は一切失敗する ことはいえますが、これの逆の (b) 現在以降ファイルを x fragments だけ拡張する write() が(空き容量が 少ないことを原因として)失敗する場合、statfs() は空き容量として x 未満を返す というのは正しくありません。  端的にいうと、f_bavail では、ファイルシステムフル *である* ことの 検出はできても、ファイルシステムフル *でない* ことの確認はできません。  過去にもこれに関する議論があったので、記事を引用します。  なお、最後の考察の事故予防策については、今考えてみると役に立たないように 思え、識者の批判を期待するところです。 -- 渡邊克宏@SRAソフトウェア工学研究所 ======== 引用はじめ ======== From: katsu@sran14.sra.co.jp (Katsuhiro Watanabe) Message-ID: Date: 21 Jan 92 19:05:39 Organization: Software Research Associates, Inc.,Japan Newsgroups: fj.unix,fj.news.adm Followup-To: fj.unix Subject: A filesystem have overflown in spite of avail>0 Distribution: fj (Followup-To: に注意)    ファイルを作ろうとした時に、対象となるファイルシステムを df(1) で 見た時の avail が 0 でないにもかかわらず、file system full になる事態を 経験しました。お正月の景気づけに事例を投稿します。  機械は Sony NEWS-3860 (NEWS-OS 4.1) ですが、BSD の Fast File System (に由来するもの)を使っている時に共通の問題です。 [1] 事故の状況  問題のファイルシステムはニュースのスプールであり、NNTP によって 記事が転送されてくる。nntpd は記事を受けとる前にディスクの 残り容量を statfs(2) で監視していることから、記事の受け取りに関する ディスク溢れは生じないと(少なくとも私と、他にもう一人は)信じていた。  このファイルシステムは、blocksize/fragmentsize が 4096/512 で、 minfree(free-space reserve) を 1% にしてあった。  ある日、記事の受け取り中に溢れが生じた。その時点で df(statfs(2) を 調べるのと同じこと)すると、 # df /var/spool/news Filesystem kbytes used avail capacity Mounted on /dev/sd10e 263303 259190 1479 99% /var/spool/news と、まだ 1479K かけそうな様相を示している。(従って nntpd は無罪。) fsck してみると、 # fsck /dev/sd10e : : : : : : : 98102 files, 518381 used, 8226 free (8226 frags, 0 blocks, 1.6% fragmentation)  というように、実は、もはや空ブロックは一つもなく、沢山残った フラグメントだけが 1479K の「まぼろし」を見せていただけであった。 8226 * 512 = 4113K (空きフラグメントの合計)  4113 - (263303 * 1%) = 1479 分だけ avail になっているわけである。  実際、フラグメントサイズを越える大きさのファイルは file system full に なって一切作ることができなかったが、フラグメントサイズ以下の大きさの ファイルは、まだいくつでも作ることができた。 [2] 考察と教訓 ・statfs(2) は、空き容量をフラグメント単位で返すだけであって、 あとどれだけ書き込めるかを教えてくれるわけではない。 (df の出力についても同様) ・他で同種のトラブルを聞かないのは、普通は free-space reserve が 十分大きいため、ブロックを使い切るよりも f_bavail が 0 になる方が 先だからだろう。 ・今回のようなことが原因による一般ユーザーでの書き込み不能を 予防するための方法論として、fsck が出す、xxx% fragmentation の xxx% よりも free-space reserve を大きくしておくことを提案する。 こうしておけば、フラグメント分は free-space reserve 分に埋もれて、 一般ユーザーにとって無関係になることが保証される。この条件が 満足されているかどうかの監視も、fsck してみるだけなので容易である。 ・BSD の Fast File System では、空きブロックの多寡が書き込み時の 性能に影響するはずである。また、満杯近くで作られたファイルは ブロックが局所化されず、結果的に読み込みの性能にも影響するはずである。 これらの点からいっても、ファイルシステムを極限状態で使うのは よした方がよい。 ----____----____ 渡邊克宏 SRAソフトウェア工学研究所 ======== 引用おわり ========