Manpages

名 前

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_FROMIN_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_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
監 視 イ ン ス タ ン ス が pathname に 対 応 す る フ ァ イ ル シ ス テ ム オ ブ ジ ェ ク ト に 対 し て す で に 存 在 す る 場 合 に 、 (マ ス ク を 置 き 換 え る の で は な く ) 監 視 マ ス ク に mask で 指 定 さ れ た イ ベ ン ト を 追 加 (OR) す る 。
IN_ONESHOT

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

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
監 視 対 象 オ ブ ジ ェ ク ト を 含 む フ ァ イ ル シ ス テ ム が ア ン マ ウ ン ト さ れ た 。 さ ら に 、 こ の 監 視 対 象 デ ィ ス ク リ プ タ ー に 対 し て IN_IGNORED イ ベ ン ト が 生 成 さ れ る 。 ア プ リ ケ ー シ ョ ン が デ ィ レ ク ト リ dir と フ ァ イ ル dir/myfile の す べ て の イ ベ ン ト を 監 視 し て い る と す る 。 以 下 に 、 こ れ ら の 2 つ の オ ブ ジ ェ ク ト に 対 し て 生 成 さ れ る イ ベ ン ト の 例 を 示 す 。
fd = open("dir/myfile", O_RDWR);

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

read(fd, buf, count);

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

write(fd, buf, count);

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

fchmod(fd, mode);

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

close(fd);

dirdir/myfile の 両 方 に 対 し て IN_CLOSE_WRITE イ ベ ン ト が 生 成 さ れ る ア プ リ ケ ー シ ョ ン が デ ィ レ ク ト リ dir1dir2、 お よ び フ ァ イ ル 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_FROMIN_MOVED_TO は 同 じ cookie 値 を 持 つ 。

dir1/xxdir2/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_SELFIN_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_tsigaction(2) で 説 明 さ れ て い る )。 si_fd に は inotify フ ァ イ ル デ ィ ス ク リ プ タ ー 番 号 が 、 si_signo に は シ グ ナ ル 番 号 が 、 si_code に は POLL_IN が 、 si_band に は POLLIN が 設 定 さ れ る 。

inotify フ ァ イ ル デ ィ ス ク リ プ タ ー に 対 し て 連 続 し て 生 成 さ れ る 出 力 inotify イ ベ ン ト が 同 一 の 場 合 (wd, mask, cookie, name が 等 し い 場 合 )、 前 の イ ベ ン ト が ま だ 読 み 込 ま れ て い な け れ ば 、 連 続 す る イ ベ ン ト が 1 つ の イ ベ ン ト に ま と め ら れ る (た だ し 「 バ グ 」 の 節 も 参 照 の こ と )。 こ れ に よ り イ ベ ン ト キ ュ ー に 必 要 な カ ー ネ ル メ モ リ ー 量 が 減 る が 、 こ れ は ま た ア プ リ ケ ー シ ョ ン が フ ァ イ ル イ ベ ン ト 数 を 信 頼 性 を 持 っ て 数 え る の に inotify を 使 用 で き な い と い う こ と で も あ る 。

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

FIONREAD ioctl(2) は inotify フ ァ イ ル デ ィ ス ク リ プ タ ー か ら 何 バ イ ト 読 み 込 め る か を 返 す 。 制 限 と 警 告
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 フ ァ イ ル デ ィ ス ク リ プ タ ー を 作 成 し 、 監 視 し て い る オ ブ ジ ェ ク ト の 監 視 対 象 デ ィ ス ク リ プ タ ー と キ ャ ッ シ ュ エ ン ト リ ー の 再 作 成 を 行 う 方 法 で あ る 。 )

