====== FreeBSDでVirtualBoxを動かしていると巨大ファイルの転送でCannot allocate memoryが出る ======
FreeBSD 10.1-RELEASEな自宅ファイルサーバからMacにファイルをコピーすると「予期しないエラーが起きたため、操作を完了できません(エラーコード -50)。」が発生してコピーに失敗する現象に長らく苦しめられていた。経験的にファイルサイズが大きいほど発生確率が高く、数百MBくらいまでのファイルなら問題ないが、2GBを超えるとまずアウトっていう。鯖→Macの場合AFP(Netatalk 3.1.7)でもCIFS(Samba 4.2.5)でも発生し、鯖→Windowsの場合は言うまでもなくCIFSしか使えないが、所々詰まりながらも一応成功するといった具合。
失敗時はNetatalkのログに「Cannot allocate memory」が必ず記録されている。発生場所は大体''{fork.c:913} (error:AFPDaemon): afp_read''か''{dsi_stream.c:424} (error:DSI): dsi_stream_read_file''のどっちか。メモリたんねーと言われましても、32GB積んでる''top''で見ても余裕のよっちゃんイカで数GBレベルで残ってますし…。もう全くわけがわからないよ!本格的に原因を探ろうとsshで各種情報をモニタリングしながらコピーしたら、今度はsshdまでCannot allocate memory吐いて接続切れるし……。
ドライバの不具合?NIC/L2SW由来の不具合??もしかしてケーブルが腐ってる???などなど、疑心暗鬼ロードを爆走していたが、ようやく、ついに!遂に!!原因がわかったッ!!!!
**犯人は**ヤス**何とVirtualBox。** VirtualBox実行中はnetgraph関連のメモリが不足しやすく?なるっぽい。[[https://lists.freebsd.org/pipermail/freebsd-emulation/2011-July/008983.html|ここ]]や[[http://www.bmtsolutions.us/wiki/article:freebsd:errors:write_failed_cannot_allocate_memory|ここ]]で同症状が報告されており、''/boot/loader.conf''に''net.graph.maxdata=65536''を追加すればおkと書いてあった。
このカーネルパラメータはnetgraphのデータキューの最大確保数を表すものらしい。同様に非データ用の''net.graph.maxalloc''なんてのもある。それぞれ''/usr/src/sys/netgraph/ng_base.c''で定義されていて、コメントが若干怖いことが書いてあった。
static int maxalloc = 4096;/* limit the damage of a leak */
static int maxdata = 512; /* limit the damage of a DoS */
下手に大きくすると問題発生時に被害が拡大しそうな雰囲気。ま、外部公開してなきゃそんなに気にしなくてもいいだろうけど。
ついでに''dmesg''に''Limiting open port RST response from 208 to 200 packets/sec.''なるログも出ていたので、''/etc/sysctl.conf''に以下を追加。
net.inet.icmp.icmplim=2000
肝心の''loader.conf''も一応。
net.graph.maxdata=65536
net.graph.maxalloc=65536
上記設定で1~6GBほどのファイルを100GB分くらいコピーしてみたら、何の問題もなく完了した。普通に動くって素晴らしい。
===== 参考サイト =====
* [[https://lists.freebsd.org/pipermail/freebsd-emulation/2011-July/008983.html|Network problems while running VirtualBox]]
* [[http://www.bmtsolutions.us/wiki/article:freebsd:errors:write_failed_cannot_allocate_memory|Write failed: Cannot allocate memory]]
* [[http://blog.goo.ne.jp/nhh0/e/02d8d5396c58b2f2eac4319bcd2bc006|(FreeBSD) bacula-fdが ERR=Cannot allocate memory というエラーを出す - ttt]]
* [[http://www.yosbits.com/opensonar/rest/man/freebsd/man/ja/man4/netgraph.4.html?l=ja|NETGRAPH(4) - 特殊ファイル - YOS OPENSONAR]]
* [[http://blog.guideme.jp/archives/148|apache負荷対策 | ガイドミー管理者日記]]