Кто использует мои inotify ресурсы?

Как насчет этого:

rsync -avn --include="*.pdf" ~/Latex/ ~/Output/
50
24.06.2011, 01:36
9 ответов

Кажется, что, если процесс создает inotify экземпляр через inotify_init (), получающийся файл, который представляет filedescriptor в/proc файловой системе, является символьной ссылкой на (несуществующий) 'anon_inode:inotify' файл.

$ cd /proc/5317/fd
$ ls -l
total 0
lrwx------ 1 puzel users 64 Jun 24 10:36 0 -> /dev/pts/25
lrwx------ 1 puzel users 64 Jun 24 10:36 1 -> /dev/pts/25
lrwx------ 1 puzel users 64 Jun 24 10:36 2 -> /dev/pts/25
lr-x------ 1 puzel users 64 Jun 24 10:36 3 -> anon_inode:inotify
lr-x------ 1 puzel users 64 Jun 24 10:36 4 -> anon_inode:inotify

Если я не неправильно понял понятие, следующая команда должна показать Вам список процессов (их представление в/proc), отсортированный по количеству inotify экземпляров, которые они используют.

$ for foo in /proc/*/fd/*; do readlink -f $foo; done | grep inotify | sort | uniq -c | sort -nr

Нахождение преступников

С помощью комментариев ниже @markkcowan упомянул это:

$ find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -exec sh -c 'cat $(dirname {})/../cmdline; echo ""' \; 2>/dev/null
39
27.01.2020, 19:33
  • 1
    Превосходный, спасибо! Я не знал о inotify inodes обнаруживающийся в/proc. В моих целях команда может быть упрощена до этого: find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print –  larsks 25.06.2011, 15:29
  • 2
    я рад, что он помог. И Ваше решение с находкой-lname действительно намного более любезно, чем мое с для цикла и readlink. –  Petr Uzel 26.06.2011, 13:44
  • 3
    Обратите внимание, что Вы могли также быть вне часов (не экземпляры). Например, в моей системе, которая дает количество низких подростков экземпляров, но существует много десятков тысяч часов от поиска по компьютеру KDE. Его слишком плохим там не является более легкий способ проверить, сколько часов/экземпляров используется, так как ядро ясно знает... –  derobert 23.01.2013, 18:18
find /proc/*/fd/* -type l -lname 'anon_inode:inotify' 2>/dev/null | cut -f 1-4 -d'/' |  sort | uniq -c  | sort -nr
3
27.01.2020, 19:33

У Вас, вероятно, заканчиваются часы inotify, а не экземпляры. Для обнаружения, кто создает много часов:

  1. Позвольте проследить часов, добавляет:
$ echo 1 > /sys/kernel/debug/tracing/events/syscalls/sys_exit_inotify_add_watch/enable`
  1. Проверьте если tracing_on s к 1:
$ cat /sys/kernel/debug/tracing/tracing_on
0
$ echo 1 > /sys/kernel/debug/tracing/tracing_on
  1. Перезапустите процессы с inotify экземплярами (определенный, как описано в ответе Petr Uzel), что Вы подозреваете в создании большого количества часов; и
  2. Установка ftrace
$ cat /sys/kernel/debug/tracing/current_tracer
nop

$ cat /sys/kernel/debug/tracing/set_ftrace_filter
#### all functions enabled ####

$ echo function              > /sys/kernel/debug/tracing/current_tracer
$ echo SyS_inotify_add_watch > /sys/kernel/debug/tracing/set_ftrace_filter
  1. Считайте файл /sys/kernel/debug/tracing/trace смотреть, сколько часов создается и который процессы.

Когда Вы будете сделаны, удостоверьтесь, что echo 0 в разрешать файл (и tracing_on файл, если необходимо было включить это также) для выключения трассировки, таким образом, Вы не подвергнетесь хиту производительности продолжения проследить.

Примечание: В более старых версиях ядра Linux /sys конечная точка раньше называлась tracing_enabled, однако это теперь называют tracing_on. Если Вы находите, что находитесь на более старом выпуске изменения ядра /sys/kernel/debug/tracing/tracing_on кому: /sys/kernel/debug/tracing/tracing_enabled.

27
27.01.2020, 19:33
  • 1
    Это было приложение резервного копирования, создающее много часов inotify, и решение в принятом ответе помогло идентифицировать преступника. Однако я не был ранее знаком с трассировкой системного вызова, которую Вы продемонстрировали здесь.Очень здорово.Спасибо за информацию! –  larsks 23.01.2013, 18:35
  • 2
    Нет никакого/sys/kernel/debug/tracing/events/syscalls/sys_exit_inotify_add_watch/enable, ни/sys/kernel/debug/tracing/tracing_enabled на хинду Linux, но/sys/kernel/debug/tracing/tracing_enabled существует. Почему это? –  zeekvfu 04.12.2013, 18:32

Я изменил сценарий, существующий в вышеупомянутом для показа списка процессов, они используют inotify ресурсы:

ps -p `find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print | sed s/'^\/proc\/'/''/ | sed s/'\/fd.*$'/''/`

Я думаю, что существует способ заменить мой двойной sed.


Да. Используйте также
cut -f 3 -d '/'   

или

sed -e 's/^\/proc\/\([0-9]*\)\/.*/\1'  

