http://mkosaki.blog46.fc2.com/blog-entry-280.html

追記:
ごめん、見直したら、tmpfsはなんかちゃんとカウントしてるっぽげ。
これは追試テストをして、結果を書きます。



と書いてそのまま忘れ去っていた。
誰も覚えてないと思うけど続きを書く。

まず結論から書くと、tmpfsはstrict non-overcommit modeの時にカウントされている。
ただしクセがあって、ちょっと使いにくい。

まず、どこでカウントされているのかを見ていくと、これはtmpfs本体の場所でソースコード的には以下

linux/mm/shmem.c の shmem_acct_block(), shmem_acct_size()
ただし、実質、shmem_acct_block()だけしか使ってない。

まあ、mmapの場所でカウントしてなかったら、他にありそうな場所はshmem.cぐらいしかないから、
想像はつくと思うけど(^^;


さて、ここで話を続ける前に余談を2つ、3ついれてみる。

余談1

mm/shmem.c のコードは tmpfs, shmfs(/dev/shm つまり、POSIX共有メモリ用), /dev/zeroのMAP_SHAREDなmmap
の3通りに使われている。
なので、以下の話は実はtmpfsに限らない



余談2
Unixなファイルシステムは普通どれもHoleとかSparseとかよばれる特殊なファイル状態をサポートしている。
これがどういうものかというと、あるファイルについてoffset 0-1023の範囲の1024byteにはデータがあり、
次の1024-2047にはデータがなく、さらに次の2048-3071にはデータがある。という状態のときに、
0-1023, 2048-3071の部分だけをディスクに書き込み、ファイルをエディタで開いたときは3072byteのファイルに
見えるが実際にはディスク容量を2048byte分しか消費していない。という事を可能にするFSの機能である。
(ディスクに記録されていない部分はエディタなどで開くと0が書かれているかのように見える)




んで、やっかいなことに、余談2で説明したスパースなファイルをmmapし、オフセット1500にメモリライトすると、その時点でディスク容量の確保が行われる。
で、この時、ディスク容量が足りなかったとしてもエラーを通知する方法は存在しないし、そんなエラーがおきたときに対処が出来るプログラムは存在しない。

アタリマエだ。メモリライトが失敗するとか思っていたらまともなアプリケーションは書けない。


で、さらにこまった事にtmpfsではファイル書き込みに必要なのはディスクじゃなくメモリなわけで、
こういう状況でOOM-killer以外に何が出来るか。
という状況なのよ。

で、現在のLinux kernelでは当該プロセスをSIGBUSで殺すという方針にしてるみたい。
前述の shmem.c#shmem_acct_block()のコメントを引用すると


/*
* ... whereas tmpfs objects are accounted incrementally as
* pages are allocated, in order to allow huge sparse files.
* shmem_getpage reports shmem_acct_block failure as -ENOSPC not -ENOMEM,
* so that a failure on a sparse tmpfs mapping will give SIGBUS not OOM.
*/



と書いてある(し、実際のコードもそうなっている)
他人が死ぬぐらいなら、自爆スイッチ押すぜ!ってわけだね。
ううむ、ブシドーだね。


という訳で、ここまで理由をかくと、まあ、分からんでもないな。となるのであるが、
実際の運用を考えるとSIGBUSで死なれて嬉しい状況なんて無いわけでかなり注意しないと
overcommit_memory=2 の時はtmpfsは使わずにrdデバイスに普通のFS作ったほうが
安心度が高まるかもしれない。

という、話でした。まる


自爆スイッチ
ポチっとな! ランキング!