setrlimit(), setrlimit64()

Установить лимиты системных ресурсов

Прототип:

#include <sys/resource.h>
int setrlimit( int resource,
const struct rlimit *rlp );
int setrlimit64( int resource,
const struct rlimit64 *rlp );

Аргументы:

resource
Ресурс, для которого необходимо установить лимит (ограничение потребления). Описание механизма для получения списка возможных ресурсов, а также их описания и выполняемые при превышении текущего лимита действия, приведены ниже.
rlp
Указатель на структуры типа struct rlimit или struct rlimit64, определяющие лимиты, которые необходимо установить.

Библиотека:

libc

Описание:

Функция setrlimit() устанавливает лимиты различных системных ресурсов для процесса и для процессов, им создаваемых. Функция setrlimit64() является 64-разрядной версией функции setrlimit().

Каждый вызов setrlimit() определяет конкретный ресурс и лимит этого ресурса. Лимит ресурса представляет собой пару значений: одно из которых задает текущий (мягкий) лимит, а другое - максимальный (жесткий) лимит.

Процесс может изменить мягкий лимит ресурса на любое значение не большее, чем жесткий лимит. Также процесс может (необратимо) понизить свой жесткий лимит на любое значение не меньшее, чем жесткий лимит. Устанавливать жесткий лимит может только процесс с эффективным идентификатором пользователя (user ID) соответствующим "суперпользователю". Как жесткие, так и мягкие лимиты могут быть изменены в одном вызове setrlimit() (учитывая описанные выше ограничения). Лимиты могут иметь специальное "бесконечное" значение RLIM_INFINITY.


Note: RLIM_INFINITY - это специальное значение, фактическое число которого нельзя рассматривать как реальный допустимый размер виртуальной памяти или адресного пространства.

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