и Вы только получите pid.
Кроме того, если Вы добавляете

2> /dev/null  

в находке Вы избавитесь от любых противных ошибочных строк, брошенных находкой. Таким образом, это работало бы:

ps -p $(find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print 2> /dev/null | sed -e 's/^\/proc\/\([0-9]*\)\/.*/\1/')
1
27.01.2020, 19:33

Для отслеживания того, какие процессы потребляют inotify watches (не экземпляры) можно использовать функцию динамической ftrace в ядре, если она включена в ядре.

Необходимая опция ядра - CONFIG_DYNAMIC_FTRACE.

Сначала смонтируйте отладочную файловую систему, если она еще не смонтирована.

mount -t debugfs nodev /sys/kernel/debug

Перейдите в подкаталог трассировка этого каталога отладочных файлов

cd /sys/kernel/debug/tracing

Включите трассировку только вызовов функций

echo function > current_tracer

Фильтр только SyS_inotify_add_watch системные вызовы

echo SyS_inotify_add_watch > set_ftrace_filter

Очистите буфер кольцевого трассировки, если он не был пуст

echo > trace

Включите трассировку, если она еще не включена

echo 1 > tracing_on

Перезапустите подозрительный процесс (в моем случае это был аварийный план), приложение резервного копирования)

Смотреть, как inotify_watch исчерпывается

wc -l trace
cat trace

Готово

.
6
27.01.2020, 19:33

Me encontré con este problema, y ​​ninguna de estas respuestas le da la respuesta de "¿cuántos relojes está usando cada proceso actualmente?" Todos los transatlánticos -le indican cuántas instancias están abiertas, lo cual es solo una parte de la historia, y el seguimiento solo es útil para ver cómo se abren nuevos relojes.

TL; DR:Esto le dará un archivo con una lista de instancias inotifyabiertas y el número de relojes que tienen, junto con los pids 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 lío, así que así es como llegué allí. Para comenzar, ejecuté un tailen un archivo de prueba y miré los fd 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 en el 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

¡Eso parece una entrada para el reloj en la parte inferior!

Probemos algo con más relojes, esta vez con la utilidad inotifywait, simplemente 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 en /tmpluego:

joel@opx1:~$ ls /tmp/ | wc -l
6

Excelente. Mi nuevo inotifywaittiene una entrada en su lista fd(que es lo que están contando los otros -transatlánticos aquí ), pero seis entradas en su archivo fdinfo. Así que podemos averiguar cuántos relojes usa un fd dado para un proceso dado consultando su archivo fdinfo. Ahora, combínelo con algunos de los anteriores para obtener una lista de procesos que tienen relojes de notificación abiertos y úselo para contar las entradas en cada fdinfo. Esto es similar a lo anterior, por lo que solo arrojaré el -forro 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 uso awkpara construir una ruta fdinfodesde la salida lsof, tomando el número pid y fd, eliminando el indicador u/r/w de este último. Luego, para cada ruta construida fdinfo, cuento el número de líneas inotifyy envío el recuento y el pid.

