Назад | Перейти на главную страницу

Где установлены ограничения по умолчанию в OS X (10.5)?

По умолчанию nofile ограничение для учетных записей пользователей OS X в наши дни составляет около 256 файловых дескрипторов. Я пытаюсь протестировать какое-то программное обеспечение, которому требуется гораздо больше подключений, чем открыто одновременно.

В типичном компьютере Debian с модулем ограничений pam я бы отредактировал /etc/security/limits.conf чтобы установить более высокие ограничения для пользователя, который будет запускать программное обеспечение, но я не понимаю, где установить эти ограничения в OS X.

Для этого есть графический интерфейс? Для этого есть где-нибудь файл конфигурации? Какой самый простой способ изменить ограничения по умолчанию в OS X?

В Leopard начальный процесс launchd. Улимиты по умолчанию для каждого процесса наследуются от 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 уже запустил вашу оболочку входа в систему, поэтому самый простой способ заставить эти изменения вступить в силу - перезапустить нашу машину. (Используйте >> для добавления в /etc/launchd.conf.)

Пределы оболочки

Ресурсы, доступные оболочке и процессам, могут быть изменены с помощью ulimit команда, которую можно добавить в сценарии запуска, такие как ~/.bashrc или ~/.bash_profile для индивидуальных пользователей или /etc/bashrc для всех пользователей. Пример строки для добавления:

ulimit -Sn 4096 && ulimit -Sl unlimited

Видеть: help ulimit и man 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.

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

не работает, потому что sudo находится не в том месте, попробуйте следующее:

echo 'limit maxfiles 10000 unlimited' | sudo tee -a /etc/launchd.conf
% 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
%

Теперь мне нужно выяснить, почему существует 2 способа проверки / установки пределов ....


Хорошо - похоже ulimit и sysctl создают ложноположительное ощущение, что они действительно что-то делают, но вместо этого они кажутся бесполезный. Может кто-нибудь это проверить?


Хорошо, я начинаю понимать. Начиная с версии 10.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 это встроенная оболочка, launchctl это программа, не зависящая от оболочки.

В OS X, если вы пытаетесь изменить мягкие ограничения для демона, процесса или задачи, правильный способ изменить эти мягкие ограничения не путем изменения конфигурации launchd по умолчанию для все процессов, но установив его для процесса, который вы пытаетесь запустить.

Это выполняется в вашем файле launchd .plist для вашего процесса.

Если у вас запущен демон или процесс, для которого нужно иметь больше открытых файлов, создайте для него файл plist и добавьте к нему следующие параметры:

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

Пример с использованием mongodb. Я создаю файл .plist с именем org.mongo.mongodb.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. В любом случае применяются разные правила для того, как launchd будет управлять вашим процессом. LaunchDaemons кажется зарезервированным для процессов, которые launchd всегда будет стараться не отставать.

Следующие действия должны разрешить большинство решений (и перечислены в порядке их иерархии):

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. maxfiles launchctl ограничены sysctl maxfiles и поэтому не могут превышать их
  4. sysctl, похоже, наследует kern.maxfilesperproc от launchctl maxfiles
  5. ulimit по умолчанию наследует значение open files от launchctl.
  6. вы можете установить собственный ulimit в / etc / profile или ~ / .profile; хотя это не обязательно, я привел пример
  7. Будьте осторожны при установке любого из этих значений на очень большое число по сравнению с их значениями по умолчанию - существуют функции стабильности / безопасности. Я взял эти цифры, которые я считаю разумными, написанные на других сайтах.
  8. Когда пределы launchctl ниже, чем ограничения sysctl, были сообщения о том, что соответствующие ограничения sysctl будут автоматически увеличены для удовлетворения требований.

Мой опыт показывает, что моя задача с большим количеством процессов была успешной только с:

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, я получал ошибку «сломанная труба».

Это было при запуске изрядного количества (500-4000) отдельных процессов на моем чудовищном Mac, OS 10.5.7, затем 10.5.8, теперь 10.6.1. Под Linux на компьютере моего начальства это просто работало.

Я думал, что количество процессов будет ближе к 1000, но похоже, что каждый процесс, который я запускал, включал свою собственную копию оболочки в дополнение к фактическому элементу, выполняющему фактическую работу. Очень празднично.

Я написал игрушку с дисплеем, которая выглядела примерно так:

#!/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 предметы в пике.

Прежде чем я поднял пределы, я мог «подкрасться» к порогу отказа, который вначале был ниже 1 КБ, но поднялся до высокого значения 1190 ... каждый раз, когда он был доведен до отказа, в следующий раз могло потребоваться немного больше, вероятно, из-за чего-то кэшируется, что увеличивается до предела каждый раз, когда он терпит неудачу.

Несмотря на то, что в моем тестовом примере в качестве окончательного утверждения было «ожидание», после его выхода все еще оставалось МНОЖЕСТВО отдельных процессов.

Большую часть информации я получил из сообщений в Интернете, но не вся она была точной. Ваш пробег может отличаться.