wake-up-neo.com

Überprüfen Sie das offene FD-Limit für einen bestimmten Prozess unter Linux

Ich hatte kürzlich einen Linux-Prozess, der Dateideskriptoren "durchgesickert" hat: Er öffnete sie und schloss einige von ihnen nicht richtig.

Wenn ich dies überwacht hätte, könnte ich - im Voraus - feststellen, dass der Prozess an seine Grenzen stößt.

Gibt es eine gute Möglichkeit, das FD-Nutzungsverhältnis für einen bestimmten Prozess in einem Ubuntu-Linux-System mit Bash\Python zu überprüfen?

BEARBEITEN:

Jetzt kann ich überprüfen, wie viele offene Dateideskriptoren vorhanden sind. Ich muss nur wissen, wie viele Dateideskriptoren für einen Prozess zulässig sind . Einige Systeme (wie Amazon EC2) verfügen nicht über die Datei /proc/pid/limits.

Vielen Dank,

Udi

56
Adam Matan

Zähle die Einträge in /proc/<pid>/fd/. Die für den Prozess geltenden harten und weichen Grenzen finden Sie in /proc/<pid>/limits.

107
caf

Die einzigen vom Linux-Kernel bereitgestellten Schnittstellen zum Abrufen von Ressourcengrenzwerten sind getrlimit() und /proc/PID/limits . getrlimit() kann nur Ressourcenlimits des aufrufenden Prozesses erhalten. Mit /proc/pid/limits können Sie die Ressourcengrenzen jedes Prozesses mit derselben Benutzer-ID abrufen. Er ist unter RHEL 5.2, RHEL 4.7, Ubuntu 9.04 und jeder Distribution mit einem 2.6.24-Kernel verfügbar.

Wenn Sie ältere Linux-Systeme unterstützen müssen, müssen Sie den Prozess selbst aufrufen, um getrlimit() aufzurufen. Am einfachsten ist es natürlich, das Programm oder eine Bibliothek, die es verwendet, zu ändern. Wenn Sie das Programm ausführen, können Sie LD_PRELOAD verwenden, um Ihren eigenen Code in das Programm zu laden. Wenn dies nicht möglich ist, können Sie den Prozess mit gdb verknüpfen und den Aufruf innerhalb des Prozesses ausführen lassen. Sie können dasselbe auch selbst mit ptrace() machen, um sich an den Prozess zu binden, den Anruf in den Speicher einzufügen, usw. Dies ist jedoch sehr kompliziert, um richtig zu sein und wird nicht empfohlen.

Bei entsprechenden Privilegien würden die anderen Möglichkeiten, dies zu tun, darin bestehen, den Kernel-Speicher durchzusehen, ein Kernel-Modul zu laden oder den Kernel anderweitig zu ändern. Ich gehe jedoch davon aus, dass dies nicht in Frage kommt.

32
mark4o

Sie haben nach Bash/Python-Methoden gefragt. ulimit wäre der beste bash-Ansatz (kurz durch /proc/$pid/fd und ähnliches per Hand). Für Python können Sie das Ressourcenmodul verwenden.

import resource

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

(1024, 65536)

resource.getrlimit entspricht dem Aufruf getrlimit in einem C-Programm. Die Ergebnisse repräsentieren die aktuellen und maximalen Werte für die angeforderte Ressource. Im obigen Beispiel ist das aktuelle (weiche) Limit 1024. Die Werte sind heutzutage typische Werte für Linux-Systeme.

2
bwalton

Sie können versuchen, ein Skript zu schreiben, das regelmäßig lsof -p {PID} für die angegebene PID aufruft.

2
Victor Sorokin

so sehen Sie die 20 wichtigsten Dateihandles mit Prozessen:

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

die Ausgabe hat das Format Dateihandle count, pid, cmndline für den Prozess

beispielausgabe

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

Python-Wrapper mit dem ausgezeichneten psutil-Paket:

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

In CentOS 6 und darunter (alles, was GCC 3 verwendet) stellen Sie möglicherweise fest, dass das Problem durch Anpassen der Kernel-Grenzwerte nicht behoben wird. Dies liegt daran, dass es einen FD_SETSIZE - Wert gibt, der zur vom GCC verwendeten Kompilierungszeit festgelegt wird. Dazu müssen Sie den Wert erhöhen und den Prozess erneut kompilieren.

Möglicherweise stellen Sie fest, dass Sie Dateideskriptoren aufgrund von bekannten Problemen in libpthread verlieren, wenn Sie diese Bibliothek verwenden. Dieser Aufruf wurde in GCC in GCC 4/CentOS7/RHEL 7 integriert und scheint die Threading-Probleme behoben zu haben.

0
James Shewey