Man page - inotify(7)

Packages contains this manual

Available languages:

en fr ja ru

Manual

INOTIFY

名 前
説 明
inotify フ ァ イ ル デ ィ ス ク リ プ タ ー か ら の イ ベ ン ト の 読 み 出 し
inotify イ ベ ン ト

/proc イ ン タ ー フ ェ ー ス
バ ー ジ ョ ン
準 拠
注 意
制 限 と 警 告
rename() イ ベ ン ト の 取 り 扱 い
バ グ

出 力 例
プ ロ グ ラ ム ソ ー ス
関 連 項 目
こ の 文 書 に つ い て

名 前

inotify - フ ァ イ ル シ ス テ ム イ ベ ン ト を 監 視 す る

説 明

inotify API は フ ァ イ ル シ ス テ ム イ ベ ン ト を 監 視 す る た め の 機 構 を 提 供 す る 。 inotify は 個 々 の フ ァ イ ル や デ ィ レ ク ト リ を 監 視 す る の に 使 え る 。 デ ィ レ ク ト リ を 監 視 す る 場 合 、 inotify は デ ィ レ ク ト リ 自 身 と デ ィ レ ク ト リ 内 の フ ァ イ ル の イ ベ ン ト を 返 す 。

こ の API で は 以 下 の シ ス テ ム コ ー ル が 使 用 さ れ る 。

*

inotify_init (2) は inotify イ ン ス タ ン ス を 作 成 し 、 inotify イ ン ス タ ン ス を 参 照 す る フ ァ イ ル デ ィ ス ク リ プ タ ー を 返 す 。 よ り 新 し い inotify_init1 (2) も inotify_init (2) と 同 様 だ が 、 こ ち ら に は い く つ か の 追 加 の 機 能 を 利 用 す る た め の flags 引 数 が あ る 。

*

inotify_add_watch (2) は inotify イ ン ス タ ン ス に 関 連 づ け ら れ た 「 監 視 対 象 (watch) リ ス ト 」 を 操 作 す る 。 監 視 対 象 リ ス ト の 各 ア イ テ ム ("watch") は 、 フ ァ イ ル ま た は デ ィ レ ク ト リ の パ ス 名 と 、 そ の パ ス 名 で 参 照 さ れ る フ ァ イ ル に 対 し て カ ー ネ ル が 監 視 す る 複 数 の イ ベ ン ト の 集 合 を 指 定 す る 。 inotify_add_watch (2) は 新 し い 監 視 ア イ テ ム の 作 成 や 既 存 の 監 視 対 象 の 変 更 が で き る 。 各 監 視 対 象 は 一 意 の 「 監 視 対 象 デ ィ ス ク リ プ タ ー 」 を 持 つ 。 こ れ は 監 視 対 象 を 作 成 し た と き に inotify_add_watch (2) か ら 返 さ れ る 整 数 で あ る 。

*

監 視 し て い る フ ァ イ ル や デ ィ レ ク ト リ で イ ベ ン ト が 起 こ る と 、 そ れ ら の イ ベ ン ト は ア プ リ ケ ー シ ョ ン か ら inotify フ ァ イ ル デ ィ ス ク リ プ タ ー か ら read (2) を 使 っ て 構 造 化 デ ー タ と し て 読 み 出 す こ と が で き る (下 記 参 照 )。

*

inotify_rm_watch (2) は inotify の 監 視 対 象 リ ス ト か ら ア イ テ ム を 削 除 す る 。

*

inotify イ ン ス タ ン ス を 指 し て い る 全 て の フ ァ イ ル デ ィ ス ク リ プ タ ー が ( close (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[]; /* ヌ ル で 終 端 さ れ た 任 意 の 名 前 */
};

wd は イ ベ ン ト 発 生 の 監 視 対 象 を 指 定 す る 。 こ れ は 、 前 も っ て 行 わ れ た inotify_add_watch (2) 呼 び 出 し で 返 さ れ た 監 視 対 象 デ ィ ス ク リ プ タ ー の う ち の 1 つ で あ る 。

mask に は 発 生 し た イ ベ ン ト (下 記 参 照 ) を 記 述 す る た め の ビ ッ ト が 含 ま れ る 。

cookie は 関 連 す る イ ベ ン ト を 関 連 づ け る た め の 一 意 な 整 数 で あ る 。 現 在 の と こ ろ 、 こ の 値 は rename イ ベ ン ト に 対 し て の み 使 わ れ て お り 、 結 果 の ペ ア で あ る IN_MOVED_FROM IN_MOVED_TO イ ベ ン ト を ア プ リ ケ ー シ ョ ン で 関 連 づ け る こ と が で き る 。 他 の イ ベ ン ト 種 別 の 場 合 に は 、 cookie は 0 に 設 定 す る 。

name フ ィ ー ル ド は 監 視 し て い る デ ィ レ ク ト リ 内 の フ ァ イ ル に 対 し て イ ベ ン ト が 返 さ れ る 場 合 の た め に だ け 存 在 す る 。 監 視 す る デ ィ レ ク ト リ 内 の フ ァ イ ル 名 を 表 す 。 こ の フ ァ イ ル 名 は ヌ ル で 終 端 さ れ 、 そ の 後 の 読 み 込 み で 適 切 な ア ド レ ス 境 界 に 調 整 す る た め に 、 さ ら に ヌ ル バ イ ト ('\0') が 含 ま れ る 場 合 も あ る 。

len フ ィ ー ル ド は ヌ ル バ イ ト を 含 む 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 (2), execve (2) な ど で ) フ ァ イ ル が ア ク セ ス さ れ た 。

