Updates
  • 7/09/2005 - If you are running OS X 10.4, check out this other solution, it is much easier!
  • 1/10/2003 - I just noticed when you upgrade to say 10.3.2 with Software Update it overwrites your WindowServer wrapper. After a major upgrade you'll have to check and reapply the wrapper if WindowServer was replaced. Also David Brown pointed out that the correct syntax for passing command line arguments to WindowServer is "$*" not just $*, to handle spaces in arguments.

I work with Terminal a lot, and often have 30 to 40 windows open, each running my shell and ssh. Add in all the other processes, and I quickly exceed the 100 maxprocperuid limit that OS X defaults to.

There have been many proposed solutions to this. You can for instance in your shell startup scripts override the limit for that shell instance, and you can run more than 100 processes from that shell, but when you launch a new window, the parent process that launches all apps for you in the GUI is still limited to that 100 process per user limit, and the new window will fail to launch your shell. Usually with the error: login: fork: Resource temporarily unavailable.

There are thre phases to fixing this problem. First you must change the over all OS limits for maxproc and maxprocperuid to higher values, change the environment daemons get started up under via rc.common, and then you must make WindowServer run in an environment with the limits raised.

System Wide
OS X 10.3 now supports the standard /etc/sysctl.conf. This means you can just put new values into this file and reboot.

>cat /etc/sysctl.conf
# Turn up maxproc
kern.maxproc=2048
# Turn up the maxproc per user
kern.maxprocperuid=512

Daemons /etc/rc.common
All of the daemons that are started via /System/Library/StartupItems are started with the default maxproxperuid of 100. This might not normally be a problem as root may not run a ton of processes, but it does matter when sshd is started up. On OS X sshd is started out of xinetd. A quick way to affect the environment of xinetd and all other daemons as well, is to put ulimit -u 512 at the top of /etc/rc.common. If you preferred, you could just edit the startup script for xinetd instead which is /System/Library/StartupItems/IPServices/IPServices

Here is a snippet of the top of my /etc/rc.common file:

#######################
# Configure the shell #
#######################

ulimit -u 512

##
# Be strict
##

WindowServer
Every process you run from the GUI is launched by WindowServer. So we need to make WindowServer launch in such a way that it has its limits raised. I cannot determine what actually launched WindowServer. Its parent process is mach_init, and I can find no way to modify how it is launched directly.

You can however write a wrapper script for WindowServer. A shell script that is launched instead of WindowServer it self, that sets the limits properly, then launches the original WindowServer as normal.

  1. Become root on command line.
  2. cd /System/Library/Frameworks/ApplicationServices.framework/\
    Frameworks/CoreGraphics.framework/Resources/
  3. mv WindowServer WindowServer.orig
  4. vi WindowServer
    Below is the script I used
    #!/bin/zsh
    ulimit -u 384
    /System/Library/Frameworks/ApplicationServices.framework/\
    Frameworks/CoreGraphics.framework/Resources/WindowServer.orig "$*"
  5. chmod a+rx WindowServer
  6. reboot
How I Tested
To quickly test if my solution was working I ran a bunch of sleep processes in the background. This was able to reproduce the problem for me on demand before the fix. I'd open one shell window, launch over 100 sleeps, and then try to launch a new Terminal window, and it would fail.
Categories: OS X Tips
Posted: November 15, 2003 11:11 AM | Perm Link
 
This is a Flickr badge showing public photos from pdm tagged with badge. Make your own badge here.
  • Recent Interesting Links
  • The requested page could not be found.

    require_once(/home/realpdm/lib/php/magpierss/rss_fetch.inc) [<a href='function.require-once'>function.require-once</a>]: failed to open stream: No such file or directory