Sin embargo, sería bueno si tuviera los procesos que estos pid representan en el mismo lugar, ¿verdad? Ya me lo imaginaba. Entonces, en un momento particularmente complicado, decidí llamar a dirnamedos veces en la ruta fdinfopara obtener el paquete en /proc/<pid>, agregarle /exey luego ejecutar readlinken que para obtener el nombre exe del proceso. Agregue eso allí también, ordénelo por número de relojes y rediríjalo a un archivo para mantenerlo seguro -y obtendremos:

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

Ejecutando eso sin sudo para mostrar 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.

6
27.01.2020, 19:33

Как сказал @Jonathan Kamens, у вас, вероятно, закончились часы. У меня есть готовый скрипт , inotify-consumers, в котором перечислены основные нарушители для вас (в более новой версии также указано имя пользователя, которому принадлежит процесс, см. ниже):

$ time inotify-consumers  

   INOTIFY
   WATCHER
    COUNT     PID     CMD
----------------------------------------
    6688    27262  /home/dvlpr/apps/WebStorm-2018.3.4/WebStorm-183.5429.34/bin/fsnotifier64
     411    27581  node /home/dvlpr/dev/kiwi-frontend/node_modules/.bin/webpack --config config/webpack.dev.js
      79     1541  /usr/lib/gnome-settings-daemon/gsd-xsettings
      30     1664  /usr/lib/gvfs/gvfsd-trash --spawner :1.22 /org/gtk/gvfs/exec_spaw/0
      14     1630  /usr/bin/gnome-software --gapplication-service
   ....

    7489  watches TOTAL COUNT

real    0m0.099s
user    0m0.042s
sys 0m0.062s

Здесь вы быстро поймете, почему ограничение по умолчанию в 8 КБ слишком мало для машины разработки, так как только экземпляр WebStorm быстро достигает его максимума при встрече с папкой node_modulesс тысячами папок. Добавьте наблюдателя веб-пакетов, чтобы гарантировать проблемы...

Несмотря на то, что он был намного быстрее, чем другие альтернативы, когда я делал его изначально, Саймон Маттер добавил несколько улучшений скорости для сильно загруженного Big Iron Linux (сотен ядер ), которые значительно ускорили его, снизив его с десять минут (! )до 15 секунд на своем чудовище.

Как использовать

inotify-consumers --helpЧтобы получить его на свой компьютер, просто скопируйте содержимое скрипта и поместите его куда-нибудь в свой $PATH, например /usr/local/bin. В качестве альтернативы, если вы доверяете этому незнакомцу в сети, вы можете не копировать его и передать в bash через http:

$ curl -s https://raw.githubusercontent.com/fatso83/dotfiles/master/utils/scripts/inotify-consumers | bash 

       INOTIFY
       WATCHER
        COUNT     PID USER     COMMAND
    --------------------------------------
        3044   3933 myuser node /usr/local/bin/tsserver
        2965   3941 myuser /usr/local/bin/node /home/myuser/.config/coc/extensions/node_modules/coc-tsserver/bin/tsserverForkStart /hom
         979   3954 myuser /usr/local/bin/node /home/myuser/.config/coc/extensions/node_modules/coc-tsserver/node_modules/typescript/li
           1   7473 myuser /usr/local/bin/node --no-warnings /home/myuser/dev/dotfiles/common-setup/vim/dotvim/plugged/coc.nvim/build/i
           1   3899 myuser /usr/local/bin/node --no-warnings /home/myuser/dev/dotfiles/common-setup/vim/dotvim/plugged/coc.nvim/build/i

        6990  watches TOTAL COUNT

Как это работает?

Для справки, основное содержание скрипта просто (вдохновлено этим ответом)