IN_ATTRIB (*)

メ タ デ ー タ が 変 更 さ れ た 。 メ タ デ ー タ と は 、 例 え ば 、 ア ク セ ス 許 可 ( chmod (2))、 タ イ ム ス タ ン プ ( utimensat (2) な ど )、 拡 張 属 性 ( setxattr (2))、 リ ン ク カ ウ ン ト (Linux 2.6.25 以 降 ; link (2) の リ ン ク 先 や unlink (2) な ど )、 ユ ー ザ ー /グ ル ー プ ID ( chown (2) な ど ) な ど で あ る 。

IN_CLOSE_WRITE (+)

書 き 込 み の た め に オ ー プ ン さ れ た フ ァ イ ル が ク ロ ー ズ さ れ た 。

IN_CLOSE_NOWRITE (*)

書 き 込 み 用 と し て は オ ー プ ン さ れ て い な い フ ァ イ ル や デ ィ レ ク ト リ が ク ロ ー ズ さ れ た 。

IN_CREATE (+)

監 視 対 象 デ ィ レ ク ト リ 内 で フ ァ イ ル や デ ィ レ ク ト リ が 作 成 さ れ た ( open (2) O_CREAT , mkdir (2), link (2), symlink (2), UNIX ド メ イ ン ソ ケ ッ ト に 対 す る bind (2) な ど )。

IN_DELETE (+)

監 視 対 象 デ ィ レ ク ト リ 内 で フ ァ イ ル や デ ィ レ ク ト リ が 削 除 さ れ た 。

IN_DELETE_SELF

監 視 対 象 の フ ァ イ ル や デ ィ レ ク ト リ 自 身 が 削 除 あ れ た 。 (こ の イ ベ ン ト は オ ブ ジ ェ ク ト が 別 の フ ァ イ ル シ ス テ ム に 移 動 さ れ た 場 合 に も 発 生 す る 。 mv (1) は 実 際 に は 別 の フ ァ イ ル シ ス テ ム に フ ァ イ ル を コ ピ ー し た 後 、 元 の フ ァ イ ル シ ス テ ム か ら そ の フ ァ イ ル を 削 除 す る か ら で あ る 。 ) ま た 、 結 果 的 に 監 視 デ ィ ス ク リ プ タ ー に 対 し て IN_IGNORED イ ベ ン ト も 生 成 さ れ る 。

IN_MODIFY (+)

フ ァ イ ル が 変 更 さ れ た ( write (2), truncate (2) な ど )。

IN_MOVE_SELF

監 視 対 象 の デ ィ レ ク ト リ ま た は フ ァ イ ル 自 身 が 移 動 さ れ た 。

IN_MOVED_FROM (+)

フ ァ イ ル 名 の 変 更 を 行 っ た 際 に 変 更 前 の フ ァ イ ル 名 が 含 ま れ る デ ィ レ ク ト リ に 対 し て 生 成 さ れ る 。

IN_MOVED_TO (+)

フ ァ イ ル 名 の 変 更 を 行 っ た 際 に 新 し い フ ァ イ ル 名 が 含 ま れ る デ ィ レ ク ト リ に 対 し て 生 成 さ れ る 。

IN_OPEN (*)

フ ァ イ ル や デ ィ レ ク ト リ が オ ー プ ン さ れ た 。

Inotify monitoring is inode-based: when monitoring a file (but not when monitoring the directory containing a file), an event can be generated for activity on any link to the file (in the same or a different directory).

デ ィ レ ク ト リ を 監 視 す る 場 合 :

*

上 記 で ア ス タ リ ス ク (*) が 付 い た イ ベ ン ト は 、 デ ィ レ ク ト リ 自 身 と デ ィ レ ク ト リ 内 の オ ブ ジ ェ ク ト の ど ち ら に 対 し て も 発 生 す る 。

*

上 記 で プ ラ ス 記 号 (+) が 付 い た イ ベ ン ト は 、 デ ィ レ ク ト リ 内 の オ ブ ジ ェ ク ト に 対 し て の み 発 生 す る (デ ィ レ ク ト リ 自 身 に 対 し て は 発 生 し な い )。

Note : when monitoring a directory, events are not generated for the files inside the directory when the events are performed via a pathname (i.e., a link) that lies outside the monitored directory.

監 視 対 象 の デ ィ レ ク ト リ 内 の オ ブ ジ ェ ク ト に 対 し て イ ベ ン ト が 発 生 し た 場 合 、 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 (Linux 2.6.15 以 降 )

pathname が シ ン ボ リ ッ ク リ ン ク で あ る 場 合 に 辿 ら な い 。 (Linux 2.6.15 以 降 )

