From: Greg Ercolano <erco@(email surpressed)>
Subject: [DEV/UNIX] How to change ulimits in perl submit scripts?
   Date: Sun, 27 Jan 2013 14:50:51 -0500
Msg# 2279
View Complete Thread (1 article) | All Threads
Last Next
> Some of our nuke renders open a /lot/ of files.. more than the default
> maximum open files on our linux system (which is 1024).
> We've modified the kernel and changed the user login shells to use 4096,
> but it seems our Rush renders aren't seeing this change.
>
> (1) Is there somewhere to change the ulimits in rush?
> (2) Is there a way to change the ulimit in the perl submit scripts?

	Taking this question first:

	> (1) Is there somewhere to change the ulimits in rush?

	Yes, you can add ulimit commands to the rush boot script.  Changes
	made there will run as root so as to avoid permission problems
        raising limits beyond defaults, and the settings will be inherited
        by the rush daemons and will affect all rush renders.

	Sounds like you'd want to use:	ulimit -n 4096
	..so just add that line to the Rush boot script.

        On linux, change both of these files:

                /etc/init.d/rush
                /usr/local/rush/etc/S99rush

        On Macs: change just this file:

                /usr/local/rush/etc/S99rush

        Add the ulimit command to this section (see "ADD THIS LINE"):

--- snip
        # Ensure rush bin directory is early in daemon's path
        PATH=${RUSH_DIR}/bin:$PATH; export PATH

        # Remove restrictive limits
        case "$OS" in
            Linux)
                ulimit -c unlimited
                ulimit -d unlimited
                ulimit -m unlimited
		ulimit -n 4096		# ADD THIS LINE
                ;;
--- snip

	Changes made here will ONLY affect rush renders,
	not other parts of the OS, and will run as root.

	Once you've made the change, restart the daemon:
		/usr/local/rush/etc/S99rush restart
	..and renders on that machine will begin using the new ulimit.

	To verify your change has taken effect, you could add a 'ulimit -a'
        command to the render script to print out the settings:

		system("ulimit -a");

	If you add that in the render script just before the renderer is invoked,
        the output will appear in the frame logs where you can easily view it.

    * * *

	Regarding question #2:

	> (2) Is there a way to change the ulimit in the perl submit scripts?

	In this case it probably wouldn't help, because renders run as normal
	users, and normal users can't raise ulimits beyond the default. 
        
        So if the submit scripts are picking up 1024 as the default max open
	files, the user won't have permission to raise it.

	It is true that the perl base language for some reason does /not/ include
        an interface to change the system resource limits.

	You use the perl module "BSD::Resource" to change ulimits using e.g.
        setrlimit() and getrlimit() function calls.

        If you don't have this module on your system (try 'man BSD::Resource';
        if the man page doesn't come up, it's not installed), then you can
        usually install it with apt-get or yum.  On my Centos system, I used:

			yum install perl-BSD-Resource

	It is likely different for other distros, but should be similar.
	Once that's installed, your perl script can use e.g.:

		use BSD::Resource;
		setrlimit(RLIMIT_NOFILE, 4096, 4096);   # raise hard+soft limit to 4096

	..but as I said, I don't think your script will have permission to
        do this, because non-root users can't raise this beyond the default.
	So you'll need to use the rush boot script mod (listed above in #1).

	As an aside: I've never heard /why/ the perl core doesn't include an
        API to adjust resource limits.. not that it would help us here, but
        it just seems weird.

	Bash uses "ulimit" to get/set these values, csh uses "limit", and in
	those shells these are 'internal' commands, so to see the docs for
	them, use 'man bash' or 'man csh' respectively, and search for those
	commands to see their syntax.

	In C the function calls are setrlimit(2) & getrlimit(2), and there's
	the concept of 'hard' and 'soft' limits.

	In the shells, these commands kinda /have to be/ internal commands
	(and not external commands in /bin) because as these limits are
	inherited from parent-to-child just like environment variables. A
	child process can't affect its parent, which is why these commands
	can't be external programs.


Last Next