find /proc/*/fd \
    -lname anon_inode:inotify \
    -printf '%hinfo/%f\n' 2>/dev/null \
    \
    | xargs grep -c '^inotify'  \
    | sort -n -t: -k2 -r 

Изменение пределов

Если вам интересно, как увеличить лимиты

$ inotify-consumers --limits 

Current limits
-------------
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 524288


Changing settings permanently
-----------------------------
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p # re-read config
34
27.01.2020, 19:33

Нам нужно было запустить этот сценарий на множестве серверов, поэтому мы написали Ansible playbook для выполнения этой задачи. Он адаптирует несколько концепций в других ответах в единую книгу, которая будет запускать команды, необходимые для создания отчета, показывающего использование наблюдателя inotify по PID.

$ ansible-playbook \
    -i systems-inventory/cluster2.lab1 \
    playbooks/show_inotify_watcher_cnt.yml \
    -l ocp-master-02a.lab1*

ПРИМЕЧАНИЕ.:Примером использования этой пьесы является комментарий в конце этой пьесы ниже.

$ cat show_inotify_watcher_cnt.yml
###########################################################
# References
###########################################################
# - https://stackoverflow.com/questions/40230184/how-to-do-multiline-shell-script-in-ansible
###########################################################


- hosts: compute infra masters
  tasks:
    - shell:
        cmd: |
            cat <<EOF > /tmp/inotify_cnt.sh
            #!/bin/bash

            ## Get the procs sorted by the number of inotify watchers
            ##
            ## From \`man find\`: 
            ##    %h     Leading directories of file's name (all but the last element).  
            ##           If the file name contains no slashes (since it is in the current directory) 
            ##           the %h specifier expands to \`.'.
            ##    %f     File's name with any leading directories removed (only the last element).
            lines=\$(
                find /proc/*/fd \
                -lname anon_inode:inotify \
                -printf '%hinfo/%f\n' 2>/dev/null \
                \
                | xargs grep -c '^inotify'  \
                | sort -n -t: -k2 -r \
                )

            printf "\n%10s\n" "INOTIFY"
            printf "%10s\n" "WATCHER"
            printf "%10s  %5s     %s\n" " COUNT " "PID" "CMD"
            printf -- "----------------------------------------\n"
            for line in \$lines; do
                watcher_count=\$(echo \$line | sed -e 's/.*://')
                pid=\$(echo \$line | sed -e 's/\/proc\/\([0-9]*\)\/.*/\1/')
                cmdline=\$(ps --columns 120 -o command -h -p \$pid) 
                printf "%8d  %7d  %s\n" "\$watcher_count" "\$pid" "\$cmdline"
            done
            EOF
      become: yes

    - file: 
        dest: /tmp/inotify_cnt.sh
        mode: a+x

    - shell: /tmp/inotify_cnt.sh
      become: yes
      register: output

    - debug:
        var: output.stdout_lines

    - shell: |
        sysctl fs.inotify
      become: yes
      register: output

    - debug:
        var: output.stdout_lines


