Лимиты на inotify

Здесь мы разберём лимиты на использование inotify. Узнаем что это такое, для чего используется и как задать ограничение на их количество.















Подсистема inotify




Подсистема inotify — позволяет получать уведомления о событиях, связанных с файлами и каталогами файловой системы. То есть, если нам нужно следить за изменениями в каком-то каталоге, мы создаем экземпляр (instances) inotify в ядре и начинаем следить за каталог. В случае если какой-нибудь файл в этом каталоге изменится или удалится, то мы получим уведомление.




Всё это мы проделываем не вручную. Это проделывают приложения, которые умеют использовать inotify. Но иногда, приложение хочет создать новые экземпляр inotify, но упирается в лимит. Поэтому иногда нужно лимиты inotify поднимать.




Ограничения экземпляров inotify




Ограничения по inotify задаются в файле /etc/sysctl.conf, из этого следует что ограничение накладывает ядро системы.




Экземпляр inotify может использоваться одним процессом или несколькими, но в рамках одного пользователя. Поэтому они распределяются по пользователям, а не по процессам.




Чтобы указать лимиты inotify, нужно использовать параметр fs.inotify.max_user_instances:




$ sudo nano /etc/sysctl.conf
fs.inotify.max_user_instances = 512




Тут мы задали что каждый пользователь сможет создать 512 экземпляров inotify.




Ограничения watches




Каждый экземпляр inotify может следить за несколькими файлами. Количество таких файлов тоже можно ограничить и это тоже задаётся в файле /etc/sysctl.conf. Для этого нужно использовать параметр fs.inotify.max_user_watches:




$ sudo nano /etc/sysctl.conf
fs.inotify.max_user_instances = 512
fs.inotify.max_user_watches = 10000




Тут мы дополнили, что каждый экземпляр inotify может следить за 10000 файлов.




Узнаём количество instances и watches inotify




Что бы узнать сколько экземпляров inotify было создано в разрезе пользователей выполните следующую команду:




# find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print 2>/dev/null | cut -d/ -f3 |xargs -I '{}' -- ps --no-headers -o '%U' -p '{}' | sort | uniq -c | sort -nr
     35 root
      6 www-data
      4 1001
      4 100000
      2 messagebus
      2 100104
      1 systemd-timesync
      1 systemd-resolve
      1 _rpc
      1 _apt




Из вывода видно, что больше всего экземпляров inotify было создано пользователем root.




А что бы узнать сколько экземпляров inotify было создано в разрезе процессов выполните следующую команду:




# find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print 2>/dev/null | cut -d/ -f3 |xargs -I '{}' -- ps --no-headers -o '%U %p %c' -p '{}' | sort | uniq -c | sort -nr
      5 root         1 systemd
      5 root     13460 systemd
      3 root     13298 systemd
      2 root      2545 fail2ban-server
      2 1001     28273 systemd
      1 www-data  3072 spiceproxy
      1 www-data  3065 pveproxy
      1 www-data 28833 pveproxy worker
      1 www-data 28790 pveproxy worker
      1 www-data 28362 pveproxy worker
 ***




Из вывода видно, что больше всего экземпляров inotify было создано процессом systemd.




Утилита inotify-consumers




Для более подробного отчета по instances и watches inotify можно использовать скрипт с github.com.




Скопируем этот скрипт себе на систему и выполним его:




# ./inotify-consumers.sh 

   INOTIFY   INSTANCES
   WATCHES      PER   
    COUNT     PROCESS   PID USER         COMMAND
------------------------------------------------------------
      82         5         1 root        /sbin/init
      33         5      7779 100000      /sbin/init
      33         5      6912 100000      /sbin/init
      33         5      6258 100000      /sbin/init
      33         5      5748 100000      /sbin/init
      33         1      7973 root        /lib/systemd/systemd-udevd
      33         1      1093 root        /lib/systemd/systemd-udevd
 *** вывод обрезан ***

     424  WATCHES TOTAL COUNT

INotify instances per user (e.g. limits specified by fs.inotify.max_user_instances): 

INSTANCES    USER
-----------  ------------------
38           100000
30           root
6            www-data
4            100103
4            100102
2            messagebus
 *** вывод обрезан ***




Утилита работает очень быстро, и помимо экземпляров показывает watches. Здесь видно что больше всего watches, а именно 82, у процесса /sbin/init (systemd). А вот экземпляров больше всего создал пользователь 100000, а именно 38 instances.









Итог




Мы узнали про подсистему inotify. И научились задавать лимиты для instances и watches inotify. А также я показал несколько способов, как узнать текущее количество instances и watches inotify.










2022-11-10T16:04:22
Администрирование Linux