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 inotifyinstancias 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 tailarchivo 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 fdinfopara 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 inotifywaitutilidad, 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 inotifywaittiene una entrada en su fdlista (que es lo que cuentan las otras frases aquí), pero seis entradas en su fdinfoarchivo. Por lo tanto, podemos averiguar cuántos relojes está utilizando un fd determinado para un proceso determinado consultando su fdinfoarchivo. 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 awkpara construir una fdinforuta desde la lsofsalida, tomando el número pid y fd, quitando el indicador u / r / w de este último. Luego, para cada fdinforuta construida , cuento el número de inotifylí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 dirnamedos veces en el fdinfocamino para llegar al paquete /proc/<pid>, añadiendo /exea ella, y luego ejecutando readlinken 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