Почему количество открытых файлов в Linux ограничено?

136

Прямо сейчас я знаю, как:

  • найти количество открытых файлов на процесс: ulimit -n
  • подсчитать все открытые файлы по всем процессам: lsof | wc -l
  • получить максимально допустимое количество открытых файлов: cat /proc/sys/fs/file-max

Мой вопрос: почему в Linux существует ограничение на количество открытых файлов?

xanpeng
источник
2
@ Роб немного погуглил и обнаружил, что это вилочная бомба , можно ли использовать ее для объяснения ограничения количества открытых файлов?
xanpeng
6
Что ж, ограничения процессов и файлов очень важны, поэтому такие вещи, как «бомбы», не разрушают сервер / компьютер для всех пользователей, только для пользователя, который делает это, и только временно. В противном случае кто-то на общем сервере может отключить бомбу и полностью уничтожить ее для всех пользователей, а не только для себя.
Роб
3
Хороший, суммирующий некоторые очень полезные команды! : +1:
Джошуа Пинтер
7
@Rob, вилочная бомба не имеет к этому никакого отношения, так как лимит файлов на процесс и каждый раз, когда вы форкаете, не открывает новый дескриптор файла.
Псуси

Ответы:

86

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

Как пользователь root вы можете изменить максимальное количество открытых файлов для каждого процесса (через ulimit -n) и для системы (например echo 800000 > /proc/sys/fs/file-max).

jofel
источник
21
Существует также причина безопасности: если бы не было ограничений, пользовательское программное обеспечение могло бы создавать файлы бесконечно, пока сервер не выйдет из строя.
Корен
15
@Coren Обсуждаемые здесь ограничения относятся только к числу обработчиков открытых файлов. Так как программа также может закрывать обработчики файлов, она может создавать столько файлов и сколько угодно больших размеров, пока все доступное дисковое пространство не будет заполнено. Чтобы предотвратить это, вы можете использовать дисковые квоты или отдельные разделы. Вы правы в том смысле, что одним из аспектов безопасности является предотвращение исчерпания ресурсов - и для этого существуют ограничения.
Джофель
1
@jofel Спасибо. Я предполагаю, что дескрипторы открытого файла представлены экземплярами struct file , и размер этой структуры довольно мал (уровень байтов), так что я могу установить /.../file-maxс довольно большим значением, если память не используется?
xanpeng
7
@xanpeng Я не эксперт по ядру, но, насколько я вижу, по умолчанию для file-maxразмера памяти, как представляется, делится на 10 КБ. Поскольку реальная память, используемая для обработчика файлов, должна быть намного меньше (размер struct fileплюс некоторая память, зависящая от драйвера), это кажется довольно консервативным ограничением.
Джофель
63

Обратите внимание, что lsof | wc -lсуммируется множество дублированных записей (разветвленные процессы могут использовать дескрипторы файлов и т. Д.). Это число может быть намного выше установленного предела /proc/sys/fs/file-max.

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

cat /proc/sys/fs/file-nr

Пример: этот сервер имеет 40096 из максимально 65536 открытых файлов, хотя lsof сообщает о гораздо большем числе:

# cat /proc/sys/fs/file-max
65536
# cat /proc/sys/fs/file-nr 
40096   0       65536
# lsof | wc -l
521504
grebneke
источник
1
Как lsofбудет сообщать о многих файлах дважды или более, например /dev/null, вы можете сделать лучший выбор с:lsof|awk '{print $9}'|sort|uniq|wc -l
Yvan
Вы можете использовать, lsof|awk '!a[$NF]++{c++}END{print c}'чтобы получить количество дубликатов открытых файлов.
П ....
18

Я думаю, что это в значительной степени по историческим причинам.

Дескриптор Unix файл представляет собой небольшое intзначение, возвращаемое функциями , как openи creat, и передается read, write, closeи так далее.

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

Более современные системы имеют более высокие пределы, но сохранили ту же общую схему, в основном из инерции.

Кит Томпсон
источник
1
20 был пределом Solaris для структур данных FILE на языке Си. Количество дескрипторов файлов всегда было больше.
Лотар
@ Лотар: Интересно. Интересно, почему границы будут отличаться. Учитывая filenoи fdopenфункции я бы ожидать , чтобы они были почти взаимозаменяемы.
Кит Томпсон
Unix-файл - это больше, чем просто возвращаемый дескриптор файла (int). Существуют дисковые буферы и блок управления файлом, который определяет текущее смещение файла, владельца файла, разрешения,
индекс
@ChuckCottrill: Да, конечно. Но большая часть этой информации должна храниться независимо от того, доступен ли файл через intдескриптор или FILE*. Если у вас будет открыто более 20 файлов open(), произойдет fdopen()сбой?
Кит Томпсон,