Why does setting the hard-limit for maxfiles to "unlimited" using
launchctl limit
result in a hard-limit slightly above the soft-limit?
By setting the maxfiles limit using launchctl to launchctl limit maxfiles 10000 unlimited
, I get the following result:
nlykkei-mbp:~ nlykkei$ launchctl limit maxfiles
maxfiles 10000 10240
Initially, after the system has booted, hard-limit is set to "unlimited", so why can't I set the same hard-limit by setting it manually?
Best Answer
A fresh system install, with default parameters is configured with the following system wide file limits:
Current kernel sysctl parameters can be viewed with sysctl command:
Now let's check limits values, using ulimit command:
For SOFT limits: [we can see that: open files = 256]
For HARD limits: [we can see that: open files = Unlimited]
Using launchctl
launchctl has the capacity to configure limit values, or show current values.
Using
launchctl limit
it shows all the current Soft and Hard limits, and we can see that soft limit is 256 and hard limit is 'unlimited' for the item maxfiles. (the same information we got using ulimit command above)To filter, we can just use
launchctl limit maxfiles
Now let's try to change those values #
Using your command line as example:
sudo launchctl limit maxfiles 10000 unlimited
But after it, when I execute again the command to display the limits, we can see that:
And from now, it is impossible to get it back to unlimited!
We can see that after executing it, it also changed the kernel sysctl parameters
The reason is
But first, let see if we can use a bigger value like 2 million:
sudo launchctl limit maxfiles 10000 2000000
Yes, we can, it accepted the bigger value.
Why this happens
It is hardcoded on the source code to not accept 'unlimited' as a value, so once we changed it, we can never put it back.
But what is the value that corresponds to 'unlimited' ?
Let's go inside the source code #
This explains why it is impossible to set 'unlimited' again, after changing it for some other value.
How to do it? #
RLIM_INFINITY is defined on line 416 of
<sys/resources.h>
In practice, for the current platform, the unlimited INFINITY maximum value is limited to INT_MAX (which is the maximum value of the Integer Type)
Considering that, it means that 'unlimited' means INT_MAX, which is the value 2147483647.
A possible workaround may be set the limit value of 2147483647:
sudo launchctl limit maxfiles 2147483647 2147483647
Because this is the maximum possible value.
Since this is a possible workaround. I would have to go deeper into source to check if this really means 'the same thing' as 'unlimited'.
Warning:
PS: Please, don't set it bigger than 2147483647, because it is SIGNED INT, and if you put 2147483648 (notice the number eight, I just add +1 to that maximum value), the SIGNED INT will be interpreted as negative, and you will instantly almost crash your macOS, because it will not be able to open any other file descriptor, including the one you will need to revert this value back, if trying to adjust it again by executing
launchctl
with different parameters.The only solution will be to hard reset your system if you try this. And you may loose all your unsaved things. Try it on some MacOS virtual machine for testing purposes
Source code References:
<sys/resource.h>
https://opensource.apple.com/source/xnu/xnu-4903.221.2/bsd/sys/resource.h.auto.html<dev/unix_startup.c>
https://opensource.apple.com/source/xnu/xnu-4903.221.2/bsd/dev/unix_startup.c.auto.html<kern/kern_resource.c>
https://opensource.apple.com/source/xnu/xnu-4903.221.2/bsd/kern/kern_resource.c.auto.html<conf/param.c>
https://opensource.apple.com/source/xnu/xnu-4903.221.2/bsd/conf/param.c.auto.html<sys/syslimits.h>
https://opensource.apple.com/source/xnu/xnu-4903.221.2/bsd/sys/syslimits.h.auto.htmllaunchctl.c
https://opensource.apple.com/source/launchd/launchd-442.21/support/launchctl.c.auto.html