Как насчет этого:
rsync -avn --include="*.pdf" ~/Latex/ ~/Output/
Кажется, что, если процесс создает 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
find /proc/*/fd/* -type l -lname 'anon_inode:inotify' 2>/dev/null | cut -f 1-4 -d'/' | sort | uniq -c | sort -nr
У Вас, вероятно, заканчиваются часы inotify, а не экземпляры. Для обнаружения, кто создает много часов:
$ echo 1 > /sys/kernel/debug/tracing/events/syscalls/sys_exit_inotify_add_watch/enable`
tracing_on
s к 1:$ cat /sys/kernel/debug/tracing/tracing_on
0
$ echo 1 > /sys/kernel/debug/tracing/tracing_on
$ 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
/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
.
Я изменил сценарий, существующий в вышеупомянутом для показа списка процессов, они используют 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/')
Для отслеживания того, какие процессы потребляют 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
Готово
.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 inotify
abiertas 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 tail
en 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 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
¡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 /tmp
luego:
joel@opx1:~$ ls /tmp/ | wc -l
6
Excelente. Mi nuevo inotifywait
tiene 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 awk
para construir una ruta fdinfo
desde 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 inotify
y 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 dirname
dos veces en la ruta fdinfo
para obtener el paquete en /proc/<pid>
, agregarle /exe
y luego ejecutar readlink
en 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.
Как сказал @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
Нам нужно было запустить этот сценарий на множестве серверов, поэтому мы написали 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
##
Только что написал приложение на C++, помогающее отслеживать информацию inotify. Должен иметь возможность отображать сводную информацию вместе с просматриваемыми файлами и каталогами.
https://github.com/mikesart/inotify-info
Надеемся, что это поможет отследить ограничения и места их превышения.
find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print
– larsks 25.06.2011, 15:29