IN_EXCL_UNLINK (Linux 2.6.36 以 降 )

デ フ ォ ル ト で は 、 あ る デ ィ レ ク ト リ の 子 フ ァ イ ル に 関 す る イ ベ ン ト を 監 視 (watch) し た 際 、 デ ィ レ ク ト リ か ら そ の 子 フ ァ イ ル が 削 除 (unlink) さ れ た 場 合 で あ っ て も そ の 子 フ ァ イ ル に 対 し て イ ベ ン ト が 生 成 さ れ る 。 こ の こ と は 、 ア プ リ ケ ー シ ョ ン に よ っ て は あ ま り 興 味 の な い イ ベ ン ト が 大 量 に 発 生 す る こ と に つ な が る (例 え ば 、 /tmp を 監 視 し て い る 場 合 、 た く さ ん の ア プ リ ケ ー シ ョ ン が 、 す ぐ に そ の 名 前 が 削 除 さ れ る 一 時 フ ァ イ ル を そ の デ ィ レ ク ト リ に 作 成 す る )。 IN_EXCL_UNLINK を 指 定 す る と こ の デ フ ォ ル ト の 動 作 を 変 更 で き 、 監 視 対 象 の デ ィ レ ク ト リ か ら 子 フ ァ イ ル が 削 除 さ れ た 後 に 子 フ ァ イ ル に 関 す る イ ベ ン ト が 生 成 さ れ な く な る 。

IN_MASK_ADD

If a watch instance already exists for the filesystem object corresponding to pathname , add (OR) the events in mask to the watch mask (instead of replacing the mask); the error EINVAL results if IN_MASK_CREATE is also specified.

IN_ONESHOT

pathname に 対 応 す る フ ァ イ ル シ ス テ ム オ ブ ジ ェ ク ト を 1 イ ベ ン ト に つ い て だ け 監 視 し 、 イ ベ ン ト が 発 生 し た ら 監 視 対 象 リ ス ト か ら 削 除 す る 。

IN_ONLYDIR (Linux 2.6.15 以 降 )

Watch pathname only if it is a directory; the error ENOTDIR results if pathname is not a directory. Using this flag provides an application with a race-free way of ensuring that the monitored object is a directory.

IN_MASK_CREATE (Linux 4.18 以 降 )

Watch pathname only if it does not already have a watch associated with it; the error EEXIST results if pathname is already being watched.

Using this flag provides an application with a way of ensuring that new watches do not modify existing ones. This is useful because multiple paths may refer to the same inode, and multiple calls to inotify_add_watch (2) without this flag may clobber existing watch masks.

以 下 の ビ ッ ト が read (2) で 返 さ れ る mask フ ィ ー ル ド に 設 定 さ れ る :

IN_IGNORED

監 視 対 象 が ( inotify_rm_watch (2) に よ り ) 明 示 的 に 削 除 さ れ た 。 も し く は (フ ァ イ ル の 削 除 、 ま た は フ ァ イ ル シ ス テ ム の ア ン マ ウ ン ト に よ り ) 自 動 的 に 削 除 さ れ た 。 「 バ グ 」 も 参 照 の こ と 。

IN_ISDIR

こ の イ ベ ン ト の 対 象 が デ ィ レ ク ト リ で あ る 。

IN_Q_OVERFLOW

イ ベ ン ト キ ュ ー が 溢 れ た (こ の イ ベ ン ト の 場 合 、 wd は -1 で あ る )。

IN_UNMOUNT

監 視 対 象 オ ブ ジ ェ ク ト を 含 む フ ァ イ ル シ ス テ ム が ア ン マ ウ ン ト さ れ た 。 さ ら に 、 こ の 監 視 対 象 デ ィ ス ク リ プ タ ー に 対 し て IN_IGNORED イ ベ ン ト が 生 成 さ れ る 。

ア プ リ ケ ー シ ョ ン が デ ィ レ ク ト リ dir と フ ァ イ ル dir/myfile の す べ て の イ ベ ン ト を 監 視 し て い る と す る 。 以 下 に 、 こ れ ら の 2 つ の オ ブ ジ ェ ク ト に 対 し て 生 成 さ れ る イ ベ ン ト の 例 を 示 す 。

fd = open("dir/myfile", O_RDWR);

dir dir/myfile の 両 方 に 対 し て IN_OPEN イ ベ ン ト が 生 成 さ れ る 。

read(fd, buf, count);

dir dir/myfile の 両 方 に 対 し て IN_ACCESS イ ベ ン ト が 生 成 さ れ る

write(fd, buf, count);

dir dir/myfile の 両 方 に 対 し て IN_MODIFY イ ベ ン ト が 生 成 さ れ る

fchmod(fd, mode);

dir dir/myfile の 両 方 に 対 し て IN_ATTRIB イ ベ ン ト が 生 成 さ れ る

close(fd);

dir dir/myfile の 両 方 に 対 し て IN_CLOSE_WRITE イ ベ ン ト が 生 成 さ れ る

