Linux ulimit command

init.d

The different implementations of init.d vary, but they have known drawbacks. For example, init.d starts everything sequentially. This means a new process has to wait if another has already started. This makes the startup process on multi-core machine slow. Another drawback related to our topic is that daemons started by init.d inherit OS limits from the root user. If a program needs to be run by another user, the switch needs to happen in the startup script itself. But the order of option files that such users read can be different, depending on if they are logged in via the ssh,  su or sudo commands.

Percona Server for MySQL

Before version 5.7, Percona Server for MySQL had a different startup sequence:

  1. <Perform another job>
  2. Start mysqld_safe as root and pass option —user=mysql to it: «${PERCONA_PREFIX}»binmysqld_safe>devnull2>&1&

With this sequence, you only need to set a hard limit for a mysql user in the file  etcsecuritylimits.conf, and mysqld_safe will do the rest.

In version 5.7, Percona Server for MySQL backported the startup sequence from MySQL Server. Since then, setting a hard limit on the number of open files for mysql users in  etcsecuritylimits.conf is not enough. You also need to have a row session required pam_limits.so in the file etcpam.dcommon-session. This is needed because the startup sequence for mysql users changed due to the design of   init.d.

BUGS top

       In older Linux kernels, the SIGXCPU and SIGKILL signals delivered
       when a process encountered the soft and hard RLIMIT_CPU limits were
       delivered one (CPU) second later than they should have been.  This
       was fixed in kernel 2.6.8.

       In 2.6.x kernels before 2.6.17, a RLIMIT_CPU limit of 0 is wrongly
       treated as "no limit" (like RLIM_INFINITY).  Since Linux 2.6.17,
       setting a limit of 0 does have an effect, but is actually treated as
       a limit of 1 second.

       A kernel bug means that RLIMIT_RTPRIO does not work in kernel 2.6.12;
       the problem is fixed in kernel 2.6.13.

       In kernel 2.6.12, there was an off-by-one mismatch between the
       priority ranges returned by getpriority(2) and RLIMIT_NICE.  This had
       the effect that the actual ceiling for the nice value was calculated
       as 19 - rlim_cur.  This was fixed in kernel 2.6.13.

       Since Linux 2.6.12, if a process reaches its soft RLIMIT_CPU limit
       and has a handler installed for SIGXCPU, then, in addition to
       invoking the signal handler, the kernel increases the soft limit by
       one second.  This behavior repeats if the process continues to
       consume CPU time, until the hard limit is reached, at which point the
       process is killed.  Other implementations do not change the
       RLIMIT_CPU soft limit in this manner, and the Linux behavior is
       probably not standards conformant; portable applications should avoid
       relying on this Linux-specific behavior.  The Linux-specific
       RLIMIT_RTTIME limit exhibits the same behavior when the soft limit is
       encountered.

       Kernels before 2.4.22 did not diagnose the error EINVAL for
       setrlimit() when rlim->rlim_cur was greater than rlim->rlim_max.

       Linux doesn't return an error when an attempt to set RLIMIT_CPU has
       failed, for compatibility reasons.

   Representation of "large" resource limit values on 32-bit platforms
       The glibc getrlimit() and setrlimit() wrapper functions use a 64-bit
       rlim_t data type, even on 32-bit platforms.  However, the rlim_t data
       type used in the getrlimit() and setrlimit() system calls is a
       (32-bit) unsigned long.  Furthermore, in Linux, the kernel represents
       resource limits on 32-bit platforms as unsigned long.  However, a
       32-bit data type is not wide enough.  The most pertinent limit here
       is RLIMIT_FSIZE, which specifies the maximum size to which a file can
       grow: to be useful, this limit must be represented using a type that
       is as wide as the type used to represent file offsets—that is, as
       wide as a 64-bit off_t (assuming a program compiled with
       _FILE_OFFSET_BITS=64).

       To work around this kernel limitation, if a program tried to set a
       resource limit to a value larger than can be represented in a 32-bit
       unsigned long, then the glibc setrlimit() wrapper function silently
       converted the limit value to RLIM_INFINITY.  In other words, the
       requested resource limit setting was silently ignored.

       Since version 2.13, glibc works around the limitations of the
       getrlimit() and setrlimit() system calls by implementing setrlimit()
       and getrlimit() as wrapper functions that call prlimit().

