В /proc/<PID>/limits у каждого лимита два столбца: Soft Limit и Hard Limit.
Мягкий лимит действует сейчас: на нём процесс и получает EMFILE. Жёсткий — потолок для мягкого. Свой мягкий лимит процесс поднимает сам, но не выше жёсткого. Жёсткий он может только опустить, а поднимает его root — и то не выше параметра ядра fs.nr_open.
У твоей оболочки эти лимиты разные:
Мягкий — 1024, жёсткий — в сотни раз больше. Программы, которым нужно много файлов, при старте сами поднимают мягкий лимит до жёсткого. У сборщика оба — 64, и поднимать ему некуда.
ulimit -n 4096 без ключа меняет оба лимита сразу, и поднять жёсткий обратно эта оболочка уже не сможет. Мягкий отдельно меняет ulimit -Sn 4096.
Мягкий лимит твоей оболочки — 1024. Ты набрал ulimit -Hn 2048, а потом ulimit -Hn 4096. Что напечатает оболочка на вторую команду?
-
Invalid argument оболочка отвечает, когда жёсткий ставят ниже мягкого. 4096 выше мягких 1024, а отказ здесь — в праве поднимать жёсткий.
-
Опустить жёсткий лимит может любой процесс, а поднять — только root. После
ulimit -Hn 2048подъём до 4096 упирается в запрет.
Опустить жёсткий лимит процесс может сам, поднять обратно — нет, без root вторая команда получает Operation not permitted. Проверь в отдельной оболочке, чтобы не задеть свою: bash -c 'ulimit -Hn 2048; ulimit -Hn 4096'.
Главное в шаге
- Мягкий лимит действует сейчас, жёсткий — потолок для мягкого.
- Мягкий процесс поднимает сам до жёсткого; жёсткий поднимает только root.
-
ulimit -nс числом меняет оба лимита,ulimit -Sn— только мягкий.