Ресурс Опсиание Действие
RLIMIT_AS (POSIX) Максимальный размер в байтах для отображаемого адресного пространства процесса. Если лимит превышен, функции brk(), mmap() и sbrk() завершаются с ошибкой, а переменная errno устанавливается в значение ENOMEM. Кроме того, ошибкой завершается автоматический рост стека.
RLIMIT_CORE (POSIX) Максимальный размер в байтах для аварийного дампа (core файла), который процесс может создать. Значение лимита равное 0 предотвращает создание аварийного дампа. Запись аварийного дампа прекращается при достижении этого размера.
RLIMIT_CPU (POSIX) Максимальное количество процессорного времени в секундах, которое может использовать процесс. Этот лимит может быть только мягким. Процессу направляется сигнал SIGXCPU. Если процесс удерживает или игнорирует сигнал SIGXCPU, то поведение определяется дисциплиной диспетчеризации.
RLIMIT_DATA (POSIX) Максимальный размер в байтах кучи для процесса. В ЗОСРВ «Нейтрино» значение RLIMIT_DATA охватывает все выделения памяти с типом MAP_ANON | MAP_PRIVATE, но не типа MAP_STACK, которые обычно соответствуют выделениям памяти для кучи. Если лимит превышен, функции brk(), mmap() и sbrk() завершаются с ошибкой, а переменная errno устанавливается в значение ENOMEM.
RLIMIT_FSIZE (POSIX) Максимальный размер в байтах для файла, который процесс может создать. Значение лимита равное 0 предотвращает создание файла. Процессу направляется сигнал SIGXFSZ. Если процесс удерживает или игнорирует сигнал SIGXFSZ, попытки увеличить размер файла сверх установленного лимита завершаются ошибкой, а переменная errno устанавливается в значение EFBIG.
RLIMIT_MEMLOCK Максимальное количество памяти, которое может быть заблокировано в физической памяти (это приводит к невозможности выгрузить такую память).
RLIMIT_NOFILE (POSIX) Значение на единицу большее максимального значения, которое система может присвоить вновь созданному дескриптору. Этот лимит ограничивает количество файловых дескрипторов, которые может создать процесс.
RLIMIT_NPROC Максимальное количество процессов. Попытки создать новые процессы будут завершаться с ошибкой.
RLIMIT_NTHR Максимальное количество потоков. Попытки создать новые потоки (например через вызов pthread_create() будут завершаться с ошибкой.
RLIMIT_OFILE Аналогичен RLIMIT_NOFILE.
RLIMIT_RSS Аналогичен RLIMIT_AS. Аналогично RLIMIT_AS.
RLIMIT_STACK (POSIX) Максимальный размер в байтах для стека процесса. Система не будет автоматически увеличивать стек сверх этого лимита.

Вызов setrlimit() внутри процесса увеличивает лимит на размер стека, но не перемещает текущие сегменты памяти для обеспечения этого роста. Для обеспечения увеличения стека до заданного лимита, лимит должен быть изменен до выполнения процесса, в котором будет использоваться новый размер стека.

В многопоточном процессе вызов setrlimit() не влияет на ограничение размера стека вызывающего потока, если этот поток не является основным потоком процесса. Вызов setrlimit() для лимита RLIMIT_STACK влияет только на стек основного потока и должен вызываться только из этого основного потока.

Процессу направляется сигнал SIGSEGV. Если процесс удерживает или игнорирует сигнал SIGSEGV, а так же, если он перехватывает сигнал SIGSEGV, но не использует альтернативный стек, то реакция на SIGSEGV перед его отправкой устанавливается в SIG_DFL.
RLIMIT_VMEM Аналогичен RLIMIT_AS. Аналогично RLIMIT_AS.

Поскольку информация о лимитах хранится в каждом процессе, то встроенная (builtin) команда оболочки ulimit (подробнее см. описание ksh) должна быть выполнена непосредственно, чтобы повлиять на все создаваемые оболочкой процессы.

Значения текущего лимита следующих ресурсов определены параметрами:

Ресурс Параметр
RLIMIT_FSIZE FCHR_MAX
RLIMIT_NOFILE OPEN_MAX

При использовании функции setrlimit() возможны несколько случаев. В случае, если запрашиваемое значение нового лимита равно RLIM_INFINITY, то новый лимит не будет установлен. В другом случае, если запрашиваемое значение равно RLIM_SAVED_MAX, то новым значением лимита станет сохраненный жесткий лимит. В другом случае, если запрашиваемое значение равно RLIM_SAVED_CUR, то новым значением лимита станет сохраненный мягкий лимит. В иных случаях новым значением лимита станет запрашиваемое значение. Кроме того, если соответствующий сохраненный лимит может быть корректно представлен в объекте типа rlim_t, то он перезаписывается новым значением.

Результат установки лимита в значение RLIM_SAVED_MAX или RLIM_SAVED_CUR будет определенным, только если предыдущий вызов getrlimit() вернул значение мягкого или жесткого лимита соответствующего ресурса.

Допустимо задавать значение лимита, превышающее число RLIM_INFINITY.

Семейство функций exec*() также приводит к сохранению лимитов на ресурсы.

Возвращаемое значение:

0
Успешное завершение.
-1
Возникла ошибка. Код ошибки записан в errno.

Коды ошибок:

EFAULT
Параметр rlp указывает на некорректный адрес.
EINVAL
Был указан некорректный ресурс, либо новое значение rlim_cur превышает новое значение rlim_max, либо указанный лимит не может быть снижен, поскольку текущее использование ресурса уже превышает этот лимит.
EPERM
Указанный лимит увеличил бы максимальное значение лимита и вызывающий процесс не является суперпользователем.

Классификация:

setrlimit() — POSIX 1003.1 XSI; setrlimit64() — Поддержка больших файлов

Точка остановки потока
Нет
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Тематические ссылки:

rlim_t, rlim64_t, struct rlimit, struct rlimit64, brk(), execl(), execle(), execlp(), execlpe(), execv(), execve(), execvp(), execvpe(), fork(), getdtablesize(), getrlimit(), getrlimit64(), malloc(), mmap(), open(), sbrk(), signal(), sysconf()

ulimit встроенная команда оболочки (см. описание ksh в Справочнике по Утилитам)




Предыдущий раздел: Описание API системной библиотеки