ア プ リ ケ ー シ ョ ン が デ ィ レ ク ト リ dir1 dir2 、 お よ び フ ァ イ ル dir1/myfile を 監 視 し て い る と す る 。 以 下 に 生 成 さ れ る イ ベ ン ト の 例 を 示 す 。

link("dir1/myfile", "dir2/new");

myfile に 対 し て IN_ATTRIB イ ベ ン ト が 生 成 さ れ 、 dir2 に 対 し て IN_CREATE イ ベ ン ト が 生 成 さ れ る 。

rename("dir1/myfile", "dir2/myfile");

dir1 に 対 し て イ ベ ン ト IN_MOVED_FROM が 、 dir2 に 対 し て イ ベ ン ト IN_MOVED_TO が 、 myfile に 対 し て イ ベ ン ト IN_MOVE_SELF が 生 成 さ れ る 。 こ の 際 イ ベ ン ト IN_MOVED_FROM IN_MOVED_TO は 同 じ cookie 値 を 持 つ 。

dir1/xx dir2/yy は 同 じ フ ァ イ ル を 参 照 す る リ ン ク で (他 の リ ン ク は な い も の と す る )、 ア プ リ ケ ー シ ョ ン は dir1 , dir2 , dir1/xx , dir2/yy を 監 視 し て い る も の と す る 。 以 下 に 示 す 順 序 で 下 記 の 呼 び 出 し を 実 行 す る と 、 以 下 の イ ベ ン ト が 生 成 さ れ る 。

unlink("dir2/yy");

xx に 対 し て IN_ATTRIB イ ベ ン ト が 生 成 さ れ (リ ン ク 数 が 変 化 し た た め )、 dir2 に 対 し て IN_DELETE イ ベ ン ト が 生 成 さ れ る 。

unlink("dir1/xx");

xx に 対 し て イ ベ ン ト IN_ATTRIB , IN_DELETE_SELF , IN_IGNORED が 生 成 さ れ 、 dir1 に 対 し て IN_DELETE イ ベ ン ト が 生 成 さ れ る 。

ア プ リ ケ ー シ ョ ン が デ ィ レ ク ト リ dir と (空 の ) デ ィ レ ク ト リ dir/subdir を 監 視 し て い る も の と す る 。 以 下 に 生 成 さ れ る イ ベ ン ト の 例 を 示 す 。

mkdir("dir/new", mode);

dir に 対 し て IN_CREATE | IN_ISDIR イ ベ ン ト が 生 成 さ れ る 。

rmdir("dir/subdir");

subdir に 対 し て イ ベ ン ト IN_DELETE_SELF IN_IGNORED が 生 成 さ れ 、 dir に 対 し て IN_DELETE | IN_ISDIR イ ベ ン ト が 生 成 さ れ る 。

/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 は glibc バ ー ジ ョ ン 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 フ ァ イ ル デ ィ ス ク リ プ タ ー の 読 み 込 み で 返 さ れ る イ ベ ン ト は 、 順 序 付 け ら れ た キ ュ ー に な る 。 従 っ て 、 た と え ば 、 あ る デ ィ レ ク ト リ の 名 前 を 別 の 名 前 に 変 更 し た 場 合 、 inotify フ ァ イ ル デ ィ ス ク リ プ タ ー に つ い て の 正 し い 順 番 で イ ベ ン ト が 生 成 さ れ る こ と が 保 証 さ れ る 。

The set of watch descriptors that is being monitored via an inotify file descriptor can be viewed via the entry for the inotify file descriptor in the process’s /proc/[pid]/fdinfo directory. See proc (5) for further details. The FIONREAD ioctl (2) returns the number of bytes available to read from an inotify file descriptor.

制 限 と 警 告

inotify API で は 、 inotify イ ベ ン ト が 発 生 す る き っ か け と な っ た ユ ー ザ ー や プ ロ セ ス に 関 す る 情 報 は 提 供 さ れ な い 。 と り わ け 、 inotify 経 由 で イ ベ ン ト を 監 視 し て い る プ ロ セ ス が 、 自 分 自 身 が き っ か け と な っ た イ ベ ン ト と 他 の プ ロ セ ス が き っ か け と な っ た イ ベ ン ト を 区 別 す る 簡 単 な 手 段 は な い 。

inotify は 、 フ ァ イ ル シ ス テ ム API 経 由 で ユ ー ザ ー 空 間 プ ロ グ ラ ム が き っ か け と な っ た イ ベ ン ト だ け を 報 告 す る 。 結 果 と し て 、 inotify は ネ ッ ト ワ ー ク フ ァ イ ル シ ス テ ム で 発 生 し た リ モ ー ト の イ ベ ン ト を 捉 え る こ と は で き な い (こ の よ う な イ ベ ン ト を 捉 え る に は ア プ リ ケ ー シ ョ ン は フ ァ イ ル シ ス テ ム を ポ ー リ ン グ す る 必 要 が あ る )。 さ ら に 、 /proc , /sys , /dev/pts と い っ た い く つ か の 疑 似 フ ァ イ ル シ ス テ ム は inotify で 監 視 す る こ と が で き な い 。

