inotify -
ファイルシステムイベントを監視する
inotify API
はファイルシステムイベントを監視するための機構を提供する。
inotify
は個々のファイルやディレクトリを監視するのに使える。
ディレクトリを監視する場合、inotify
はディレクトリ自身と
ディレクトリ内のファイルのイベントを返す。
以下のシステムコールがこの
API と共に使用される:
inotify_init(2) (や
inotify_init1(2)),
inotify_add_watch(2),
inotify_rm_watch(2),
read(2),
close(2).
inotify_init(2) は inotify
インスタンスを作成し、inotify
インスタンスを参照する
ファイルディスクリプタを返す。
もっと新しい
inotify_init1(2)
も
inotify_init(2)
と同様だが、いくつかの追加の機能が提供されている。
inotify_add_watch(2) は inotify
インスタンスに関連づけられた「監視対象
(watch)
リスト」を操作する。
監視対象リストの各アイテム
("watch") は、
ファイルまたはディレクトリのパス名と、
そのパス名で参照されるファイルに対して
カーネルが監視する複数のイベントの集合を指定する。
inotify_add_watch(2)
は新しい監視アイテムの作成や既存の監視対象の変更ができる。
各監視対象は一意の「監視対象ディスクリプタ」を持つ。
これは監視対象を作成したときに
inotify_add_watch(2)
から返される整数である。
inotify_rm_watch(2) は inotify
の監視対象リストからアイテムを削除する。
inotify
インスタンスを指している
全てのファイルディスクリプタがクローズされた場合、
その下層にあるオブジェクトとそのリソースは、
カーネルで再利用するために解放される。
関連が切られた監視対象は自動的に解放される。
どのようなイベントが起こっていたかを知るには、
アプリケーションで
inotify
ファイルディスクリプタを
read(2) すればよい。
これまでに何もイベントが起こっていない場合、
停止 (blocking)
モードのファイルディスクリプタであれば、
少なくとも 1
つのイベントが起こるまで
read(2) は停止する
(シグナルにより割り込まれなかった場合。
シグナルによる割り込みがあった場合、呼び出しはエラー
EINTR で失敗する。
signal(7)
参照)。
read(2)
が成功すると、以下の構造体を
1
つ以上含むバッファが返される:
struct inotify_event {
int wd; /* 監視対象ディスクリプタ */
uint32_t mask; /* イベントのマスク */
uint32_t cookie; /* 関連するイベント群を関連づける
一意なクッキー (rename(2) 用) */
uint32_t len; /* 'name' フィールドのサイズ */
char name[]; /* NULL で終端された任意の名前 */
};
wd
はイベント発生の監視対象を指定する。
これは、前もって行われた
inotify_add_watch(2)
呼び出しで返された監視対象ディスクリプタのうちの
1 つである。
mask
には発生したイベント
(下記参照)
を記述するためのビットが含まれる。
cookie
は関連するイベントを関連づけるための一意な整数である。
現在のところ、この値は
rename
イベントに対してのみ使われており、
結果のペアである
IN_MOVE_FROM と
IN_MOVE_TO
イベントを
アプリケーションで関連づけることができる。
他のイベント種別の場合には、
cookie は 0 に設定する。
name
フィールドは監視しているディレクトリ内のファイルに対して
イベントが返される場合のためにだけ存在する。
監視するディレクトリからのファイルの相対パス名を表す。
このパス名は NULL
で終端され、
その後の読み込みで適切なアドレス境界に調整するために、
さらに NULL
バイトが含まれる場合もある。
len フィールドは NULL
バイトを含む
name
の全てのバイト数を表す。
よって、
inotify_event
構造体のサイズは
sizeof(struct inotify_event)+len である。
read(2)
に渡されたバッファが小さすぎて次のイベントに関する情報を返せ
ない場合の動作はカーネルのバージョンにより異なる。
2.6.21 より前のカー
ネルでは、
read(2) は 0
を返す。 2.6.21
以降のカーネルでは、
read(2) はエラー
EINVAL
で失敗する。
バッファサイズとして
sizeof(struct inotify_event) + NAME_MAX + 1
を指定すれば、少なくとも
1
イベントで読み出しを行うには十分である。
inotify イベント¶
inotify_add_watch(2) の
mask
引き数と、inotify
ファイル構造体を
read(2)
したときに返される
inotify_event 構造体の
mask
フィールドは、ともに
inotify
イベントを識別するための
ビットマスクである。
以下のビットが
inotify_add_watch(2) を呼ぶときの
mask
に指定可能であり、
read(2) で返される
mask
フィールドで返される:
- IN_ACCESS
- ファイルがアクセス
(read) された。(*)
- IN_ATTRIB
- メタデータが変更された。
メタデータとは、例えば、許可
(permission)、タイムスタンプ、拡張属性、
リンクカウント (Linux 2.6.25
以降)、UID、GID
などである。(*)
- IN_CLOSE_WRITE
- 書き込みのためにオープンされたファイルがクローズされた。(*)
- IN_CLOSE_NOWRITE
- 書き込み以外のためにオープンされたファイルがクローズされた。(*)
- IN_CREATE
- 監視対象ディレクトリ内でファイルやディレクトリが作成された。(*)
- IN_DELETE
- 監視対象ディレクトリ内でファイルやディレクトリが削除された。(*)
- IN_DELETE_SELF
- 監視対象のディレクトリまたはファイル自身が削除された。
- IN_MODIFY
- ファイルが修正された。(*)
- IN_MOVE_SELF
- 監視対象のディレクトリまたはファイル自身が移動された。
- IN_MOVED_FROM
- ファイルが監視対象ディレクトリ外へ移動された。(*)
- IN_MOVED_TO
- ファイルが監視対象ディレクトリ内へ移動された。(*)
- IN_OPEN
- ファイルがオープンされた。(*)
ディレクトリを監視する場合、
上記でアスタリスク (*)
を付けたイベントは、
そのディレクトリ内のファイルに対して発生する。
このとき
inotify_event
構造体で返される
name
フィールドは、ディレクトリ内のファイル名を表す。
IN_ALL_EVENTS
マクロは上記のイベント全てのマスクとして定義される。
このマクロは
inotify_add_watch(2)
を呼び出すときの
mask
引き数として使える。
さらに 2
つの便利なマクロがある。
IN_MOVE は IN_MOVED_FROM|IN_MOVED_TO
と同じで、
IN_CLOSE は
IN_CLOSE_WRITE|IN_CLOSE_NOWRITE
と同じである。
その他にも以下のビットを
inotify_add_watch(2) を呼ぶときの
mask に指定できる:
- IN_DONT_FOLLOW
- pathname
がシンボリックリンクである場合に辿らない。
(Linux 2.6.15 以降)
- IN_EXCL_UNLINK (Linux 2.6.36 以降)
- デフォルトでは、あるディレクトリの子ファイルに関するイベントを監視
(watch)
した際、ディレクトリからその子ファイルが削除
(unlink)
された場合であっても
その子ファイルに対してイベントが生成される。このことは、アプリケーションに
よってはあまり興味のないイベントが大量に発生することにつながる
(例えば、 /tmp
を監視している場合、たくさんのアプリケーションが、すぐにその名前が削除される
一時ファイルをそのディレクトリにに作成する)。
IN_EXCL_UNLINK を指定すると
このデフォルトの動作を変更でき、監視対象のディレクトリから子ファイルが削除
された後に子ファイルに関するイベントが生成されなくなる。
- IN_MASK_ADD
- pathname
に対する監視マスクが既に存在する場合、
(マスクの置き換えではなく)
イベントを追加 (OR)
する。
- IN_ONESHOT
- 1
つのイベントについて
pathname を監視し、
イベントが発生したら監視対象リストから削除する。
- IN_ONLYDIR (Linux 2.6.15 以降)
- pathname
がディレクトリの場合にのみ監視する。
以下のビットが
read(2)
で返される
mask
フィールドに設定される:
- IN_IGNORED
- 監視対象が
(inotify_rm_watch(2) により)
明示的に
削除された。もしくは
(ファイルの削除、またはファイル
システムのアンマウントにより)
自動的に削除された。
- IN_ISDIR
- このイベントの対象がディレクトリである。
- IN_Q_OVERFLOW
- イベントキューが溢れた
(このイベントの場合、
wd は -1 である)。
- IN_UNMOUNT
- 監視対象オブジェクトを含むファイルシステムがアンマウントされた。
/proc
インターフェース¶
以下のインターフェースは、inotify
で消費される
カーネルメモリの総量を制限するのに使用できる:
- /proc/sys/fs/inotify/max_queued_events
- このファイルの値は、アプリケーションが
inotify_init(2)
を呼び出すときに使用され、対応する
inotify
インスタンスについて
キューに入れられるイベントの数の上限を設定する。
この制限を超えたイベントは破棄されるが、
IN_Q_OVERFLOW
イベントが常に生成される。
- /proc/sys/fs/inotify/max_user_instances
- 1 つの実ユーザ ID
に対して生成できる
inotify
インスタンスの数の上限を指定する。
- /proc/sys/fs/inotify/max_user_watches
- 作成可能な監視対象の数の実
UID
単位の上限を指定する。
バージョン¶
inotify は 2.6.13 の Linux
カーネルに組込まれた。
これに必要なライブラリのインターフェースは、
glibc のバージョン 2.4
に追加された (
IN_DONT_FOLLOW,
IN_MASK_ADD,
IN_ONLYDIR
だけはバージョン 2.5
で追加された)。
inotify API は Linux
独自のものである。
inotify
ファイルディスクリプタは
select(2),
poll(2),
epoll(7)
を使って監視できる。
イベントがある場合、ファイルディスクリプタは読み込み可能と通知する。
Linux 2.6.25
以降では、シグナル駆動
(signal-driven) I/O の通知が inotify
ファイルディスクリプタについて利用可能である。
fcntl(2) に書かれている
(
O_ASYNC
フラグを設定するための)
F_SETFL,
F_SETOWN,
F_SETSIG
の議論を参照のこと。
シグナルハンドラに渡される
siginfo_t
構造体は、以下のフィールドが設定される
(
siginfo_t は
sigaction(2)
で説明されている)。
si_fd には inotify
ファイルディスクリプタ番号が、
si_signo
にはシグナル番号が、
si_code には
POLL_IN が、
si_band
には
POLLIN
が設定される。
inotify
ファイルディスクリプタに対して
連続して生成される出力
inotify
イベントが同一の場合
(
wd,
mask,
cookie,
name
が等しい場合)、
前のイベントがまだ読み込まれていなければ、
連続するイベントが 1
つのイベントにまとめられる
(ただし「バグ」の節も参照のこと)。
inotify
ファイルディスクリプタの読み込みで返されるイベントは、
順序付けられたキューになる。
従って、たとえば、あるディレクトリの名前を別の名前に変更した場合、
inotify
ファイルディスクリプタについての正しい順番で
イベントが生成されることが保証される。
FIONREAD ioctl(2) は inotify
ファイルディスクリプタから何バイト読み込めるかを返す。
制限と警告¶
inotify
によるディレクトリの監視は再帰的に行われない:
あるディレクトリ以下の
サブディレクトリを監視する場合、
監視対象を追加で作成しなければならない。
大きなディレクトリツリーの場合には、この作業にかなり時間がかかることがある。
inotify API では inotify
イベントのきっかけとなったユーザやプロセスに関する
情報が提供されない。
イベントキューは溢れる場合があることに注意すること。この場合にはイベントは
失われてしまう。堅牢性が必要なアプリケーションでは、イベントが失われる可能性
を適切に扱う必要がある。
inotify API
では影響が受けるファイルをファイル名で特定する。
しかしながら、アプリケーションが
inotify
イベントを処理する時点では、
そのファイル名がすでに削除されたり変更されたりしている可能性がある。
ディレクトリツリー全体を監視していて、そのツリー内に新しいサブディレクトリが
作成される場合、新しいサブディレクトリに対する
watch を作成するまでに、
新しいファイルがそのサブディレクトリ内にすでに作成されている場合がある点に
注意すること。したがって、watch
を追加した直後にサブディレクトリの内容を
スキャンしたいと思う場合もあるだろう。
2.6.16 以前のカーネルでは
IN_ONESHOT mask
フラグが働かない。
カーネル 2.6.25
より前では、
連続する同一のイベントを一つにまとめることを意図したコード
(古い方のイベントがまだ読み込まれていない場合に、
最新の 2
つのイベントを一つにまとめられる可能性がある)
が、
最新のイベントが「最も古い」読み込まれていないイベントとまとめられるか
をチェックするようになっていた。
関連項目¶
inotify_add_watch(2),
inotify_init(2),
inotify_init1(2),
inotify_rm_watch(2),
read(2),
stat(2),
Documentation/filesystems/inotify.txt.
この文書について¶
この man ページは Linux
man-pages
プロジェクトのリリース
3.41 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。