1. 序章

最近のソフトウェアは、データの変更に基づいてビューを自動的に更新することがよくあります。

この便利さは、さまざまなシステムによってもたらされます。

このチュートリアルでは、inotifyシステムとその機能について説明します。 その後、現在のユーザーを確認する方法を探ります。 最後に、inotifyに関連するいくつかの一般的なエラーについて説明します。

このチュートリアルのコードは、GNU Bash5.1.4を使用したDebian11(Bullseye)でテストしました。 これはPOSIXに準拠しており、そのような環境で機能するはずです。

2. ファイルシステムイベント通知

ネイティブLinuxファイルシステムのキーとしてinodesについて説明しました。 実際、それらの変更は多くのファイルイベントに関連しています。

これに基づいて、 inotifyサブシステムの主な機能は、ファイルシステムのイベントを監視および報告することです。 inotifywaitおよびinotifywatchツールを使用する場合でも、他のソフトウェアからのシステムコールを使用する場合でも、ファイル操作を簡単に追跡できます。

たとえば、コマンドラインを使用して、特定のファイルのイベントを単純に待機できます。

$ inotifywait /file.ext && echo 'Event.'
Setting up watches.
Watches established.

したがって、 /file.ext が操作の一部になっている場合は、通知が届きます。 しかし、一度に多くのオブジェクトに対して永続的にそれを実行したい場合はどうでしょうか。

3. 複数のファイルとディレクトリツリーの監視

より一般的な監視が必要な場合があります。 1つの方法は、 –recursive -r )および –monitor -m )スイッチをinotifywait[に追加することです。 X119X]。 これらは、それぞれディレクトリツリーの処理と継続的な監視を保証します。

さらに、 inotifywatch を使用して、ファイルシステムの特定の部分にリンクされているイベントをリッスンできます。

$ inotifywatch /
Establishing watches...
Finished establishing watches, now collecting statistics.

ファイルシステムオブジェクトごとに個別のウォッチが必要なため、Linuxには最大数の上限があります。 実際、特定のシステムでそれが何であるかを確認できます。

$ cat /proc/sys/fs/inotify/max_user_watches
524288

ここでは、システムは 524288 (2 ^ 19)の時計を許可します。 便利なことに、いつでも誰がそれらを使用しているかを確認できます。

4. inotifyユーザーの確認

いくつかのLinuxコマンドを組み合わせることで、現在時計を使用しているプロセスを見つけることができます

$ inotifywatch / &
Establishing watches...
Finished establishing watches, now collecting statistics.
[1] 666
$ find /proc/*/fd -lname anon_inode:inotify |
  cut -d/ -f3 |
  xargs -I '{}' -- ps --no-headers -o '%p %U %c' -p '{}' |
  uniq -c |
  sort -nr
      1    6660 root     inotifywatch

inotifyファイル記述子の数がwatchesの数と同じではありません。 このため、 script があります。これには、上記のコマンドラインのより優れたバージョンと他の機能が含まれています。

さらに、 strace (システムトレース)を使用して、すべての時計のリストを取得できます。

$ strace --follow-forks --trace='inotify_add_watch' inotifywait --quiet /file.ext
inotify_add_watch(3, "/file.ext",
  IN_ACCESS|IN_MODIFY|IN_ATTRIB|IN_CLOSE_WRITE|IN_CLOSE_NOWRITE|IN_OPEN|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF) = 1

最後に、 lsof (開いているファイルの一覧表示)ツールもあります。このツールには、inotifyユーザーも一覧表示されます。

$ tail -f /file.ext &
[1] 666
$ lsof | grep inotify
tail    666             root    4r  a_inode               0,11        0            15387 inotify

時計の使い方や取り扱い方はすべて揃っていますが、問題が発生することは珍しくありません。

5. 一般的なinotifyエラー

inotifyサブシステムを使用する場合の落とし穴があります。 それらのいくつかについて話し合いましょう。

5.1. 権限

実際、他のファイルシステム操作と同様に、ターゲットオブジェクトを少なくともある程度制御する必要があります。 言い換えれば、適切な権限なしでは監視できません

$ inotifywatch /root
Establishing watches...
Failed to watch /root: Permission denied

これを修正するには、少なくともターゲットオブジェクトを読み取ることができる必要があります。 ここでは、 chmod (変更モード)を介して必要な権利を追加します。

$ chmod +r /root

これらの変更後、時計を追加できます。

5.2. inotifyウォッチ制限

/上の再帰的なinotifywatchは、ファイルと同じ数のウォッチを使用することを考慮してください。 実際、監視制限を超えるファイルを含むファイルシステムでこれを行うと、エラーが発生します。

$ cat /proc/sys/fs/inotify/max_user_watches
524288<
$ df --inodes /
Filesystem       Inodes  IUsed    IFree IUse% Mounted on
/dev/sdb       16777216 666000 16111216    4% /
$ inotifywatch --recursive /
Establishing watches...
Failed to watch /; upper limit on inotify watches reached!
Please increase the amount of inotify watches allowed per user via '/proc/sys/fs/inotify/max_user_watches'.

もちろん、解決策はエラーテキストにあります。 ただし、それを適用する方法は複数あります。

$ max_user_watches=CUSTOM_MAX_USER_WATCHES_VALUE
$ sysctl fs.inotify.max_user_watches=${max_user_watches}
$ echo fs.inotify.max_user_watches=${max_user_watches} >> /etc/sysctl.conf
$ sysctl --load

最初のコマンドはセッションごとに適用しますが、2番目のコマンドは再起動後も存続します。 これは、/etc/sysctl.confに行が追加されるためです。 ただし、回線がすでに存在する場合は、必要に応じて変更する必要があります。 構成ファイルを再読み取りして適用する最後のコマンドで再起動を回避できます。

5.3. メインメモリ(RAM)の問題

各時計は構造物であるため、使用可能なメモリはinotifyを使用する際のボトルネックにもなります。 実際、時計は最大1KBのスペースを占める可能性があります。 これは、100万個の時計が1GBのRAM使用量を増やす可能性があることを意味します。

時々、これは奇妙なエラーにつながる可能性があります:

  • inotify_add_watchが失敗しました:デバイス(/file.ext)にスペースが残っていません
  • ‘/file.ext’を監視できません:デバイスにスペースが残っていません

メモリを解放することは、進むべき道のようです。 ただし、このアプローチにはいくつかの問題があります。

まず、 inotifyは、スワップできないカーネルメモリを使用します。 第二に、プログラムは、時計が不足している場合でも、このようなエラーをスローする可能性があります。

6. 概要

この記事では、多くのアプリケーションで使用されている inotifyLinuxサブシステムについて説明しました。

結論として、時計について知ることで、ソフトウェア製品の内部動作だけでなく、使用中に見られるエラーも理解することができます。