inotify API は mmap (2), msync (2), munmap (2) に よ り 起 こ っ た フ ァ イ ル の ア ク セ ス と 変 更 を 報 告 し な い 。

inotify API で は 影 響 が 受 け る フ ァ イ ル を フ ァ イ ル 名 で 特 定 す る 。 し か し な が ら 、 ア プ リ ケ ー シ ョ ン が inotify イ ベ ン ト を 処 理 す る 時 点 で は 、 そ の フ ァ イ ル 名 が す で に 削 除 さ れ た り 変 更 さ れ た り し て い る 可 能 性 が あ る 。

inotify API で は 監 視 対 象 デ ィ ス ク リ プ タ ー を 通 し て イ ベ ン ト が 区 別 さ れ る 。 (必 要 で あ れ ば ) 監 視 対 象 デ ィ ス ク リ プ タ ー と パ ス 名 の マ ッ ピ ン グ を キ ャ ッ シ ュ し て お く の は ア プ リ ケ ー シ ョ ン の 役 目 で あ る 。 デ ィ レ ク ト リ の 名 前 変 更 の 場 合 、 キ ャ ッ シ ュ し て い る 複 数 の パ ス 名 に 影 響 が あ る 点 に 注 意 す る こ と 。

inotify に よ る デ ィ レ ク ト リ の 監 視 は 再 帰 的 に 行 わ れ な い : あ る デ ィ レ ク ト リ 以 下 の サ ブ デ ィ レ ク ト リ を 監 視 す る 場 合 、 監 視 対 象 を 追 加 で 作 成 し な け れ ば な ら な い 。 大 き な デ ィ レ ク ト リ ツ リ ー の 場 合 に は 、 こ の 作 業 に か な り 時 間 が か か る こ と が あ る 。

デ ィ レ ク ト リ ツ リ ー 全 体 を 監 視 し て い て 、 そ の ツ リ ー 内 に 新 し い サ ブ デ ィ レ ク ト リ が 作 成 さ れ る か 、 既 存 の デ ィ レ ク ト リ が 名 前 が 変 更 さ れ そ の ツ リ ー 内 に 移 動 し た 場 合 、 新 し い サ ブ デ ィ レ ク ト リ に 対 す る watch を 作 成 す る ま で に 、 新 し い フ ァ イ ル (や サ ブ デ ィ レ ク ト リ ) が そ の サ ブ デ ィ レ ク ト リ 内 に す で に 作 成 さ れ て い る 場 合 が あ る 点 に 注 意 す る こ と 。 し た が っ て 、 watch を 追 加 し た 直 後 に サ ブ デ ィ レ ク ト リ の 内 容 を ス キ ャ ン し た い と 思 う 場 合 も あ る だ ろ う (必 要 な ら そ の サ ブ デ ィ レ ク ト リ 内 の サ ブ デ ィ レ ク ト リ に 対 す る watch も 再 帰 的 に 追 加 す る こ と も あ る だ ろ う )。

イ ベ ン ト キ ュ ー は オ ー バ ー フ ロ ー す る 場 合 が あ る こ と に 注 意 す る こ と 。 こ の 場 合 、 イ ベ ン ト は 失 な わ れ る 。 ロ バ ス ト 性 が 求 め ら れ る ア プ リ ケ ー シ ョ ン で は 、 イ ベ ン ト が 失 な わ れ る 可 能 性 も 含 め て 適 切 に 処 理 を 行 う べ き で あ る 。 例 え ば 、 ア プ リ ケ ー シ ョ ン 内 の キ ャ ッ シ ュ の 一 部 分 ま た は 全 て を 再 構 築 す る 必 要 が あ る か も し れ な い 。 (単 純 だ が 、 お そ ら く コ ス ト が か か る 方 法 は 、 inotify フ ァ イ ル デ ィ ス ク リ プ タ ー を ク ロ ー ズ し 、 キ ャ ッ シ ュ を 空 に し 、 新 し い inotify フ ァ イ ル デ ィ ス ク リ プ タ ー を 作 成 し 、 監 視 し て い る オ ブ ジ ェ ク ト の 監 視 対 象 デ ィ ス ク リ プ タ ー と キ ャ ッ シ ュ エ ン ト リ ー の 再 作 成 を 行 う 方 法 で あ る 。 )

If a filesystem is mounted on top of a monitored directory, no event is generated, and no events are generated for objects immediately under the new mount point. If the filesystem is subsequently unmounted, events will subsequently be generated for the directory and the objects it contains.

rename() イ ベ ン ト の 取 り 扱 い

上 述 の 通 り 、 rename (2) に よ り 生 成 さ れ る IN_MOVED_FROM IN_MOVED_TO イ ベ ン ト の 組 は 、 共 有 さ れ る cookie 値 に よ っ て 対 応 を 取 る こ と が で き る 。 し か し 、 対 応 を 取 る 場 合 に は い く つ か 難 し い 点 が あ る 。