##########
# USAGE
##########
## $ ansible-playbook -i systems-inventory/cluster2.lab1 playbooks/show_inotify_watcher_cnt.yml -l ocp-master-02a.lab1*
##   
##   PLAY [compute infra masters] *****************************************************************************************************************************************************
##   
##   TASK [Gathering Facts] ***********************************************************************************************************************************************************
##   ok: [ocp-master-02a.lab1.mydomclec.local]
##   
##   TASK [shell] *********************************************************************************************************************************************************************
##   changed: [ocp-master-02a.lab1.mydomclec.local]
##   
##   TASK [file] **********************************************************************************************************************************************************************
##   ok: [ocp-master-02a.lab1.mydomclec.local]
##   
##   TASK [shell] *********************************************************************************************************************************************************************
##   changed: [ocp-master-02a.lab1.mydomclec.local]
##   
##   TASK [debug] *********************************************************************************************************************************************************************
##   ok: [ocp-master-02a.lab1.mydomclec.local] => {
##       "output.stdout_lines": [
##           "",
##           "   INOTIFY",
##           "   WATCHER",
##           "    COUNT     PID     CMD",
##           "----------------------------------------",
##           "     957     6553  /usr/bin/hyperkube kubelet --v=2 --address=0.0.0.0 --allow-privileged=true --anonymous-auth=true --authentication-token-",
##           "      11      856  /usr/lib/systemd/systemd-udevd",
##           "      11     1457  /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid",
##           "      10     1471  /usr/sbin/rpc.gssd",
##           "       5        1  /usr/lib/systemd/systemd --switched-root --system --deserialize 22",
##           "       5        1  /usr/lib/systemd/systemd --switched-root --system --deserialize 22",
##           "       5     1508  /usr/sbin/NetworkManager --no-daemon",
##           "       4        1  /usr/lib/systemd/systemd --switched-root --system --deserialize 22",
##           "       4        1  /usr/lib/systemd/systemd --switched-root --system --deserialize 22",
##           "       4     1508  /usr/sbin/NetworkManager --no-daemon",
##           "       4     1378  /usr/lib/polkit-1/polkitd --no-debug",
##           "       3     4211  tail --follow=name /var/log/openvswitch/ovs-vswitchd.log /var/log/openvswitch/ovsdb-server.log",
##           "       3     1970  /usr/sbin/crond -n",
##           "       3     1378  /usr/lib/polkit-1/polkitd --no-debug",
##           "       2     1893  /usr/sbin/rsyslogd -n",
##           "       2     1389  /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation",
##           "       1     9012  virt-handler -v 3 --port 8443 --hostname-override ocp-master-02a.lab1.mydomclec.local --pod-ip-address 172.20.0.201",
##           "       1     9012  virt-handler -v 3 --port 8443 --hostname-override ocp-master-02a.lab1.mydomclec.local --pod-ip-address 172.20.0.201",
##           "       1     9012  virt-handler -v 3 --port 8443 --hostname-override ocp-master-02a.lab1.mydomclec.local --pod-ip-address 172.20.0.201",
##           "       1     9012  virt-handler -v 3 --port 8443 --hostname-override ocp-master-02a.lab1.mydomclec.local --pod-ip-address 172.20.0.201",
##           "       1     6553  /usr/bin/hyperkube kubelet --v=2 --address=0.0.0.0 --allow-privileged=true --anonymous-auth=true --authentication-token-",
##           "       1     6553  /usr/bin/hyperkube kubelet --v=2 --address=0.0.0.0 --allow-privileged=true --anonymous-auth=true --authentication-token-",
##           "       1        1  /usr/lib/systemd/systemd --switched-root --system --deserialize 22",
##           "       1     1388  /usr/sbin/sssd -i --logger=files",
##           "       1     1359  /usr/bin/abrt-watch-log -F BUG: WARNING: at WARNING: CPU: INFO: possible recursive locking detected ernel BUG at list_de",
##           "       1     1347  /usr/sbin/abrtd -d -s",
##           "       0     6553  /usr/bin/hyperkube kubelet --v=2 --address=0.0.0.0 --allow-privileged=true --anonymous-auth=true --authentication-token-"
##       ]
##   }
##   
##   TASK [shell] *********************************************************************************************************************************************************************
##   changed: [ocp-master-02a.lab1.mydomclec.local]
##   
##   TASK [debug] *********************************************************************************************************************************************************************
##   ok: [ocp-master-02a.lab1.mydomclec.local] => {
##       "output.stdout_lines": [
##           "fs.inotify.max_queued_events = 16384",
##           "fs.inotify.max_user_instances = 128",
##           "fs.inotify.max_user_watches = 65536"
##       ]
##   }
##   
##   PLAY RECAP ***********************************************************************************************************************************************************************
##   ocp-master-02a.lab1.mydomclec.local : ok=7    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
##   
0
03.02.2020, 21:01

Только что написал приложение на C++, помогающее отслеживать информацию inotify. Должен иметь возможность отображать сводную информацию вместе с просматриваемыми файлами и каталогами.

https://github.com/mikesart/inotify-info

Надеемся, что это поможет отследить ограничения и места их превышения.

1
15.09.2021, 02:57

Теги

Похожие вопросы