COLOPHON top

       This page is part of the util-linux (a random collection of Linux
       utilities) project.  Information about the project can be found at 
       ⟨https://www.kernel.org/pub/linux/utils/util-linux/⟩.  If you have a
       bug report for this manual page, send it to
       util-linux@vger.kernel.org.  This page was obtained from the
       project's upstream Git repository
       ⟨git://git.kernel.org/pub/scm/utils/util-linux/util-linux.git⟩ on
       2020-08-13.  (At that time, the date of the most recent commit that
       was found in the repository was 2020-08-12.)  If you discover any
       rendering problems in this HTML version of the page, or you believe
       there is a better or more up-to-date source for the page, or you have
       corrections or improvements to the information in this COLOPHON
       (which is not part of the original manual page), send a mail to
       man-pages@man7.org

util-linux                        July 2014                       PRLIMIT(1)

Pages that refer to this page:
getrlimit(2), 
prlimit(2), 
prlimit64(2), 
setrlimit(2), 
ugetrlimit(2), 
vlimit(3), 
cgroups(7)

ERRORS top

       EFAULT A pointer argument points to a location outside the accessible
              address space.

       EINVAL The value specified in resource is not valid; or, for
              setrlimit() or prlimit(): rlim->rlim_cur was greater than
              rlim->rlim_max.

       EPERM  An unprivileged process tried to raise the hard limit; the
              CAP_SYS_RESOURCE capability is required to do this.

       EPERM  The caller tried to increase the hard RLIMIT_NOFILE limit
              above the maximum defined by /proc/sys/fs/nr_open (see
              proc(5))

       EPERM  (prlimit()) The calling process did not have permission to set
              limits for the process specified by pid.

       ESRCH  Could not find a process with the ID specified in pid.

Using ulimit in Linux

Here’s the syntax for ulimit command:

Display all limits for any user

You can display all kind of limits for a specified user in this manner:

The flag will display all options and their configuration for your specific user name.

If you omit the user_name, it shows limits for you. Let me show you the limits set up for me by default:

Your default values may be different than mine, of course. This view displays a description, the assigned flag (that can be used for changing the limits), and the configuration.

Display Hard and Soft Limits

It is also possible to see either of these respective limits with a flag.

To display soft limits, use option -S:

To display hard limits, use option -H:

It is more useful to combine these with specific flags from above. So if you want to check the hard limit on the maximum number of user processes, you would type:

Change the limits (temporarily)

Now, let’s change that value to 31500 for demonstration purposes and check the hard limit again.

It is worth noting that any changes your priviliege allows you will only be temporarily written and affect your current shell.

To confirm this, I exited my shell and created a new terminal and got the original default value.

The next section shows how to make the changes permanent.

Making permanent changes to ulimit

As I mentioned in the beginning of the article, ulimit is governed by /etc/security/limits.conf. If you want to make any permanent changes to the ulimits of any user, you will have to make changes to the security file as root.

When editing you need to include these four elements:

Here is the text I appended to the file to set the hard limit on the number of processes for user christoper (i.e. my own account):

Keep in mind that it is a best practice not to enable the root account unless you are fully aware of the potential consequences. I’ve done this on a virtual machine so you don’t have to do it yourself.

As you can see, the limit for ‘christopher’ was changed to 20000.

How do you know what keyword to use for editing the /etc/security/limits.conf file? Well, here is a table that includes possible item keywords and their descriptions:

Item Keyword Description
core limits the core file size (KB)
data max data size (KB)
fsize maximum filesize (KB)
memlock max locked-in-memory address space (KB)
nofile max number of open file descriptors
rss max resident set size (KB)
stack max stack size (KB)
cpu max CPU time (MIN)
nproc max number of processes
as address space limit (KB)
maxlogins max number of logins for this user
maxsyslogins max number of logins on the system
priority the priority to run user process with
locks max number of file locks the user can hold
sigpending max number of pending signals
msgqueue – max memory used by POSIX message queues (bytes)
nice max nice priority allowed to raise to values:
rtprio max realtime priority
chroot change root to directory (Debian-specific)
Limit Type Description
hard hard limit
soft soft limit
both hard and soft limit

Change ulimit for groups

Changing a group policy is very similar to what you saw in the previous section but you will include an symbol before the name of the group.

Here’s an example where I set the maximum number of logins for the group student is 4 by editing the /etc/security/limits.conf file:

Conclusion

I hope you liked this quick primer on ulimit Linux command.

If you have any comments or questions, leave them below. If you have any suggestions for topics you’d like to see covered, feel free to leave those as well.

Как проверить все открытые файлы пользователем или процессом в Linux

В некоторых ситуациях на Linux могут возникать ошибки, связанные с превышением лимита использования файловых дескрипторов.
Эти лимиты накладываются как самим ядром Linux, так и его программными модулями, например PAM.

Лимит ядра Linux