こ れ ら の 2 つ の イ ベ ン ト は 、 inotify フ ァ イ ル デ ィ ス ク リ プ タ ー か ら 読 み 出 し を 行 っ た 場 合 に 、 通 常 は イ ベ ン ト ス ト リ ー ム 内 で 連 続 し て い る 。 し か し な が ら 、 連 続 し て い る こ と は 保 証 さ れ て い な い 。 複 数 の プ ロ セ ス が 監 視 対 象 オ ブ ジ ェ ク ト で イ ベ ン ト を 発 生 さ せ た 場 合 、 (め っ た に 起 こ ら な い こ と だ が ) イ ベ ン ト IN_MOVED_FROM IN_MOVED_TO の 間 に 任 意 の 数 の 他 の イ ベ ン ト が は さ ま る 可 能 性 が あ る 。 さ ら に 、 対 と な る イ ベ ン ト が ア ト ミ ッ ク に キ ュ ー に 挿 入 さ れ る こ と も 保 証 さ れ て い な い 。 IN_MOVED_FROM が 現 れ た が IN_MOVED_TO は 現 れ て い な い と い う 短 い 期 間 が あ り え る と い う こ と だ 。

し た が っ て 、 rename (2) に よ り 生 成 さ れ た IN_MOVED_FROM IN_MOVED_TO の イ ベ ン ト の 組 の 対 応 を 取 る の は 本 質 的 に 難 し い こ と で あ る (監 視 対 象 の デ ィ レ ク ト リ の 外 へ オ ブ ジ ェ ク ト の rename が 行 わ れ た 場 合 に は IN_MOVED_TO イ ベ ン ト は 存 在 し さ え し な い こ と を 忘 れ て は な ら な い )。 (イ ベ ン ト は 常 に 連 続 し て い る と の 仮 定 を 置 く と い っ た ) 発 見 的 な 方 法 を 使 う と 、 ほ と ん ど の 場 合 で イ ベ ン ト の 組 を う ま く 見 つ け る こ と が で き る が 、 い く つ か の 場 合 に 見 逃 す こ と が 避 け ら れ ず 、 ア プ リ ケ ー シ ョ ン が IN_MOVED_FROM IN_MOVED_TO イ ベ ン ト が 無 関 係 だ と み な し て し ま う 可 能 性 が あ る 。 結 果 的 に 、 監 視 対 象 デ ィ ス ク リ プ タ ー が 破 棄 さ れ 再 作 成 さ れ た 場 合 、 こ れ ら の 監 視 対 象 デ ィ ス ク リ プ タ ー は 、 処 理 待 ち イ ベ ン ト の 監 視 対 象 デ ィ ス ク リ プ タ ー と 一 貫 性 の な い も の に な っ て し ま う (inotify フ ァ イ ル デ ィ ス ク リ プ タ ー の 再 作 成 と キ ャ ッ シ ュ の 再 構 成 は こ の 状 況 に 対 処 す る の に 有 用 な 方 法 な の だ が )。

ま た 、 ア プ リ ケ ー シ ョ ン は 、 IN_MOVED_FROM イ ベ ン ト が 今 行 っ た read (2) の 呼 び 出 し で 返 さ れ た バ ッ フ ァ ー の ち ょ う ど 一 番 最 後 の イ ベ ン ト で 、 IN_MOVED_TO イ ベ ン ト は 次 の read (2) を 行 わ な い と 取 得 で き な い 可 能 性 も 考 慮 に 入 れ る 必 要 が あ る 。 2 つ 目 の read (2) は (短 い ) タ イ ム ア ウ ト で 行 う べ き で あ る 。 こ れ は 、 IN_MOVED_FROM - IN_MOVED_TO の イ ベ ン ト ペ ア の キ ュ ー へ の 挿 入 は ア ト ミ ッ ク で は な く 、 ま た IN_MOVED_TO イ ベ ン ト が 全 く 発 生 し な い 可 能 性 も あ る と い う 事 実 を 考 慮 に 入 れ て お く 必 要 が あ る か ら で あ る 。

バ グ

Before Linux 3.19, fallocate (2) did not create any inotify events. Since Linux 3.19, calls to fallocate (2) generate IN_MODIFY events.

2.6.16 以 前 の カ ー ネ ル で は IN_ONESHOT mask フ ラ グ が 働 か な い 。

元 々 は 設 計 /実 装 時 の 意 図 通 り 、 イ ベ ン ト が 一 つ 発 生 し watch が 削 除 さ れ た 際 に IN_ONESHOT フ ラ グ で は IN_IGNORED イ ベ ン ト が 発 生 し な か っ た 。 し か し 、 別 の 変 更 で の 意 図 し て い な か っ た 影 響 に よ り 、 Linux 2.6.36 以 降 で は 、 こ の 場 合 に IN_IGNORED イ ベ ン ト が 生 成 さ れ る 。

カ ー ネ ル 2.6.25 よ り 前 で は 、 連 続 す る 同 一 の イ ベ ン ト を 一 つ に ま と め る こ と を 意 図 し た コ ー ド (古 い 方 の イ ベ ン ト が ま だ 読 み 込 ま れ て い な い 場 合 に 、 最 新 の 2 つ の イ ベ ン ト を 一 つ に ま と め ら れ る 可 能 性 が あ る ) が 、 最 新 の イ ベ ン ト が 「 最 も 古 い 」 読 み 込 ま れ て い な い イ ベ ン ト と ま と め ら れ る か を チ ェ ッ ク す る よ う に な っ て い た 。

