Encontrei esse problema e nenhuma dessas respostas fornece a resposta "quantos relógios cada processo está usando atualmente?" Todos os itens de uma linha fornecem quantas instâncias estão abertas, o que é apenas parte da história, e o material de rastreamento é útil apenas para ver novos relógios sendo abertos.
TL; DR: você receberá um arquivo com uma lista de inotifyinstâncias abertas e o número de relógios que eles têm, juntamente com os pids e binários que os geraram, classificados em ordem decrescente pela contagem de visualizações:
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
É uma grande bagunça, então aqui está como cheguei lá. Para começar, eu corri um tailarquivo de teste e observei os arquivos abertos:
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
Então, 4 é o valor que queremos investigar. Vamos ver o que há fdinfopara isso:
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 uma entrada para o relógio na parte inferior!
Vamos tentar algo com mais relógios, desta vez com o inotifywaitutilitário, apenas observando o que estiver em /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
Aha! Mais entradas! Portanto, devemos ter seis coisas /tmp:
joel@opx1:~$ ls /tmp/ | wc -l
6
Excelente. Meu novo inotifywaittem uma entrada em sua fdlista (que é o que os outros itens aqui estão contando), mas seis entradas em seu fdinfoarquivo. Assim, podemos descobrir quantos relógios um determinado fd para um determinado processo está usando consultando seu fdinfoarquivo. Agora, junte-o a algumas das opções acima para obter uma lista de processos que notificaram a abertura de relógios e use isso para contar as entradas em cada um fdinfo. Isso é semelhante ao acima, então eu vou despejar o one-liner aqui:
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
Há algumas coisas grossas aqui, mas o básico é que eu uso awkpara criar um fdinfocaminho a partir da lsofsaída, pegando o número pid e fd, retirando a bandeira u / r / w do último. Então, para cada fdinfocaminho construído , conto o número de inotifylinhas e produzo a contagem e o pid.
Seria bom se eu tivesse quais processos esses pids representam no mesmo lugar, certo? Eu pensei assim. Assim, em um pouco particularmente confuso, eu estabeleci-me em chamar dirnameduas vezes no fdinfocaminho para chegar pack para /proc/<pid>, adicionando /exea ele, e depois correndo readlinkem que para obter o nome exe do processo. Jogue isso lá também, classifique-o pelo número de relógios e redirecione-o para um arquivo para proteção e obteremos:
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
Executando isso sem o sudo para apenas mostrar meus processos que iniciei acima, recebo:
joel@gladstone:~$ cat watches
6 /proc/4906/fdinfo/3 /usr/bin/inotifywait
1 /proc/22734/fdinfo/4 /usr/bin/tail
Perfeito! Uma lista de processos, fd's e quantos relógios cada um está usando, exatamente o que eu precisava.
find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print