Nach einem kürzlich durchgeführten Upgrade auf Fedora 15 stelle ich fest, dass eine Reihe von Tools mit Fehlern wie den folgenden ausfällt:
tail: inotify resources exhausted
tail: inotify cannot be used, reverting to polling
Es ist auch nicht nur so, tail
dass Probleme mit inotify gemeldet werden. Gibt es eine Möglichkeit, den Kernel abzufragen, um herauszufinden, welche Prozesse die inotifizierten Ressourcen verbrauchen? Die aktuellen inotify-bezogenen sysctl
Einstellungen sehen folgendermaßen aus:
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 8192
fs.inotify.max_queued_events = 16384
find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print
find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -exec sh -c 'cat $(dirname {})/../cmdline; echo ""' \; 2>/dev/null
Wahrscheinlich gehen Ihnen nicht nur Instanzen, sondern auch inotify- Uhren aus . So finden Sie heraus, wer viele Uhren herstellt:
echo 1 >> /sys/kernel/debug/tracing/events/syscalls/sys_exit_inotify_add_watch/enable
Verfolgung der Uhr zu ermöglichen , ergänzt;cat /sys/kernel/debug/tracing/tracing_enabled
um sicherzustellen , dass es auf 1 gesetzt , und wenn es nicht tun wirdecho 1 >> /sys/kernel/debug/tracing/tracing_enabled
;/sys/kernel/debug/tracing/trace
, um zu sehen, wie viele Uhren erstellt werden und von welchen Prozessen.Wenn Sie fertig sind, stellen Sie sicher, dass Sie 0 in die Aktivierungsdatei (und die Datei "tracing_enabled", falls Sie diese ebenfalls aktivieren mussten) eingeben, um die Ablaufverfolgung zu deaktivieren, damit Sie nicht die Leistungseinbußen beim Fortsetzen der Ablaufverfolgung erleiden.
quelle
echo 1 | sudo tee /sys/kernel/debug/tracing/tracing_on
auf modernen Distributionen (Ubuntu 18.04.2 LTS) arbeiten.Wie @ Jonathan Kamens sagte, gehen Ihnen wahrscheinlich die Uhren aus. Ich habe einen vorgefertigten Skript ,
inotify-consumers
, dass die Listen dies für Sie:Hier sehen Sie schnell, warum die Standardbeschränkung von 8K-Beobachtern auf einem Entwicklungscomputer zu gering ist, da nur die WebStorm-Instanz diese schnell ausschöpft, wenn sie auf einen
node_modules
Ordner mit Tausenden von Ordnern stößt . Fügen Sie einen Webpack-Beobachter hinzu, um Probleme zu garantieren ...Kopieren Sie einfach den Inhalt des Skripts (oder die Datei auf GitHub) und legen Sie sie irgendwo in Ihrem
$PATH
, wie/usr/local/bin
. Als Referenz ist der Hauptinhalt des Skripts einfach diesWenn Sie sich fragen, wie Sie die Grenzwerte erhöhen können, gehen Sie wie folgt vor, um sie dauerhaft zu machen:
quelle
Ich bin auf dieses Problem gestoßen, und keine dieser Antworten gibt Ihnen die Antwort "Wie viele Uhren verwendet jeder Prozess derzeit?" Die Einzeiler geben an, wie viele Instanzen geöffnet sind, was nur ein Teil der Geschichte ist, und das Trace-Zeug ist nur nützlich, um zu sehen, wie neue Uhren geöffnet werden.
TL; DR: Hiermit erhalten Sie eine Datei mit einer Liste der offenen
inotify
Instanzen und der Anzahl der darin enthaltenen Überwachungen sowie den Pids und Binärdateien, die sie hervorgebracht haben, sortiert in absteigender Reihenfolge nach Anzahl der Überwachungen:Das ist eine große Sauerei, also bin ich hierher gekommen. Um zu beginnen, habe ich
tail
eine Testdatei ausgeführt und mir die FDS angesehen, die geöffnet wurden:Also, 4 ist der fd, den wir untersuchen wollen. Mal sehen was drin ist
fdinfo
:Das sieht aus wie ein Eintrag für die Uhr unten!
Versuchen wir etwas mit mehr Uhren, diesmal mit dem
inotifywait
Hilfsprogramm, und schauen uns an, was auch immer drin ist/tmp
:Aha! Weitere Einträge! Also sollten wir sechs Dinge in
/tmp
dann haben:Ausgezeichnet. Mein neuer
inotifywait
hat einen Eintrag in seinerfd
Liste (was die anderen Einzeiler hier zählen), aber sechs Einträge in seinerfdinfo
Datei. So können wir herausfinden, wie viele Uhren ein bestimmter FD für einen bestimmten Prozess verwendet, indem wir seinefdinfo
Datei konsultieren . Um es nun mit einigen der oben genannten zusammenzufassen, greifen Sie auf eine Liste der Prozesse zu, bei denen Benachrichtigungsüberwachungen geöffnet sind, und verwenden Sie diese, um die Einträge in den einzelnen zu zählenfdinfo
. Das ist ähnlich wie oben, also werde ich den Einzeiler hier einfach wegwerfen:Es gibt einige dicke Sachen hier, aber die Grundlagen sind, dass ich
awk
einenfdinfo
Pfad von derlsof
Ausgabe aufbaue, die pid- und fd-Nummer greife und das u / r / w-Flag von letzterer abziehe. Dannfdinfo
zähle ich für jeden konstruierten Pfad die Anzahl derinotify
Zeilen und gebe die Anzahl und die PID aus.Es wäre schön, wenn ich hätte, welche Prozesse diese Pids an der gleichen Stelle darstellen, nicht wahr? Ich dachte auch. Also, in einem besonders chaotisch Bit, ließ ich mich auf Aufruf
dirname
zweimal auf demfdinfo
Weg zu bekommen Pack/proc/<pid>
, das Hinzufügen/exe
zu, und dann laufenreadlink
auf , dass den exe - Namen des Prozesses zu erhalten. Werfen Sie das auch hinein, sortieren Sie es nach der Anzahl der Uhren und leiten Sie es zur sicheren Aufbewahrung in eine Datei um. Wir erhalten:Wenn ich das ohne sudo ausführe, um nur meine oben gestarteten Prozesse zu zeigen, erhalte ich:
Perfekt! Eine Liste von Prozessen, FDS und wie viele Uhren jeder verwendet, genau das, was ich brauchte.
quelle
lsof
für diesen Zweck würde ich empfehlen, die-nP
Flags zu verwenden, um unnötige Lookups von Reverse-DNS- und Portnamen zu vermeiden. In diesem speziellen Fall wird auch das Hinzufügen-bw
empfohlen, um ein potenzielles Blockieren von Systemaufrufen zu vermeiden. Das heißt, dalsof
ich auf meiner bescheidenen Workstation 3 Sekunden Zeit für die Wanduhr verschlungen habe (von denen 2 Sekunden im Kernel verbracht werden), ist dieser Ansatz gut für die Erkundung, aber leider ungeeignet für Überwachungszwecke.lsof | awk '/a_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | sed 's/fdinfo.*//' | sort | uniq > uniq-o
thencat uniq-o | while read fdi; do count=$(cat ${fdi}fdinfo/* | grep -c inotify 2>/dev/null); exe=$(readlink ${fdi}exe); echo -e $count"\t"${fdi}"\t"$exe; done > watches
Zu verfolgen , welche Prozesse inotify verbrauchen Uhren (keine Instanzen) können Sie die dynamische Ftrace Funktion des Kernels verwenden , wenn es in Ihrem Kernel aktiviert ist.
Die Kernel-Option, die Sie benötigen, ist
CONFIG_DYNAMIC_FTRACE
.Hängen Sie zuerst das debugfs-Dateisystem ein, falls es noch nicht angehängt ist.
Gehen Sie in das
tracing
Unterverzeichnis dieses debugfs-VerzeichnissesAktivieren Sie das Tracing von Funktionsaufrufen
Filtern Sie nur
SyS_inotify_add_watch
SystemaufrufeLöschen Sie den Trace-Ringpuffer, wenn er nicht leer war
Aktivieren Sie die Ablaufverfolgung, wenn sie noch nicht aktiviert ist
Starten Sie den verdächtigen Prozess neu (in meinem Fall war es Crashplan, eine Sicherungsanwendung)
Beobachten Sie, wie die inotify_watch erschöpft ist
Getan
quelle
quelle
Ich habe das Skript oben geändert, um die Liste der Prozesse anzuzeigen, die inotify- Ressourcen verbrauchen :
Ich denke, es gibt eine Möglichkeit, mein doppeltes Sed zu ersetzen .
Ja. Benutze das eine oder das andere
oder
und du bekommst nur die pid.
Auch wenn Sie hinzufügen
Im Fund werden Sie alle lästigen Fehlerzeilen los, die vom Fund geworfen werden. Das würde also funktionieren:
quelle