inotify_rm_watch (2) の 呼 び 出 し に よ り 監 視 対 象 デ ィ ス ク リ プ タ ー が 削 除 さ れ た 場 合 (な お 、 監 視 対 象 フ ァ イ ル の 削 除 や 監 視 対 象 フ ァ イ ル が 含 ま れ る フ ァ イ ル シ ス テ ム の ア ン マ ウ ン ト に よ っ て も 監 視 対 象 デ ィ ス ク リ プ タ ー は 削 除 さ れ る )、 こ の 監 視 対 象 デ ィ ス ク リ プ タ ー 関 連 の 処 理 待 ち の 未 読 み 出 し イ ベ ン ト は 、 読 み 出 し 可 能 な ま ま と な る 。 監 視 対 象 デ ィ ス ク リ プ タ ー は inotify_add_watch (2) に よ っ て 後 で 割 り 当 て ら れ る た め 、 カ ー ネ ル は 利 用 可 能 な 監 視 対 象 デ ィ ス ク リ プ タ ー の 範 囲 (0 か ら INT_MAX ) か ら 昇 順 に サ イ ク リ ッ ク に 割 り 当 て を 行 う 。 未 使 用 の 監 視 対 象 デ ィ ス ク リ プ タ ー を 割 り 当 て る 際 、 そ の 監 視 対 象 デ ィ ス ク リ プ タ ー 番 号 に inotify キ ュ ー で 処 理 待 ち の 未 読 み 出 し イ ベ ン ト が あ る か の 確 認 は 行 わ れ な い 。 し た が っ て 、 監 視 対 象 デ ィ ス ク リ プ タ ー が 再 割 り 当 て さ れ た 際 に 、 そ の 監 視 対 象 デ ィ ス ク リ プ タ ー の 一 つ 前 の 使 用 時 に 発 生 し た 処 理 待 ち の 未 読 み 出 し イ ベ ン ト が 存 在 す る と い う こ と が 起 こ り う る 。 そ の 結 果 、 ア プ リ ケ ー シ ョ ン は こ れ ら の イ ベ ン ト を 読 み 出 す 可 能 性 が あ り 、 こ れ ら の イ ベ ン ト が 新 し く 再 利 用 さ れ た 監 視 対 象 デ ィ ス ク リ プ タ ー に 関 連 付 け ら れ た フ ァ イ ル に 属 す る も の か を 解 釈 す る 必 要 が 出 て 来 る 。 実 際 の と こ ろ 、 こ の バ グ を 踏 む 可 能 性 は 極 め て 低 い 。 そ れ は 、 こ の バ グ を 踏 む た め に は 、 ア プ リ ケ ー シ ョ ン が INT_MAX 個 の 監 視 対 象 デ ィ ス ク リ プ タ ー が 一 周 さ せ て 、 キ ュ ー に 未 読 み 出 し イ ベ ン ト が 残 っ て い る 監 視 対 象 デ ィ ス ク リ プ タ ー を 解 放 し 、 そ の 監 視 対 象 デ ィ ス ク リ プ タ ー を 再 利 用 す る 必 要 が あ る か ら で あ る 。 こ の 理 由 と 、 実 世 界 の ア プ リ ケ ー シ ョ ン で 発 生 し た と い う バ グ 報 告 が な い こ と か ら 、 Linux 3.15 時 点 で は 、 こ の 計 算 上 は 起 こ り う る バ グ を 取 り 除 く た め の カ ー ネ ル の 変 更 は 行 わ れ て い な い 。

以 下 の プ ロ グ ラ ム は inotify API の 使 用 例 を 示 し た も の で あ る 。 コ マ ン ド ラ イ ン 引 数 で 渡 さ れ た デ ィ レ ク ト リ に 印 を 付 け 、 タ イ プ が IN_OPEN , IN_CLOSE_NOWRITE IN_CLOSE_WRITE の イ ベ ン ト を 待 つ 。

以 下 は 、 フ ァ イ ル /home/user/temp/foo を 編 集 し 、 デ ィ レ ク ト リ /tmp の 一 覧 表 示 を 行 っ た 場 合 の 出 力 で あ る 。 対 象 の フ ァ イ ル と デ ィ レ ク ト リ が オ ー プ ン さ れ る 前 に 、 イ ベ ン ト IN_OPEN が 発 生 し て い る 。 対 象 フ ァ イ ル が ク ロ ー ズ さ れ た 後 に イ ベ ン ト IN_CLOSE_WRITE が 発 生 し て い る 。 対 象 デ ィ レ ク ト リ が ク ロ ー ズ さ れ た 後 に イ ベ ン ト IN_CLOSE_NOWRITE が 発 生 し て い る 。 ユ ー ザ ー が ENTER キ ー を 押 す る と 、 プ ロ グ ラ ム の 実 行 は 終 了 す る 。

出 力 例

