Un beau matin on se lève, et tout est cassé ; le log de lighttpd est plein de :

(response.c.544) file not found ... or so: Too many open files
(mod_proxy.c.744) socket failed: Too many open files
(network_linux_sendfile.c.143) open failed: Too many open files
(response.c.544) file not found ... or so: Too many open files /favicon.ico ->

Tous ceux qui ont la joie de faire tourner des services populaires (ou des softs mals codés Undecided) sur leur machine ont un jour ou l'autre rencontré ce problème.

Pénurie de descripteurs de fichiers

Le système d'exploitation Linux se protège contre l'utilisation abusive des ressources en plaçant des limites. La limite peut être globale au système ou spécifique à un utilisateur. Les limites par défaut conviennent pour la plupart des machines. Cependant si vous hébergez des services gourmands, l'augmentation des valeurs par défaut peut s'avérer nécessaire (ou la ré-écriture du programme trop gourmand Laughing).

Limites du système : sysctl.conf

Jetons d'abord un coup d'oeil aux limites globales du système :

~$ cat /proc/sys/fs/file-nr
5504         0         206401
|          |           |
|          |           |
|          |          nombre total de descripteurs de fichier allouables
|          nombre de descripteurs de fichier disponibles (parmis ceux déjà alloués)
nombre de descripteurs de fichiers alloués (depuis le boot)

Les descripteurs de fichiers sont alloués de manière dynamique (on l'alloue pas le max dès le début). Le nombre de descripteurs de fichiers ouverts est = colonne 1 - colonne 2
Si ce nombre est élevé (proche de colonne 3), il faut augmenter la limite. Pour celà, ajoutez au fichier /etc/sysctl.conf :

fs.file-max = 131072

La modification sera appliquée à chaque démarrage du système. Pour l'appliquer immédiatement, faire :

~$ sysctl -p

L'application de la modification peut être directement consultée :

~$ cat /proc/sys/fs/file-max
131072

Limites par utilisateur : /etc/security/limits.conf

Il est également possible de fixer des limites par utilisateur. Dans le fichier /etc/security/limits.conf, ajoutez ces lignes (ici pour modifier le nombre de descripteurs de fichiers utilisables par www-data) :

www-data soft nofile 1024
www-data hard nofile 65535

Ces limites sont normalement utilisées par PAM. Elles prennent donc effet au prochain login de l'utilisateur ou à la prochaine execution d'une tâche en cron.Pour s'en assurer, vérifiez que le moduel pam_limits est requis dans le fichier /etc/pam.d/cron ; il devrait contenir :

# Sets up user limits, please define limits for cron tasks
# through /etc/security/limits.conf
session    required   pam_limits.so

Attention ! Les services lancés au démarrage ne peuvent bénéficier de ces limitations puisque c'est root qui change d'identité pour lancer le service. Il n'y a pas de connexion de l'utilisateur, PAM ne rentre pas en jeu.

Limites dans Lighttpd : server.max-fds

Pour éviter la solution extrême qui consiste à editer les scripts de /etc/init.d/ pour y ajouter des commandes ulimit, certains serveurs comme Lighttpd permettent de modifier le nombre maximal de descripteurs de fichiers utilisables. Ajoutez la ligne suivante dans la configuration de lighttpd :

server.max-fds = 65535