Me encontré con este problema, y ninguna de estas respuestas te da la respuesta de "¿cuántos relojes usa actualmente cada proceso?" Todas las frases te dan cuántas instancias están abiertas, lo cual es solo una parte de la historia, y las cosas de seguimiento solo son útiles para ver que se abren nuevos relojes.
TL; DR: Esto le dará un archivo con una lista de inotify
instancias abiertas y la cantidad de relojes que tienen, junto con las imágenes y binarios que los generaron, ordenados en orden descendente por conteo de relojes:
sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); exe=$(sudo readlink $(dirname $(dirname $fdi))/exe); echo -e $count"\t"$fdi"\t"$exe; done | sort -nr > watches
Esa es una gran bola de desastre, así que así es como llegué allí. Para comenzar, ejecuté un tail
archivo de prueba y miré los archivos que abrió:
joel@gladstone:~$ tail -f test > /dev/null &
[3] 22734
joel@opx1:~$ ls -ahltr /proc/22734/fd
total 0
dr-xr-xr-x 9 joel joel 0 Feb 22 22:34 ..
dr-x------ 2 joel joel 0 Feb 22 22:34 .
lr-x------ 1 joel joel 64 Feb 22 22:35 4 -> anon_inode:inotify
lr-x------ 1 joel joel 64 Feb 22 22:35 3 -> /home/joel/test
lrwx------ 1 joel joel 64 Feb 22 22:35 2 -> /dev/pts/2
l-wx------ 1 joel joel 64 Feb 22 22:35 1 -> /dev/null
lrwx------ 1 joel joel 64 Feb 22 22:35 0 -> /dev/pts/2
Entonces, 4 es el fd que queremos investigar. Veamos qué hay fdinfo
para eso:
joel@opx1:~$ cat /proc/22734/fdinfo/4
pos: 0
flags: 00
mnt_id: 11
inotify wd:1 ino:15f51d sdev:ca00003 mask:c06 ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:1df51500a75e538c
¡Parece una entrada para el reloj en la parte inferior!
Probemos algo con más relojes, esta vez con la inotifywait
utilidad, solo mirando lo que esté en /tmp
:
joel@gladstone:~$ inotifywait /tmp/* &
[4] 27862
joel@gladstone:~$ Setting up watches.
Watches established.
joel@gladstone:~$ ls -ahtlr /proc/27862/fd | grep inotify
lr-x------ 1 joel joel 64 Feb 22 22:41 3 -> anon_inode:inotify
joel@gladstone:~$ cat /proc/27862/fdinfo/3
pos: 0
flags: 00
mnt_id: 11
inotify wd:6 ino:7fdc sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:dc7f0000551e9d88
inotify wd:5 ino:7fcb sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:cb7f00005b1f9d88
inotify wd:4 ino:7fcc sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:cc7f00006a1d9d88
inotify wd:3 ino:7fc6 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:c67f00005d1d9d88
inotify wd:2 ino:7fc7 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:c77f0000461d9d88
inotify wd:1 ino:7fd7 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:d77f00000053c98b
¡Ajá! Más entradas! Entonces deberíamos tener seis cosas /tmp
:
joel@opx1:~$ ls /tmp/ | wc -l
6
Excelente. Mi nuevo inotifywait
tiene una entrada en su fd
lista (que es lo que cuentan las otras frases aquí), pero seis entradas en su fdinfo
archivo. Por lo tanto, podemos averiguar cuántos relojes está utilizando un fd determinado para un proceso determinado consultando su fdinfo
archivo. Ahora para unirlo con algunos de los anteriores para obtener una lista de procesos que tienen abiertos los relojes de notificación y usarlos para contar las entradas en cada uno fdinfo
. Esto es similar a lo anterior, así que simplemente volcaré la línea aquí:
sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); echo -e $count"\t"$fdi; done
Hay algunas cosas gruesas aquí, pero lo básico es que utilizo awk
para construir una fdinfo
ruta desde la lsof
salida, tomando el número pid y fd, quitando el indicador u / r / w de este último. Luego, para cada fdinfo
ruta construida , cuento el número de inotify
líneas y genero el recuento y el pid.
Sería bueno si tuviera qué procesos representan estos pids en el mismo lugar, ¿verdad? Ya me lo imaginaba. Así, en un poco desordenado en particular, que se establecieron en llamar dirname
dos veces en el fdinfo
camino para llegar al paquete /proc/<pid>
, añadiendo /exe
a ella, y luego ejecutando readlink
en que para obtener el nombre del exe del proceso. Agregue eso también, ordénelo por número de relojes y rediríjalo a un archivo para guardarlo y obtenemos:
sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); exe=$(sudo readlink $(dirname $(dirname $fdi))/exe); echo -e $count"\t"$fdi"\t"$exe; done | sort -n > watches
Al ejecutar eso sin sudo para mostrar solo mis procesos que inicié anteriormente, obtengo:
joel@gladstone:~$ cat watches
6 /proc/4906/fdinfo/3 /usr/bin/inotifywait
1 /proc/22734/fdinfo/4 /usr/bin/tail
¡Perfecto! Una lista de procesos, fd y cuántos relojes usa cada uno, que es exactamente lo que necesitaba.
find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print