$ ./a.out /tmp /home/user/temp
Press enter key to terminate.
Listening for events.
IN_OPEN: /home/user/temp/foo [file]
IN_CLOSE_WRITE: /home/user/temp/foo [file]
IN_OPEN: /tmp/ [directory]
IN_CLOSE_NOWRITE: /tmp/ [directory]

Listening for events stopped.

プ ロ グ ラ ム ソ ー ス

#include <errno.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <string.h>

/* Read all available inotify events from the file descriptor 'fd'.
wd is the table of watch descriptors for the directories in argv.
argc is the length of wd and argv.
argv is the list of watched directories.
Entry 0 of wd and argv is unused. */

static void
handle_events(int fd, int *wd, int argc, char* argv[])
{
/* Some systems cannot read integer variables if they are not
properly aligned. On other systems, incorrect alignment may
decrease performance. Hence, the buffer used for reading from
the inotify file descriptor should have the same alignment as
struct inotify_event. */

char buf[4096]
__attribute__ ((aligned(__alignof__(struct inotify_event))));
const struct inotify_event *event;
ssize_t len;

/* Loop while events can be read from inotify file descriptor. */

for (;;) {

/* Read some events. */

len = read(fd, buf, sizeof(buf));
if (len == -1 && errno != EAGAIN) {
perror("read");
exit(EXIT_FAILURE);
}

/* If the nonblocking read() found no events to read, then
it returns -1 with errno set to EAGAIN. In that case,
we exit the loop. */

if (len <= 0)
break;

/* バ ッ フ ァ ー 内 の 全 イ ベ ン ト を 処 理 す る */

for (char *ptr = buf; ptr < buf + len;
ptr += sizeof(struct inotify_event) + event->len) {

event = (const struct inotify_event *) ptr;

/* Print event type */

if (event->mask & IN_OPEN)
printf("IN_OPEN: ");
if (event->mask & IN_CLOSE_NOWRITE)
printf("IN_CLOSE_NOWRITE: ");
if (event->mask & IN_CLOSE_WRITE)
printf("IN_CLOSE_WRITE: ");

/* Print the name of the watched directory */

for (int i = 1; i < argc; ++i) {
if (wd[i] == event->wd) {
printf("%s/", argv[i]);
break;
}
}

/* Print the name of the file */

if (event->len)
printf("%s", event->name);

/* Print type of filesystem object */

if (event->mask & IN_ISDIR)
printf(" [directory]\n");
else
printf(" [file]\n");
}
}
}

int
main(int argc, char* argv[])
{
char buf;
int fd, i, poll_num;
int *wd;
nfds_t nfds;
struct pollfd fds[2];

if (argc < 2) {
printf("Usage: %s PATH [PATH ...]\n", argv[0]);
exit(EXIT_FAILURE);
}

printf("Press ENTER key to terminate.\n");

/* Create the file descriptor for accessing the inotify API */

fd = inotify_init1(IN_NONBLOCK);
if (fd == -1) {
perror("inotify_init1");
exit(EXIT_FAILURE);
}

/* Allocate memory for watch descriptors */

wd = calloc(argc, sizeof(int));
if (wd == NULL) {
perror("calloc");
exit(EXIT_FAILURE);
}

/* Mark directories for events
- file was opened
- file was closed */

for (i = 1; i < argc; i++) {
wd[i] = inotify_add_watch(fd, argv[i],
IN_OPEN | IN_CLOSE);
if (wd[i] == -1) {
fprintf(stderr, "Cannot watch '%s': %s\n",
argv[i], strerror(errno));
exit(EXIT_FAILURE);
}
}

/* ポ ー リ ン グ の 準 備 */

nfds = 2;

/* コ ン ソ ー ル の 入 力 */

fds[0].fd = STDIN_FILENO;
fds[0].events = POLLIN;

/* Inotify input */

fds[1].fd = fd;
fds[1].events = POLLIN;

/* Wait for events and/or terminal input */

printf("Listening for events.\n");
while (1) {
poll_num = poll(fds, nfds, -1);
if (poll_num == -1) {
if (errno == EINTR)
continue;
perror("poll");
exit(EXIT_FAILURE);
}

if (poll_num > 0) {

if (fds[0].revents & POLLIN) {

/* Console input is available. Empty stdin and quit */

while (read(STDIN_FILENO, &buf, 1) > 0 && buf != '\n')
continue;
break;
}

if (fds[1].revents & POLLIN) {

/* Inotify events are available */

handle_events(fd, wd, argc, argv);
}
}
}

printf("Listening for events stopped.\n");

/* Close inotify file descriptor */

close(fd);

free(wd);
exit(EXIT_SUCCESS);
}

関 連 項 目

inotifywait (1), inotifywatch (1), inotify_add_watch (2), inotify_init (2), inotify_init1 (2), inotify_rm_watch (2), read (2), stat (2), fanotify (7)

Linux カ ー ネ ル ソ ー ス 内 の Documentation/filesystems/inotify.txt

こ の 文 書 に つ い て

こ の man ペ ー ジ は Linux man-pages プ ロ ジ ェ ク ト の リ リ ー ス 5.10 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は https://www.kernel.org/doc/man-pages/ に 書 か れ て い る 。