Pourquoi le nombre de fichiers ouverts est-il limité sous Linux?

136

En ce moment, je sais comment:

  • trouver la limite de fichiers ouverts par processus: ulimit -n
  • compter tous les fichiers ouverts par tous les processus: lsof | wc -l
  • obtenir le nombre maximum autorisé de fichiers ouverts: cat /proc/sys/fs/file-max

Ma question est la suivante: pourquoi existe-t-il une limite de fichiers ouverts dans Linux?

Xanpeng
la source
2
@Rob googlé un peu et trouver que c'est une bombe fourchette , peut-il être utilisé pour expliquer la limite de fichier ouvert?
xanpeng
6
Bien, les limites de processus et de fichiers sont importantes pour que des choses telles que les bombes à la fourche ne cassent pas un serveur / ordinateur pour tous les utilisateurs, seulement pour l'utilisateur qui le fait et seulement temporairement. Sinon, quelqu'un sur un serveur partagé pourrait déclencher une incursion en fourche et l'assommer complètement pour tous les utilisateurs, pas seulement eux-mêmes.
Rob
3
Un bel résumé de commandes très utiles! : +1:
Joshua Pinter
7
@Rob, une bombe fourchue n'a rien à voir avec celle-ci puisque la limite de fichier est définie par processus et qu'à chaque ouverture de fourchettes, elle n'ouvre pas un nouveau descripteur de fichier.
Psusi

Réponses:

86

La raison en est que le système d'exploitation a besoin de mémoire pour gérer chaque fichier ouvert, et la mémoire est une ressource limitée - en particulier sur les systèmes intégrés.

En tant qu'utilisateur root, vous pouvez modifier le nombre maximal de fichiers ouverts par processus (via ulimit -n) et par système (par exemple echo 800000 > /proc/sys/fs/file-max).

jofel
la source
21
Il y a aussi une raison de sécurité: s'il n'y avait pas de limite, un logiciel utilisateur pourrait créer des fichiers indéfiniment jusqu'à ce que le serveur tombe en panne.
Coren
15
@Coren Les limites discutées ici ne concernent que le nombre de gestionnaires de fichiers ouverts. Comme un programme peut également fermer les gestionnaires de fichiers, il peut créer autant de fichiers et aussi gros que souhaité, jusqu'à ce que tout l'espace disque disponible soit saturé. Pour éviter cela, vous pouvez utiliser des quotas de disque ou des partitions séparées. Vous êtes vrai en ce sens que l'un des aspects de la sécurité est d'empêcher l'épuisement des ressources - et pour cela, il y a des limites.
Jofel
1
@ jofel Merci. Je suppose que les descripteurs de fichiers ouverts sont représentés par des instances de fichier struct , et que la taille de cette structure est assez petite (niveau en octets), puis-je définir /.../file-maxune valeur assez grande tant que la mémoire n'est pas utilisée?
xanpeng
7
@ xanpeng Je ne suis pas un expert du noyau, mais autant que je sache, la valeur par défaut pour file-maxsemble être la taille de la RAM divisée par 10k. Comme la vraie mémoire utilisée par gestionnaire de fichiers devrait être beaucoup plus petite (taille de struct fileplus de la mémoire dépendante du pilote), cela semble être une limite assez conservatrice.
Jofel
63

Veuillez noter que lsof | wc -lrésume de nombreuses entrées dupliquées (les processus forkés peuvent partager des descripteurs de fichier, etc.). Ce nombre pourrait être beaucoup plus élevé que la limite fixée dans /proc/sys/fs/file-max.

Pour obtenir le nombre actuel de fichiers ouverts du point de vue du noyau Linux, procédez comme suit:

cat /proc/sys/fs/file-nr

Exemple: Ce serveur contient 40096 fichiers ouverts sur un maximum de 65 536 fichiers, bien que lsof en signale un nombre beaucoup plus important:

# cat /proc/sys/fs/file-max
65536
# cat /proc/sys/fs/file-nr 
40096   0       65536
# lsof | wc -l
521504
Grebneke
la source
1
Comme nous lsofallons signaler plusieurs fichiers deux fois ou plus, par exemple /dev/null, vous pouvez tenter votre chance avec:lsof|awk '{print $9}'|sort|uniq|wc -l
Yvan
vous pouvez utiliser lsof|awk '!a[$NF]++{c++}END{print c}'pour obtenir le nombre non dupliqué de fichiers ouverts.
P ....
18

Je pense que c'est en grande partie pour des raisons historiques.

Un descripteur de fichier Unix est une petite intvaleur, retournée par des fonctions telles que openet creat, et transmis à read, write, close, et ainsi de suite.

Au moins dans les premières versions d'Unix, un descripteur de fichier était simplement un index dans un tableau de structures de taille fixe par processus, chaque structure contenant des informations sur un fichier ouvert. Si je me souviens bien, certains des premiers systèmes limitaient la taille de ce tableau à une vingtaine.

Les systèmes plus modernes ont des limites plus élevées, mais ont conservé le même schéma général, en grande partie par inertie.

Keith Thompson
la source
1
20 était la limite Solaris pour les structures de données FILE en langage C. Le nombre de descripteurs de fichiers était toujours plus grand.
Lothar
@ Lothar: Intéressant. Je me demande pourquoi les limites seraient différentes. Étant donné les fonctions filenoet fdopen, je m'attendrais à ce qu'elles soient presque interchangeables.
Keith Thompson
Un fichier Unix est plus que le descripteur de fichier (int) renvoyé. Il existe des tampons de disque et un bloc de contrôle de fichier qui définit le décalage de fichier actuel, le propriétaire du fichier, les autorisations, l'inode, etc.
ChuckCottrill
@ChuckCottrill: Oui, bien sûr. Mais la plupart de ces informations doivent être stockées, qu’un fichier soit accessible via un intdescripteur ou un fichier FILE*. Si vous avez plus de 20 fichiers ouverts via open(), fdopen()échoueriez-vous?
Keith Thompson