web-dev-qa-db-fra.com

Vérifier la limite FD ouverte pour un processus donné sous Linux

J'ai récemment eu un processus Linux qui "filtrait" des descripteurs de fichiers: il les ouvrait et ne fermait pas correctement certains d'entre eux.

Si j'avais surveillé cela, je pourrais dire - à l'avance - que le processus atteignait ses limites.

Existe-t-il un moyen agréable, Bash\Python, de vérifier le taux d’utilisation FD pour un processus donné sur un système Linux Ubuntu?

MODIFIER:

Je sais maintenant comment vérifier combien de descripteurs de fichiers ouverts sont là; J'ai seulement besoin de savoir combien de descripteurs de fichiers sont autorisés pour un processus . Certains systèmes (comme Amazon EC2) n'ont pas le fichier /proc/pid/limits.

Merci,

Udi

56
Adam Matan

Comptez les entrées dans /proc/<pid>/fd/. Les limites strictes et souples applicables au processus se trouvent dans /proc/<pid>/limits.

107
caf

Les seules interfaces fournies par le noyau Linux pour obtenir des limites de ressources sont getrlimit() et /proc/PID/limits . getrlimit() ne peut obtenir que les limites de ressources du processus appelant. /proc/pid/limits vous permet d'obtenir les limites de ressources de tout processus avec le même ID utilisateur. Il est disponible sur RHEL 5.2, RHEL 4.7, Ubuntu 9.04 et sur toute distribution avec un noyau 2.6.24 ou ultérieur.

Si vous devez prendre en charge des systèmes Linux plus anciens, vous devrez alors appeler le processus lui-même pour appeler getrlimit(). Bien sûr, le moyen le plus simple de le faire est de modifier le programme ou une bibliothèque qu’il utilise. Si vous exécutez le programme, vous pouvez utiliser LD_PRELOAD pour charger votre propre code dans le programme. Si rien de tout cela n'est possible, vous pouvez vous connecter au processus avec gdb et le faire exécuter l'appel dans le processus. Vous pouvez également faire la même chose vous-même en utilisant ptrace() pour vous associer au processus, insérer l'appel dans sa mémoire, etc. Toutefois, cette opération est très compliquée et déconseillée.

Avec les privilèges appropriés, les autres moyens de le faire impliqueraient de consulter la mémoire du noyau, de charger un module du noyau ou de modifier le noyau, mais je suppose que cela est hors de question.

32
mark4o

Vous avez demandé des méthodes bash/python. ulimit serait la meilleure approche bash (à moins de munger /proc/$pid/fd et similaires à la main). Pour Python, vous pouvez utiliser le module de ressources.

import resource

print(resource.getrlimit(resource.RLIMIT_NOFILE))
$ python test.py

(1024, 65536)

resource.getrlimit correspond à l'appel getrlimit dans un programme C. Les résultats représentent les valeurs actuelles et maximales de la ressource demandée. Dans l'exemple ci-dessus, la limite actuelle (logicielle) est de 1024. Les valeurs par défaut sur les systèmes Linux sont typiques de nos jours.

2
bwalton

Vous pouvez essayer d'écrire un script qui appelle périodiquement lsof -p {PID} sur un pid donné.

2
Victor Sorokin

pour voir les 20 meilleurs descripteurs de fichiers utilisant des processus:

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

la sortie est au format nombre de descripteurs de fichier, pid, cmndline for process

exemple de sortie

701 1216 /sbin/rsyslogd-n-c5
169 11835 postgres: spaceuser spaceschema [local] idle
164 13621 postgres: spaceuser spaceschema [local] idle
161 13622 postgres: spaceuser spaceschema [local] idle
161 13618 postgres: spaceuser spaceschema [local] idle
1
johnjamesmiller

Enveloppe Python utilisant l'excellent paquet psutil:

import psutil

for p in psutil.process_iter(attrs=['pid', 'name', 'username', 'num_fds']):
    try:
        soft, hard = p.rlimit(psutil.RLIMIT_NOFILE)
        cur = p.info['num_fds']
        usage = int(cur / soft * 100)
        print('{:>2d}% {}/{}/{}'.format(
            usage,
            p.info['pid'],
            p.info['username'],
            p.info['name'],
            ))
    except psutil.NoSuchProcess:
        pass
0
Willem

Dans CentOS 6 et inférieur (tout ce qui utilise GCC 3), vous constaterez peut-être que l’ajustement des limites du noyau ne résout pas le problème. En effet, une valeur FD_SETSIZE est définie lors de la compilation et utilisée par GCC. Pour cela, vous devrez augmenter la valeur, puis recompiler le processus.

En outre, vous constaterez peut-être une fuite de descripteurs de fichiers en raison de problèmes connus dans libpthread si vous utilisez cette bibliothèque. Cet appel a été intégré à GCC dans GCC 4/CentOS7/RHEL 7, ce qui semble avoir résolu le problème de threading.

0
James Shewey