名 前
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_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);
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 フ ァ イ ル デ ィ ス ク リ プ タ ー に つ い て の 正 し い 順 番 で イ ベ ン ト が 生 成 さ れ る こ と が 保 証 さ れ る 。
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_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 イ ベ ン ト が 全 く 発 生 し な い 可 能 性 も あ る と い う 事 実 を 考 慮 に 入 れ て お く 必 要 が あ る か ら で あ る 。
バ グ
カ ー ネ ル 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/ に 書 か れ て い る 。