rename() イ ベ ン ト の 取 り 扱 い 上 述 の 通 り 、 rename(2) に よ り 生 成 さ れ る IN_MOVED_FROMIN_MOVED_TO イ ベ ン ト の 組 は 、 共 有 さ れ る cookie 値 に よ っ て 対 応 を 取 る こ と が で き る 。 し か し 、 対 応 を 取 る 場 合 に は い く つ か 難 し い 点 が あ る 。 こ れ ら の 2 つ の イ ベ ン ト は 、 inotify フ ァ イ ル デ ィ ス ク リ プ タ ー か ら 読 み 出 し を 行 っ た 場 合 に 、 通 常 は イ ベ ン ト ス ト リ ー ム 内 で 連 続 し て い る 。 し か し な が ら 、 連 続 し て い る こ と は 保 証 さ れ て い な い 。 複 数 の プ ロ セ ス が 監 視 対 象 オ ブ ジ ェ ク ト で イ ベ ン ト を 発 生 さ せ た 場 合 、 (め っ た に 起 こ ら な い こ と だ が ) イ ベ ン ト IN_MOVED_FROMIN_MOVED_TO の 間 に 任 意 の 数 の 他 の イ ベ ン ト が は さ ま る 可 能 性 が あ る 。 さ ら に 、 対 と な る イ ベ ン ト が ア ト ミ ッ ク に キ ュ ー に 挿 入 さ れ る こ と も 保 証 さ れ て い な い 。 IN_MOVED_FROM が 現 れ た が IN_MOVED_TO は 現 れ て い な い と い う 短 い 期 間 が あ り え る と い う こ と だ 。 し た が っ て 、 rename(2) に よ り 生 成 さ れ た IN_MOVED_FROMIN_MOVED_TO の イ ベ ン ト の 組 の 対 応 を 取 る の は 本 質 的 に 難 し い こ と で あ る (監 視 対 象 の デ ィ レ ク ト リ の 外 へ オ ブ ジ ェ ク ト の rename が 行 わ れ た 場 合 に は IN_MOVED_TO イ ベ ン ト は 存 在 し さ え し な い こ と を 忘 れ て は な ら な い )。 (イ ベ ン ト は 常 に 連 続 し て い る と の 仮 定 を 置 く と い っ た ) 発 見 的 な 方 法 を 使 う と 、 ほ と ん ど の 場 合 で イ ベ ン ト の 組 を う ま く 見 つ け る こ と が で き る が 、 い く つ か の 場 合 に 見 逃 す こ と が 避 け ら れ ず 、 ア プ リ ケ ー シ ョ ン が IN_MOVED_FROMIN_MOVED_TO イ ベ ン ト が 無 関 係 だ と み な し て し ま う 可 能 性 が あ る 。 結 果 的 に 、 監 視 対 象 デ ィ ス ク リ プ タ ー が 破 棄 さ れ 再 作 成 さ れ た 場 合 、 こ れ ら の 監 視 対 象 デ ィ ス ク リ プ タ ー は 、 処 理 待 ち イ ベ ン ト の 監 視 対 象 デ ィ ス ク リ プ タ ー と 一 貫 性 の な い も の に な っ て し ま う (inotify フ ァ イ ル デ ィ ス ク リ プ タ ー の 再 作 成 と キ ャ ッ シ ュ の 再 構 成 は こ の 状 況 に 対 処 す る の に 有 用 な 方 法 な の だ が )。 ま た 、 ア プ リ ケ ー シ ョ ン は 、 IN_MOVED_FROM イ ベ ン ト が 今 行 っ た read(2) の 呼 び 出 し で 返 さ れ た バ ッ フ ァ ー の ち ょ う ど 一 番 最 後 の イ ベ ン ト で 、 IN_MOVED_TO イ ベ ン ト は 次 の read(2) を 行 わ な い と 取 得 で き な い 可 能 性 も 考 慮 に 入 れ る 必 要 が あ る 。 2 つ 目 の read(2) は (短 い ) タ イ ム ア ウ ト で 行 う べ き で あ る 。 こ れ は 、 IN_MOVED_FROMIN_MOVED_TO の イ ベ ン ト ペ ア の キ ュ ー へ の 挿 入 は ア ト ミ ッ ク で は な く 、 ま た IN_MOVED_TO イ ベ ン ト が 全 く 発 生 し な い 可 能 性 も あ る と い う 事 実 を 考 慮 に 入 れ て お く 必 要 が あ る か ら で あ る 。

バ グ

カ ー ネ ル 3.17 時 点 で は 、 fallocate(2) の 呼 び 出 し で は inotify イ ベ ン ト が 生 成 さ れ な い 。

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>

/* 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;
int i;
ssize_t len;
char *ptr;

/* 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 (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 (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’\n", argv[i]);
perror("inotify_add_watch");
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 プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。

COMMENTS