Узнать текущее значение максимального количества файловых дескрипторов, определяемое ядром Linux можно командой:

# cat /proc/sys/fs/file-max

Этот лимит может быть изменён без перезагрузки системы (начинает действовать сразу и действует до перезагрузки):

# echo "1221724" > /proc/sys/fs/file-max

Чтобы требуемое значение использовалось постоянно, то есть действовало и после перезагрузки, его необходимо определить в конфиг.файле :

sysclt.conf
...
fs.file-max=1221724
...

Методика подсчёта открытых файлов

Для получения информации о количестве всех открытых файлов всеми процессами в Linux некоторые «знатоки» предлагают использовать команду типа

# lsof | wc -l

Однако такая команда показывает гораздо большее значение, чем всего открыто файлов в системе на данный момент на самом деле. Это связано с тем, что по несколько раз в подсчёт попадают одни и теже открытые файлы, используемые разными процессами.

Поэтому проще для получения общего числа открытых файлов использовать данные ядра Linux

# cat /proc/sys/fs/file-nr

Первое число — общее количество занятых/используемых на данный момент времени файловых дескрипторов.

Второе число — количество выделенных процессам, но не используемых в данный момент дескрипторов.

Третье число — максимальное количество открытых дескрипторов

Примеры получения данных

Получить список TOP-20 процессов с самым большим количеством открытых файловых дескрипторов:

# for x in `ps -eF| awk '{ print $2 }'`; \
 do echo `ls /proc/$x/fd 2> /dev/null | \
 wc -l` $x `cat /proc/$x/cmdline 2> /dev/null`; \
 done | sort -n -r | head -n 20

Подсчитать количество открытых файлов в разрезе процессов (в первой колонке будет выведен PID процесса, во второй количество открытых файлов этим процессом):

# ps aux | sed 1d | awk \
 '{print "fd_count=$(lsof -p " $2 " | wc -l) && echo " $2 " $fd_count"}' | \
 xargs -I {} bash -c {}

Посмотреть открытые файловые дескрипторы во всех процессах для отдельно взятого пользователя, например «apache»

# lsof -u apache

Подсчитать количество открытых файлов в каждом процессе для отдельно взятого пользователя:

# lsof -u apache | awk '{print $2}' | sort | uniq -c | sort -n

Тоже самое, только в реальном режиме времени:

# watch 'lsof -u vdsm | awk '\''{print $2}'\'' | sort | uniq -c | sort -n'

Посмотреть открыте файловые дескриптры для отдельно взятого процесса (по PID процесса):

# lsof -p 9189

Подсчитать количество файловых дескриптров для отдельно взятого процесса:

# lsof -p 9189 | wc -l

Дополнительные источники информации:

Блог Дениса Тулякова — Количество открытых файлов, сокетов

Проверено на следующих конфигурациях:

Версия ОС
Debian GNU/Linux 8.10 (jessie)

Автор первичной редакции:Алексей Максимов
Время публикации: 09.06.2018 11:18

Ошибка too many open files Linux

Дословно эта ошибка означает, что программа открыла слишком много файлов и больше ей открывать нельзя. В Linux установлены жёсткие ограничения на количество открываемых файлов для каждого процесса и пользователя.

Посмотреть, сколько файлов можно открыть в вашей файловой системе, можно, выполнив команду:

Посмотреть текущие ограничения количества открытых файлов для пользователя можно командой:

Утилита ulimit возвращает два вида ограничений — hard и soft. Ограничение soft вы можете менять в любую сторону, пока оно не превышает hard. Ограничение hard можно менять только в меньшую сторону от имени обычного пользователя. От имени суперпользователя можно менять оба вида ограничений так, как нужно. По умолчанию отображаются soft-ограничения:

Чтобы вывести hard, используйте опцию -H:

Вы можете изменить ограничение, просто передав в ulimit новое значение:

Но поскольку hard-ограничение составляет 4000, то установить лимит больше этого значения вы не сможете. Чтобы изменить настройки ограничений для пользователя на постоянной основе, нужно настроить файл /etc/security/limits.conf. Синтаксис у него такой:

имя_пользователя тип_ограничения название_ограничения значение

Вместо имени пользователя можно использовать звездочку, чтобы изменения применялись ко всем пользователям в системе. Тип ограничения может быть soft или hard. Название — в нашем случае нужно nofile. И последний пункт — нужное значение. Установим максимум — 1617596.

Нужно установить значение для soft и hard параметра, если вы хотите, чтобы изменения вступили в силу. Также убедитесь, что в файле /etc/pam.d/common-session есть такая строчка:

