OS X(10.5)上指定的默认ulimit在哪里?


26

nofile如今,OS X用户帐户的默认限制似乎约为256个文件描述符。我正在尝试测试比一次打开需要更多连接的软件。

在运行pam限制模块的典型Debian盒子上,我/etc/security/limits.conf将为要运行该软件的用户设置更高的限制,但是我对在OS X中设置这些限制的位置感到困惑。

是否在某个地方有GUI?是否在某处有配置文件?在OS X上更改默认ulimit的最简洁的方法是什么?



Answers:


27

在Leopard下,初始过程为launchd。每个进程的默认ulimit继承自launchd。作为参考,默认(编译)限制为

$ sudo launchctl limit
    cpu         unlimited      unlimited      
    filesize    unlimited      unlimited      
    data        6291456        unlimited      
    stack       8388608        67104768       
    core        0              unlimited      
    rss         unlimited      unlimited      
    memlock     unlimited      unlimited      
    maxproc     266            532            
    maxfiles    256            unlimited

要更改这些限制,请在上添加一行(您可能需要先创建文件)/etc/launchd.conf,参数与传递给launchctl命令的参数相同。例如

echo "limit maxfiles 1024 unlimited" | sudo tee -a /etc/launchd.conf

但是,launchd您的登录Shell已经启动,因此使这些更改生效的最简单方法是重新启动计算机。(使用>>附加到/etc/launchd.conf。)


2
您可以为此添加到官方文档的链接吗?
Glyph'1

7
杜德(Dude),如果任何地方都有记录,则不需要此页面
Dave Cheney 2010年

1
似乎不适用于Snow Leopard。
ismail

1
知道这和它有sysctl.maxfiles什么不同吗?(相关问题:apple.stackexchange.com/questions/33715/too-many-open-files
keflavich 2011年

2
较小的更正:您正在echosudo下运行,但是尝试将无特权的shell附加到文件中,该文件无权执行。试试吧echo "limit maxfiles 1024 unlimited" | sudo tee -a /etc/launchd.conf
Vineet

4
sudo echo "limit maxfiles 1024 unlimited" >> /etc/launchd.conf

由于sudo放置在错误的位置而无法正常工作,请尝试以下操作:

echo 'limit maxfiles 10000 unlimited' | sudo tee -a /etc/launchd.conf

3
作为您所参考答案的“建议编辑”,这可能会更好。
克里斯·约翰森

3

外壳极限

适用于shell和流程的资源可以通过改变ulimit它可以添加到启动脚本,如命令~/.bashrc~/.bash_profile为个别用户/etc/bashrc所有用户。添加示例行:

ulimit -Sn 4096 && ulimit -Sl unlimited

请参阅:help ulimitman bash了解更多信息。

系统限制

一般来说,系统的限制是由控制的launchd框架,并且可以通过改变launchctl命令,例如

launchctl limit maxfiles 10240 unlimited

为了使更改持久化,您需要在特定的“ 启动兼容”文件夹中创建一个属性列表文件,该文件夹充当启动代理。

这是创建此类启动文件的示例命令:

sudo /usr/libexec/PlistBuddy /Library/LaunchAgents/com.launchd.maxfiles.plist -c "add Label string com.launchd.maxfiles" -c "add ProgramArguments array" -c "add ProgramArguments: string launchctl" -c "add ProgramArguments: string limit" -c "add ProgramArguments: string maxfiles" -c "add ProgramArguments: string 10240" -c "add ProgramArguments: string unlimited" -c "add RunAtLoad bool true"

该文件将在系统启动时加载,但是要加载以手动运行:

sudo launchctl load /Library/LaunchAgents/com.launchd.maxfiles.plist

要验证当前限制,请运行:launchctl limit

请参阅:创建启动守护程序和代理

内核限制

  • 内核限制由sysctl命令控制。
  • 要查看当前的内核限制,请运行:sysctl -a | grep ^kern.max
  • 要更改允许打开的最大文件数,请运行:sudo sysctl -w kern.maxfiles=20480
  • 若要使更改持久,请使用上述类似方法在系统启动文件夹中创建属性列表文件。

有关:


不推荐使用的方法

在早期版本的macOS中,您可以/etc/sysctl.conf像在Unix上一样在系统范围内设置这些限制,但是似乎不支持此限制。

使用~/.launchd.conf/etc/launchd.conf似乎在任何现有的macOS版本中也不支持它。维基

/etc/rc.local启动文件相同,在macOS上不支持。


2
% ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) 6144
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 2560
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 266
virtual memory          (kbytes, -v) unlimited
%

现在,我必须找出为什么存在两种检查/设置极限的方法。


好的-似乎ulimitsysctl给人一种错误肯定的感觉,他们实际上在做某事-但相反,它们似乎毫无用处。有人可以验证吗?


好的,我开始理解。从v10.4开始,init不再有进程,它已由替换launchd,该进程也以PID为1运行。

% ps -fu root
  UID   PID  PPID   C     STIME TTY           TIME CMD
    0     1     0   0   0:30.72 ??         0:46.72 /sbin/launchd

当然值得一提的是,它ulimit是内置的shell,launchctl是独立于shell的程序。


2

在OS X上,如果您尝试修改守护程序,进程或任务的软限制,则更改这些软限制的正确方法不是通过更改所有进程的默认启动配置,而是通过为进程设置它试图运行。

这是在您启动的过程的.plist文件中完成的。

如果您正在运行的守护程序或进程需要更多的打开文件,请为其创建一个plist文件并向其中添加以下参数:

    <key>SoftResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>1024</integer>
    </dict>

一个使用mongodb的示例。我创建了一个名为org.mongo.mongodb.plist的.plist文件,并将其保存到/Library/LaunchDaemons/org.mongo.mongodb.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>Disabled</key>
  <false/>
  <key>Label</key>
  <string>org.mongo.mongod</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/lib/mongodb/bin/mongod</string>
    <string>--dbpath</string>
    <string>/Users/Shared/mongodata/</string>
    <string>--logpath</string>
    <string>/var/log/mongodb.log</string>
  </array>
  <key>QueueDirectories</key>
  <array/>
  <key>RunAtLoad</key>
  <true/>
  <key>UserName</key>
  <string>daemon</string>
  <key>SoftResourceLimits</key>
  <dict>
    <key>NumberOfFiles</key>
    <integer>1024</integer>
    <key>NumberOfProcesses</key>
    <integer>512</integer>
  </dict>
</dict>
</plist>

现在,您的流程拥有了所需的资源,而无需考虑系统的全局配置。这将在重启时自动设置。或者,如果您不想重新启动,则可以运行

sudo launchctl load /Library/LaunchDaemons/org.mongod.plist

如果您的流程或任务不是守护程序而是守护程序,则可以将.plist放在/ Library / LaunchAgents中。在这两种情况下,启动如何控制流程的规则都不同。LaunchDaemons似乎保留给已启动的进程,这些进程将始终尝试保持同步。


1

以下应解决大多数解决方案(并按其层次结构顺序列出):

echo 'kern.maxfiles=20480' | sudo tee -a /etc/sysctl.conf
echo -e 'limit maxfiles 8192 20480\nlimit maxproc 1000 2000' | sudo tee -a /etc/launchd.conf
echo 'ulimit -n 4096' | sudo tee -a /etc/profile

笔记:

  1. 您将需要重新启动才能使这些更改生效。
  2. AFAIK,您不能再在OS X下将限制设置为“无限”
  3. launchctl maxfile受sysctl maxfile限制,因此不能超过它们
  4. sysctl似乎从launchctl maxfiles继承了kern.maxfilesperproc
  5. 默认情况下,ulimit似乎从launchctl继承了它的“打开文件”值
  6. 您可以在/ etc / profile或〜/ .profile中设置自定义ulimit;虽然这不是必需的,但我提供了一个示例
  7. 与默认值相比,将这些值中的任何一个设置为非常高的值时都要小心-这些功能具有稳定性/安全性。我已经将这些我认为是合理的示例数字写在其他网站上。
  8. 有报告说,当launchctl限制低于sysctl限制时,相关的sysctl限制将自动提高以满足要求。

1

我的经验是,我的高进程数任务仅成功完成:

kern.maxproc=2500  # This is as big as I could set it.

kern.maxprocperuid=2048

ulimit -u 2048

/etc/sysctl.conf为了可靠的设置,前两个可以进入,而ulimit值可以进入launchd.conf。

由于tcp / ip是我正在做的事情的一部分,所以我也需要提高

kern.ipc.somaxconn=8192

从默认值128开始。

在增加流程限制之前,我遇到了“分叉”故障,资源不足。在增加kern.ipc.somaxconn之前,我遇到了“断管”错误。

这是在我的怪物Mac OS 10.5.7,然后是10.5.8,现在是10.6.1上运行相当数量的(500-4000)分离进程的时候。在老板电脑上的Linux下,它可以正常工作。

我以为进程的数量将接近1000,但似乎我开始的每个进程除了执行实际工作的实际项目外,还包括其自己的shell副本。非常喜庆。

我写了一个展示玩具,类似:

#!/bin/sh

while[ 1 ]

do

    n=netstat -an | wc -l

    nw=netstat -an | grep WAIT | wc -l

    p=ps -ef | wc -l

    psh=ps -ef | fgrep sh | wc -l

    echo "netstat: $n   wait: $nw      ps: $p   sh: $psh"

    sleep 0.5

done

并查看了ps -ef中最大的进程数,并在netstat中挂起等待TIME_WAIT到期...随着限制的提高,我看到了3500多个TIME_WAIT项目处于高峰。

在我提高极限之前,我可以先“了解”故障阈值,该阈值开始于1K以下,但后来升至1190的高值。每次将其推入故障状态时,下一次可能要花费更多时间,可能是由于某种原因每次失败都会缓存扩展到其限制。

尽管我的测试用例的最终陈述是“等待”,但退出后仍然有大量的独立流程挂起。

我从互联网上发布的信息中获得了大部分信息,但并非全部都是准确的。您的里程可能会有所不同。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.