Po ostatnim uaktualnieniu do Fedory 15 stwierdzam, że wiele narzędzi nie działa z błędami w następujący sposób:
tail: inotify resources exhausted
tail: inotify cannot be used, reverting to polling
To nie tylko tail
zgłaszanie problemów z inotify. Czy jest jakiś sposób na przesłuchanie jądra, aby dowiedzieć się, jaki proces lub procesy zużywają zasoby inotify? Obecne sysctl
ustawienia związane z inotify wyglądają tak:
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
Prawdopodobnie zabrakło Ci raczej inotify zegarków niż instancji. Aby dowiedzieć się, kto tworzy wiele zegarków:
echo 1 >> /sys/kernel/debug/tracing/events/syscalls/sys_exit_inotify_add_watch/enable
aby umożliwić śledzenie dodawania zegarka;cat /sys/kernel/debug/tracing/tracing_enabled
, aby upewnić się, że jest on ustawiony na 1, a jeżeli nie jest to zrobićecho 1 >> /sys/kernel/debug/tracing/tracing_enabled
;/sys/kernel/debug/tracing/trace
aby zobaczyć, ile zegarków zostało utworzonych i według których procesów.Kiedy skończysz, upewnij się, że echo 0 w pliku włączania (i pliku śledzenia_włączonego, jeśli musiałeś również to włączyć), aby wyłączyć śledzenie, aby nie ponieść wydajności w wyniku kontynuowania śledzenia.
źródło
echo 1 | sudo tee /sys/kernel/debug/tracing/tracing_on
na nowoczesnych dystrybucjach (Ubuntu 18.04.2 LTS).Jak powiedział @Jonathan Kamens, prawdopodobnie kończy Ci się zegarki. Mam predefiniowanych skryptów ,
inotify-consumers
, który wymienia to dla ciebie:Tutaj szybko widać, dlaczego domyślny limit obserwatorów 8K jest zbyt mały na maszynie programistycznej, ponieważ tylko instancja WebStorm szybko to zwiększa, gdy napotyka
node_modules
folder z tysiącami folderów. Dodaj obserwatora pakietu internetowego, aby zagwarantować problemy ...Po prostu skopiuj zawartość skryptu (lub pliku na GitHub) i umieść go gdzieś w twoim
$PATH
, jak/usr/local/bin
. Dla porównania, główna treść skryptu jest po prostu takaJeśli zastanawiasz się, jak zwiększyć limity, możesz to zrobić na stałe:
źródło
Natknąłem się na ten problem i żadna z tych odpowiedzi nie daje odpowiedzi „ile zegarków obecnie używa każdy proces?” Wszystkie linijki pokazują, ile instancji jest otwartych, co jest tylko częścią historii, a ślady są przydatne tylko do oglądania nowych zegarków.
TL; DR: Otrzymasz plik z listą otwartych
inotify
instancji i liczbą posiadanych zegarków , wraz z pidami i plikami binarnymi, które je zrodziły, posortowanymi w kolejności malejącej według liczby zegarków:To wielka kula bałaganu, więc oto jak się tam dostałem. Aby rozpocząć, uruchomiłem
tail
plik testowy i spojrzałem na otwarte fd:Tak więc 4 to fd, który chcemy zbadać. Zobaczmy, co w
fdinfo
tym jest:To wygląda jak wpis do zegarka na dole!
Spróbujmy czegoś z większą liczbą zegarków, tym razem z
inotifywait
narzędziem, po prostu oglądając wszystko, co jest w/tmp
:Aha! Więcej wpisów! Powinniśmy zatem mieć sześć rzeczy
/tmp
:Doskonały. Mój nowy
inotifywait
ma jeden wpis nafd
liście (to, co liczą inne tutaj jednowierszowe), ale sześć wpisów w swoimfdinfo
pliku. Możemy więc dowiedzieć się, ile zegarków używa dany FD dla danego procesu, sprawdzając jegofdinfo
plik. Teraz, aby połączyć to z niektórymi z powyższych, aby pobrać listę procesów, które powiadomiły zegarki otwarte i użyj tego, aby policzyć wpisy w każdym z nichfdinfo
. Jest to podobne do powyższego, więc po prostu zrzucę tutaj linijkę:Jest tu trochę grubych rzeczy, ale podstawy są takie, że używam
awk
do budowaniafdinfo
ścieżki z danychlsof
wyjściowych, chwytając numer pid i fd, usuwając z niego flagę u / r / w. Następnie dla każdej skonstruowanejfdinfo
ścieżki liczę liczbęinotify
wierszy i wyprowadzam liczbę i pid.Byłoby miło, gdybym miał procesy, które te pidy reprezentują w tym samym miejscu, prawda? Tak myślałem. Tak więc, w szczególnie brudny bit, zdecydowałem się na wywołanie
dirname
dwukrotnie nafdinfo
drodze do uzyskania Pack/proc/<pid>
, dodając/exe
do niego, a następnie uruchomićreadlink
na to , aby uzyskać nazwę exe procesu. Wrzuć to tam, posortuj według liczby zegarków i przekieruj do pliku w celu bezpiecznego przechowywania, a otrzymamy:Działając bez sudo, aby pokazać moje procesy, które uruchomiłem powyżej, otrzymuję:
Doskonały! Lista procesów, fd i liczba używanych zegarków , dokładnie tego potrzebowałem.
źródło
lsof
z tego celu, polecam używanie-nP
flag, aby uniknąć niepotrzebnego wyszukiwania odwrotnego DNS i nazw portów. W tym konkretnym przypadku-bw
zalecane jest również dodanie, aby uniknąć potencjalnego blokowania wywołań systemowych. To powiedziawszy, zlsof
pożeraniem 3 sekund zegara ściennego na mojej skromnej stacji roboczej (z czego 2 sekundy spędzam w jądrze), takie podejście jest dobre do eksploracji, ale niestety nieodpowiednie do celów monitorowania.lsof | awk '/a_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | sed 's/fdinfo.*//' | sort | uniq > uniq-o
następniecat 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
Aby śledzić, które procesy zużywają zegarki inotify (nie instancje), możesz użyć funkcji dynamicznego ftrace jądra, jeśli jest ono włączone w jądrze.
Potrzebna jest opcja jądra
CONFIG_DYNAMIC_FTRACE
.Najpierw podłącz system plików debugfs, jeśli nie jest jeszcze zamontowany.
Przejdź do
tracing
podkatalogu tego katalogu debugfsWłącz śledzenie wywołań funkcji
Filtruj tylko
SyS_inotify_add_watch
wywołania systemoweWyczyść bufor pierścienia śledzenia, jeśli nie był pusty
Włącz śledzenie, jeśli nie jest jeszcze włączone
Uruchom ponownie podejrzany proces (w moim przypadku był to plan awaryjny, aplikacja do tworzenia kopii zapasowych)
Zobacz wyczerpanie inotify_watch
Gotowy
źródło
źródło
Zmodyfikowałem skrypt obecny powyżej, aby wyświetlić listę procesów, które zużywają zasoby inotify :
Myślę, że istnieje sposób na zastąpienie mojego podwójnego seda .
Tak. Użyj albo
lub
a dostaniesz tylko pid.
Ponadto, jeśli dodasz
w znalezieniu pozbędziesz się wszelkich irytujących linii błędów wyrzucanych przez find. To by działało:
źródło