Если её нет, добавьте в конец. Она нужна, чтобы ваши ограничения загружались при авторизации пользователя.

Если вам нужно настроить ограничения только для определенного сервиса, например  Apache или Elasticsearch, то для этого не обязательно менять все настройки в системе. Вы можете сделать это с помощью systemctl. Просто выполните:

И добавьте в открывшейся файл такие строки:

Здесь мы устанавливаем максимально возможное ограничение как для hard- так и для soft-параметра. Дальше нужно закрыть этот файл и обновить конфигурацию сервисов:

Затем перезагрузить нужный сервис:

Убедится, что для вашего сервиса применились нужные ограничения, можно, открыв файл по пути /proc/pid_сервиса/limits. Сначала смотрим PID нужного нам сервиса:

Затем смотрим информацию:

Увеличить Max Open File Limit в Unix/Linux

Приведу команды на различные Unix/Linux ОС

Увеличить Max Open File Limit в Linux

Для начала проверим какой предел установлен в ОС:

# cat /proc/sys/fs/file-max

Увеличиваем данный предел  в Linux

Мы можем увеличить лимиты для открытых файлов:

  • Временно.
  • Постоянно.

-===ВРЕМЕННО===-

Если есть необходимость увеличить лимит временно (для тестирования, например), то можно это сделать так:

# sysctl -w fs.file-max=500000

Или:

# echo "500000" > /proc/sys/fs/file-max

Вот еще один пример:

# ulimit -n 65635

-===ПОСТОЯННО===-

Если есть необходимость увеличить лимит навсегда, то  можно это сделать так:

# vim /etc/sysctl.conf

fs.file-max = 500000

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

# sysctl -p

Настройка лимитов для каждого пользователя

# vim /etc/security/limits.conf

Добавляем параметры:

* hard nofile 500000
* soft nofile 500000
root hard nofile 500000
root soft nofile 500000

Проверка установленных лимитов

Используйте следующую команду, чтобы увидеть максимальное чисто для открытых файлов:

# cat /proc/sys/fs/file-max

Подключаемся от пользователя (у меня это nginx):

# su nginx

Проверяем параметры Hard лимитов:

# ulimit -Hn

В консоле, можно ввести данную команду (очень удобно отображает):

# for pid in `pidof nginx`; do echo "$(< /proc/$pid/cmdline)"; egrep 'files|Limit' /proc/$pid/limits; echo "Currently open files: $(ls -1 /proc/$pid/fd | wc -l)"; echo; done

Проверяем параметры лимитов Soft:

# ulimit -Sn

Увеличить Max Open File Limit в Mac OS X

Выполним проверку лимитов с помощью:

$ launchctl limit maxfiles

Где:

  • Первый аргумент — soft limit.
  • Второй аргумент — hard limit.

Можно прописать в файл:

# vim ~/.bash_profile

Следующее значение:

ulimit -n 65536 200000

Вот и все!

Увеличюем nginx worker_rlimit_nofile  в nginx ( на уровне Nginx)

В nginx также можно увеличить лимиты с директивой worker_rlimit_nofile, которая позволяет увеличить этот лимит, если это не хватает данного ресурса на лету на уровне процесса:

# vim /etc/nginx/nginx.conf

И прописываем (редактируем):

# set open fd limit to 30000
worker_rlimit_nofile 30000;

После чего, проверяем конфигурацию nginx и перезапускаем его:
Save and close the file. Reload nginx web server, enter:

# nginx -t && service nginx -s reload

ulimit в Kali Linux

Включение ограничений на основе PAM в Unix/Lixux

Для Debian/Ubuntu

Редактируем файл (Debian/Ubuntu):

# vim /etc/pam.d/common-session

Вставляем:

session    required   pam_limits.so

Открываем еще один файл:

# vim /etc/security/limits.conf

Прописываем лимиты:

* soft nofile 65536
* hard nofile 200000

Открываем:

# vim /etc/ssh/sshd_config

И, приводим к виду:

UseLogin yes

И выполняем рестарт:

# reboot

Для CentOS/RedHat/Fedora

Редактируем файл (Debian/Ubuntu):

# vim /etc/pam.d/login

Вставляем:

session    required   pam_limits.so

Открываем еще один файл:

# vim /etc/security/limits.conf

Прописываем лимиты:

* soft nofile 65536
* hard nofile 200000

Открываем:

# vim /etc/ssh/sshd_config

И, приводим к виду:

UseLogin yes

И выполняем рестарт:

# reboot

У меня все! Статья «Увеличить Max Open File Limit в Unix/Linux», завершено.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector