Troubles with ulimit on OSX
Recently I stumbled upon a problem related to maximum number of open files and maximum number of processes per user. This would be a quicky in my homeland known as Linux, but proved to be quite a feat of tinkering on OSX El Capitan.
Default settings:
[kumara@macbook ~]$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 256 pipe size (512 bytes, -p) 1 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 709 virtual memory (kbytes, -v) unlimited [kumara@macbook ~]$
Now if you attempt to open 1000 websocket clients, like I foolishly did, you will be surprised with the outcome. Long story short, number of open files (256) and number of max user processes as well, (in my specific case) were the culprit.
First thing I tried, coming from Linux land was setting the values using ulimit. FAIL
Some google foo revealed that this has been changing a lot between different versions of OSX, and one should try with launchctl limit, which surprise, surprise did not work either. Another FAIL.
After even more serious googling, someone explained the need for two new files. Those will be used by launchctl to set system wide limits after reboot.
/Library/LaunchDaemons/limit.maxfiles.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>limit.maxfiles</string>
<key>ProgramArguments</key>
<array>
<string>launchctl</string>
<string>limit</string>
<string>maxfiles</string>
<string>524288</string>
<string>524288</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>limit.maxproc</string>
<key>ProgramArguments</key>
<array>
<string>launchctl</string>
<string>limit</string>
<string>maxproc</string>
<string>2048</string>
<string>2048</string>
</array>
<key>RunAtLoad</key>
<true />
<key>ServiceIPC</key>
<false />
</dict>
</plist>
Crazy as it sounds, files created, reboot and nothing. Still sucking diesel. After day or so of even more intensive googling, I have learned that Apple believes MacbookPro will be used by hipsters, Justin Bieber and Rihanna sort of people, and not the developers sort, so they have provided utility called csrutil which prevents setting values other then those Apple sees as consistent, without telling you anything, just silently ignoring your settings.
Right....Now what?
So how do you turn csrutil off? Google says sudo csrutil disable... Ummm, not so easy, can only be done in Recovery Mode. So, reboot, hold command + R to enter Recovery Mode, once there open terminal and do csrutil disable... Finally a breakthrough...disabled.
Another reboot and my shiny two plist files take effect giving me:
[kumara@macbook ~]$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 524288 pipe size (512 bytes, -p) 1 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 2048 virtual memory (kbytes, -v) unlimited
Finally success... On a side note, Apple recommends not to tinker with csrutil and to keep it enabled.