Manpages

名 前

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

説 明

fanotify API は フ ァ イ ル シ ス テ ム イ ベ ン ト の 通 知 と 横 取 り 機 能 (interception) を 提 供 す る 。 ユ ー ス ケ ー ス と し て は 、 ウ イ ル ス ス キ ャ ン や 階 層 型 ス ト レ ー ジ の 管 理 な ど が あ る 。 現 在 の と こ ろ 、 限 定 的 な イ ベ ン ト の み が サ ポ ー ト さ れ て い る 。 特 に 、 作 成 (create)、 削 除 (delete)、 移 動 (move) イ ベ ン ト が サ ポ ー ト さ れ て い な い (こ れ ら の イ ベ ン ト を 通 知 す る API の 詳 細 に つ い て は inotify(7) を 参 照 )。

inotify(7) API と 比 較 し て 追 加 さ れ て い る 機 能 と し て は 、 マ ウ ン ト さ れ た フ ァ イ ル シ ス テ ム の 全 オ ブ ジ ェ ク ト を 監 視 す る 機 能 、 ア ク セ ス 許 可 の 判 定 を 行 う 機 能 、 他 の ア プ リ ケ ー シ ョ ン に よ る ア ク セ ス の 前 に フ ァ イ ル を 読 み 出 し た り 変 更 し た り す る 機 能 が あ る 。 こ の API で は 以 下 の シ ス テ ム コ ー ル を 使 用 す る : fanotify_init(2), fanotify_mark(2), read(2), write(2), close(2)

fanotify_init(), fanotify_mark() と 通 知 グ ル ー プ
fanotify_init(2) シ ス テ ム コ ー ル は fanotify 通 知 グ ル ー プ を 作 成 、 初 期 化 し 、 こ の 通 知 グ ル ー プ を 参 照 す る フ ァ イ ル デ ィ ス ク リ プ タ ー を 返 す 。

fanotify 通 知 グ ル ー プ は カ ー ネ ル 内 部 の オ ブ ジ ェ ク ト で 、 イ ベ ン ト が 作 成 さ れ る フ ァ イ ル 、 デ ィ レ ク ト リ 、 マ ウ ン ト ポ イ ン ト の リ ス ト を 保 持 す る 。

fanotify 通 知 グ ル ー プ の 各 エ ン ト リ ー に は 2 つ の ビ ッ ト マ ス ク が あ る 。 mark マ ス ク と ignore マ ス ク で あ る 。 mark マ ス ク は ど の フ ァ イ ル 操 作 に つ い て イ ベ ン ト を 作 成 す る か を 定 義 す る 。 ignore マ ス ク は ど の 操 作 に つ い て イ ベ ン ト を 作 成 し な い か を 定 義 す る 。 こ れ ら の 2 種 類 の マ ス ク が あ る こ と で 、 マ ウ ン ト ポ イ ン ト や デ ィ レ ク ト リ に 対 し て イ ベ ン ト の 受 信 を mark し て お き つ つ 、 同 時 に そ の マ ウ ン ト ポ イ ン ト や デ ィ レ ク ト リ 配 下 の 特 定 の オ ブ ジ ェ ク ト に 対 す る イ ベ ン ト を 無 視 す る 、 と い っ た こ と が で き る 。

fanotify_mark(2) シ ス テ ム コ ー ル は 、 フ ァ イ ル 、 デ ィ レ ク ト リ 、 マ ウ ン ト を 通 知 グ ル ー プ に 追 加 し 、 ど の イ ベ ン ト を 報 告 (も し く は 無 視 ) す る か を 指 定 す る 。 ま た 、 こ の よ う な エ ン ト リ ー の 削 除 、 変 更 も 行 う 。

ignore マ ス ク の 考 え ら れ る 使 用 方 法 は フ ァ イ ル キ ャ ッ シ ュ に 対 し て で あ る 。 フ ァ イ ル キ ャ ッ シ ュ に 関 し て 興 味 の あ る イ ベ ン ト は 、 フ ァ イ ル の 変 更 と フ ァ イ ル の ク ロ ー ズ で あ る 。 そ れ ゆ え 、 キ ャ ッ シ ュ さ れ た デ ィ レ ク ト リ や マ ウ ン ト ポ イ ン ト は 、 こ れ ら の イ ベ ン ト を 受 信 す る よ う に マ ー ク さ れ る 。 フ ァ イ ル が 変 更 さ れ た と い う 最 初 の イ ベ ン ト を 受 信 し た 後 は 、 対 応 す る キ ャ ッ シ ュ エ ン ト リ ー は 無 効 化 さ れ る 。 そ の フ ァ イ ル が ク ロ ー ズ さ れ る ま で は 、 こ の フ ァ イ ル に 対 す る 変 更 イ ベ ン ト は 興 味 の な い 情 報 と な る 。 し た が っ て 、 変 更 イ ベ ン ト を ignore マ ス ク に 追 加 す る こ と が で き る 。 ク ロ ー ズ イ ベ ン ト を 受 信 す る と 、 変 更 イ ベ ン ト を ignore イ ベ ン ト か ら 削 除 し 、 フ ァ イ ル キ ャ ッ シ ュ エ ン ト リ ー を 更 新 す る こ と が で き る 。

fanotify 通 知 グ ル ー プ の エ ン ト リ ー は 、 フ ァ イ ル や デ ィ レ ク ト リ で は inode 番 号 経 由 で 参 照 さ れ 、 マ ウ ン ト で は マ ウ ン ト ID 経 由 で 参 照 さ れ る 。 フ ァ イ ル や デ ィ レ ク ト リ の 名 前 が 変 更 さ れ た り 、 移 動 さ れ た り し た 場 合 も 、 関 連 す る エ ン ト リ ー は そ の ま ま 残 る 。 フ ァ イ ル や デ ィ レ ク ト リ が 削 除 さ れ た り 、 マ ウ ン ト が ア ン マ ウ ン ト さ れ た り し た 場 合 に は 、 対 応 す る エ ン ト リ ー は 削 除 さ れ る 。 イ ベ ン ト キ ュ ー 通 知 グ ル ー プ に よ り 監 視 さ れ て い る フ ァ イ ル シ ス テ ム オ ブ ジ ェ ク ト で イ ベ ン ト が 発 生 す る と 、 fanotify シ ス テ ム は イ ベ ン ト を 生 成 し 、 そ の イ ベ ン ト は キ ュ ー に ま と め ら れ る 。 こ れ ら の イ ベ ン ト は 、 fanotify_init(2) が 返 し た fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー か ら (read(2) な ど を 使 っ て ) 読 み 出 す こ と が で き る 。

2 種 類 の イ ベ ン ト が 生 成 さ れ る 。 notification (通 知 ) イ ベ ン ト と permission (ア ク セ ス 許 可 ) イ ベ ン ト で あ る 。 通 知 イ ベ ン ト は 単 な る 情 報 通 知 で あ り 、 イ ベ ン ト で 渡 さ れ た フ ァ イ ル デ ィ ス ク リ プ タ ー を ク ロ ー ズ す る 場 合 (下 記 参 照 ) を 除 き 、 受 信 し た ア プ リ ケ ー シ ョ ン で ア ク シ ョ ン を 取 る 必 要 は な い 。 ア ク セ ス 許 可 イ ベ ン ト は 、 受 信 し た ア プ リ ケ ー シ ョ ン が フ ァ イ ル ア ク セ ス の 許 可 を 承 認 す る か を 判 定 す る 必 要 が あ る 。 こ の 場 合 、 受 信 者 は ア ク セ ス が 許 可 さ れ た か 否 か を 決 定 す る 応 答 を 書 き 込 ま な け れ ば な ら な い 。 イ ベ ン ト は 、 読 み 出 さ れ る と 、 fanotify グ ル ー プ の イ ベ ン ト キ ュ ー か ら 削 除 さ れ る 。 読 み 出 さ れ た ア ク セ ス 許 可 イ ベ ン ト は 、 fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー に ア ク セ ス 許 可 の 判 定 が 書 き 込 ま れ る か 、 fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー が ク ロ ー ズ さ れ る ま で 、 fanotify グ ル ー プ の 内 部 の リ ス ト に 保 持 さ れ る 。

fanotify イ ベ ン ト の 読 み 出 し
fanotify_init(2) が 返 し た フ ァ イ ル デ ィ ス ク リ プ タ ー に 対 す る read(2) を 呼 び 出 し は 、 (fanotify_init(2) の 呼 び 出 し で フ ラ グ FAN_NONBLOCK を 指 定 し な か っ た 場 合 ) フ ァ イ ル イ ベ ン ト が 起 こ る か 、 呼 び 出 し が シ グ ナ ル に よ っ て 割 り 込 ま れ る (signal(7) 参 照 ) ま で 停 止 す る 。

read(2) が 成 功 す る と 、 読 み 出 し バ ッ フ ァ ー に は 以 下 の 構 造 体 が 1 つ 以 上 格 納 さ れ る 。

struct fanotify_event_metadata {
__u32 event_len;
__u8 vers;
__u8 reserved;
__u16 metadata_len;
__aligned_u64 mask;
__s32 fd;
__s32 pid; }; 性 能 上 の 理 由 か ら 、 複 数 の イ ベ ン ト を 一 度 の read(2) で 取 得 で き る よ う に 大 き め の バ ッ フ ァ ー サ イ ズ (例 え ば 4096 バ イ ト ) を 使 用 す る こ と を 推 奨 す る 。

read(2) の 返 り 値 は バ ッ フ ァ ー に 格 納 さ れ た バ イ ト 数 で あ る 。 エ ラ ー の 場 合 は −1 が 返 さ れ る (た だ し 、 バ グ も 参 照 )。

fanotify_event_metadata 構 造 体 の フ ィ ー ル ド は 以 下 の と お り で あ る 。
event_len
こ れ は 、 こ の イ ベ ン ト の デ ー タ 長 で あ り 、 バ ッ フ ァ ー 内 の 次 の イ ベ ン ト へ の オ フ セ ッ ト で あ る 。 現 在 の 実 装 で は 、 event_len の 値 は 常 に FAN_EVENT_METADATA_LEN で あ る 。 し か し な が ら 、 API は 将 来 可 変 長 の 構 造 体 を 返 す こ と が で き る よ う に 設 計 さ れ て い る 。

vers こ の フ ィ ー ル ド に は 構 造 体 の バ ー ジ ョ ン 番 号 が 入 る 。 実 行 時 に 返 さ れ た 構 造 体 が コ ン パ イ ル 時 の 構 造 体 と 一 致 し て い る か を 検 査 す る に は 、 こ の 値 を

FANOTIFY_METADATA_VERSION を 比 較 す る こ と 。 一 致 し な い 場 合 、 ア プ リ ケ ー シ ョ ン は そ の fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー を 使 用 す る の を 諦 め る べ き で あ る 。
reserved
こ の フ ィ ー ル ド は 使 用 さ れ な い 。
metadata_len
こ の 構 造 体 の 長 さ で あ る 。 こ の フ ィ ー ル ド は 、 イ ベ ン ト 種 別 単 位 の オ プ シ ョ ン ヘ ッ ダ ー の 実 装 を 扱 う た め に 導 入 さ れ た 。 現 在 の 実 装 で は こ の よ う な オ プ シ ョ ン ヘ ッ ダ ー は 存 在 し な い 。

mask イ ベ ン ト を 示 す ビ ッ ト マ ス ク で あ る

(下 記 参 照 )

fd こ れ は ア ク セ ス さ れ た オ ブ ジ ェ ク ト に

対 す る オ ー プ ン さ れ た フ ァ イ ル デ ィ ス ク リ プ タ ー で あ る 。 ま た は 、 キ ュ ー の オ ー バ ー フ ロ ー が 発 生 し た 場 合 に は FAN_NOFD が 入 る 。 フ ァ イ ル デ ィ ス ク リ プ タ ー は 監 視 対 象 の フ ァ イ ル や デ ィ レ ク ト リ の 内 容 に ア ク セ ス す る の に 使 用 で き る 。 読 み 出 し た ア プ リ ケ ー シ ョ ン は 責 任 を 持 っ て こ の フ ァ イ ル デ ィ ス ク リ プ タ ー を ク ロ ー ズ し な け れ ば な ら な い 。

fanotify_init(2) を 呼 び 出 す 際 、 呼 び 出 し 元 は こ の フ ァ イ ル デ ィ ス ク リ プ タ ー に 対 応 す る オ ー プ ン フ ァ イ ル 記 述 に セ ッ ト さ れ た 様 々 な フ ァ イ ル 状 態 フ ラ グ を (event_f_flags 引 き 数 を 使 っ て ) 指 定 す る こ と が で き る 。 さ ら に 、 (カ ー ネ ル 内 部 の ) FMODE_NONOTIFY フ ァ イ ル 状 態 フ ラ グ が オ ー プ ン フ ァ イ ル 記 述 に セ ッ ト さ れ る 。 こ の フ ラ グ は fanotify イ ベ ン ト の 生 成 を 抑 制 す る 。 し た が っ て 、 fanotify イ ベ ン ト の 受 信 者 が こ の フ ァ イ ル デ ィ ス ク リ プ タ ー を 使 っ て 通 知 さ れ た フ ァ イ ル や デ ィ レ ク ト リ に ア ク セ ス し た 際 に 、 こ れ 以 上 イ ベ ン ト が 作 成 さ れ な く な る 。

pid こ れ は イ ベ ン ト が 発 生 す る 原 因 と な っ た プ ロ セ ス

ID で あ る 。

fanotify イ ベ ン ト を 監 視 し て い る プ ロ グ ラ ム は 、 こ の PID を getpid(2) が 返 す PID と 比 較 す る こ と で 、 イ ベ ン ト が 監 視 し て い る プ ロ グ ラ ム 自 身 か ら 発 生 し た か ど う か 、 別 の プ ロ セ ス に よ る フ ァ イ ル ア ク セ ス に よ り 発 生 し た か 、 を 判 定 で き る 。

mask の ビ ッ ト マ ス ク は 、 1 つ の フ ァ イ ル シ ス テ ム オ ブ ジ ェ ク ト に 対 し て ど の イ ベ ン ト が 発 生 し た か を 示 す 。 監 視 対 象 の フ ァ イ ル シ ス テ ム オ ブ ジ ェ ク ト に 複 数 の イ ベ ン ト が 発 生 し た 場 合 は 、 こ の マ ス ク に 複 数 の ビ ッ ト が セ ッ ト さ れ る こ と が あ る 。 特 に 、 同 じ フ ァ イ ル シ ス テ ム オ ブ ジ ェ ク ト に 対 す る 連 続 す る イ ベ ン ト が 同 じ プ ロ セ ス か ら 生 成 さ れ た 場 合 に は 、 一 つ の イ ベ ン ト に ま と め ら れ る こ と が あ る 。 例 外 と し て 、 2 つ の ア ク セ ス 許 可 イ ベ ン ト が 一 つ の キ ュ ー エ ン ト リ ー に ま と め ら れ る こ と は 決 し て な い 。

mask で セ ッ ト さ れ て い る 可 能 性 の あ る ビ ッ ト は 以 下 の と お り で あ る 。
FAN_ACCESS
フ ァ イ ル や デ ィ レ ク ト リ が ア ク セ ス さ れ た (読 み 出 し が 行 わ れ た ) (た だ し 、 「 バ グ 」 の 節 も 参 照 )。
FAN_OPEN
フ ァ イ ル や デ ィ レ ク ト リ が オ ー プ ン さ れ た 。
FAN_MODIFY
フ ァ イ ル や デ ィ レ ク ト リ が 変 更 さ れ た 。
FAN_CLOSE_WRITE
書 き 込 み 用 (O_WRONLYO_RDWR) に オ ー プ ン さ れ た フ ァ イ ル が ク ロ ー ズ さ れ た 。
FAN_CLOSE_NOWRITE
読 み 出 し 用 (O_RDONLY) に オ ー プ ン さ れ た フ ァ イ ル が ク ロ ー ズ さ れ た 。
FAN_Q_OVERFLOW
イ ベ ン ト キ ュ ー が 16384 エ ン ト リ ー の 上 限 を 超 過 し た 。 こ の 上 限 は fanotify_init(2) 呼 び 出 し 時 に FAN_UNLIMITED_QUEUE フ ラ グ を 指 定 す る こ と で 上 書 き で き る 。
FAN_ACCESS_PERM
ア プ リ ケ ー シ ョ ン が 例 え ば read(2)readdir(2) な ど を 使 っ て フ ァ イ ル や デ ィ レ ク ト リ を 読 み 出 そ う と し た 。 こ の イ ベ ン ト を 読 み 出 し た プ ロ グ ラ ム は 、 そ の フ ァ イ ル シ ス テ ム オ ブ ジ ェ ク ト へ の ア ク セ ス 許 可 を 承 認 す る か を 判 定 し (下 記 で 説 明 す る と お り ) 応 答 を 書 き 込 ま な け れ ば な ら な い 。
FAN_OPEN_PERM
ア プ リ ケ ー シ ョ ン が フ ァ イ ル や デ ィ レ ク ト リ を オ ー プ ン し よ う と し た 。 こ の イ ベ ン ト を 読 み 出 し た プ ロ グ ラ ム は 、 そ の フ ァ イ ル シ ス テ ム オ ブ ジ ェ ク ト の オ ー プ ン を 承 認 す る か を 判 定 し (下 記 で 説 明 す る と お り ) 応 答 を 書 き 込 ま な け れ ば な ら な い 。 ク ロ ー ズ イ ベ ン ト を 確 認 す る た め に 以 下 の ビ ッ ト マ ス ク を 使 う こ と が で き る 。
FAN_CLOSE
フ ァ イ ル が ク ロ ー ズ さ れ た 。 以 下 の 同 義 語 で あ る 。

FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE

fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー か ら の read(2) が 返 し た fanotify イ ベ ン ト メ タ デ ー タ を 含 む バ ッ フ ァ ー に 対 し て 繰 り 返 し を 行 う た め 、 以 下 の マ ク ロ が 提 供 さ れ て い る 。
FAN_EVENT_OK(meta, len)
こ の マ ク ロ は 、 バ ッ フ ァ ー meta の 残 り の 長 さ len を 、 メ タ デ ー タ 構 造 体 の 長 さ と バ ッ フ ァ ー の 最 初 の メ タ デ ー タ 構 造 体 の event_len フ ィ ー ル ド と 比 較 し て 検 査 す る 。
FAN_EVENT_NEXT(meta, len)
こ の マ ク ロ は 、 meta が 指 す メ タ デ ー タ 構 造 体 の event_len フ ィ ー ル ド で 示 さ れ た 長 さ を 使 っ て 、 meta の 次 の メ タ デ ー タ 構 造 体 の ア ド レ ス を 計 算 す る 。 len は バ ッ フ ァ ー に 現 在 残 っ て い る メ タ デ ー タ の バ イ ト 数 で あ る 。 こ の マ ク ロ は meta の 次 の メ タ デ ー タ 構 造 体 へ の ポ イ ン タ ー を 返 し 、 ス キ ッ プ さ れ た メ タ デ ー タ 構 造 体 の バ イ ト 数 だ け len を 減 算 す る (つ ま り 、 len か ら meta−>event_len を 引 き 算 す る )。 ま た 、 以 下 の マ ク ロ も 用 意 さ れ て い る 。
FAN_EVENT_METADATA_LEN
こ の マ ク ロ は fanotify_event_metadata 構 造 体 の (バ イ ト 単 位 の ) サ イ ズ を 返 す 。 返 さ れ る 値 は イ ベ ン ト メ タ デ ー タ の 最 小 値 で あ る (現 在 の と こ ろ 、 こ れ が 唯 一 の サ イ ズ で あ る )。

fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー の イ ベ ン ト を 監 視 す る
fanotify イ ベ ン ト が 発 生 す る と 、 epoll(7), poll(2), select(2) に fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー が 渡 さ れ た 場 合 に は 、 そ の フ ァ イ ル デ ィ ス ク リ プ タ ー が 読 み 出 し 可 能 で あ る と 通 知 さ れ る 。 ア ク セ ス 許 可 イ ベ ン ト の 取 り 扱 い ア ク セ ス 許 可 イ ベ ン ト で は 、 ア プ リ ケ ー シ ョ ン は 以 下 の 形 式 の 構 造 体 を fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー に write(2) し な け れ ば な ら な い 。

struct fanotify_response {
__s32 fd;
__u32 response; }; こ の 構 造 体 の フ ィ ー ル ド は 以 下 の と お り で あ る 。

fd こ の フ ィ ー ル ド は

fanotify_event_metadata 構 造 体 で 返 さ れ た フ ァ イ

ル デ ィ ス ク リ プ タ ー で あ る 。

response こ の フ ィ ー ル ド は ア ク セ ス 許 可 を 承 認 す る か ど う か を 示 す 。 値 は 、 こ の フ ァ イ ル 操 作 を 許 可 す る FAN_ALLOW か 、 こ の フ ァ イ ル 操 作 を 拒 否 す る FAN_DENY の い ず れ か で な け れ ば な ら な い 。 ア ク セ ス を 拒 否 し た 場 合 、 ア ク セ ス を 要 求 し た ア プ リ ケ ー シ ョ ン は EPERM エ ラ ー を 受 け 取 る こ と に な る 。

fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー の ク ロ ー ズ
fanotify 通 知 グ ル ー プ を 参 照 す る す べ て の フ ァ イ ル デ ィ ス ク リ プ タ ー が ク ロ ー ズ さ れ る と 、 fanotify グ ル ー プ は 解 放 さ れ 、 カ ー ネ ル が 再 利 用 で き る よ う に そ の リ ソ ー ス は 解 放 さ れ る 。 close(2) の 際 に 、 処 理 中 で あ っ た ア ク セ ス 許 可 イ ベ ン ト に は 許 可 が 設 定 さ れ る 。

/proc/[pid]/fdinfo フ ァ イ ル /proc/[pid]/fdinfo/[fd] に は 、 プ ロ セ ス pid の フ ァ イ ル デ ィ ス ク リ プ タ ー fd の fanotify マ ー ク に 関 す る 情 報 が 格 納 さ れ る 。 詳 細 は カ ー ネ ル の ソ ー ス フ ァ イ ル Documentation/filesystems/proc.txt を 参 照 。

エ ラ ー

通 常 の read(2) の エ ラ ー に 加 え 、 fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー か ら 読 み 出 し を 行 っ た 際 に 以 下 の エ ラ ー が 発 生 す る こ と が あ る 。

getrlimit(2)

EINVAL バ ッ フ ァ ー が イ ベ ン ト を 保 持 す る に は 小 さ す ぎ る 。

EMFILE オ ー プ ン し た フ ァ イ ル 数 の プ ロ セ ス 毎 の 上 限 に 達 し た 。

RLIMIT_NOFILE の 説 明 を 参 照 。

ENFILE オ ー プ ン さ れ た フ ァ イ ル 数 の シ ス テ ム 全 体 の 上 限 に 達 し た 。

proc(5)

/proc/sys/fs/file−max を 参 照 。

ETXTBSY

fanotify_init(2) の 呼 び 出 し 時 に O_RDWRO_WRONLYevent_f_flags 引 き 数 に 指 定 さ れ て お り 、 現 在 実 行 中 の 監 視 対 象 の フ ァ イ ル に 対 し て イ ベ ン ト が 発 生 し た 際 に 、 こ の エ ラ ー が read(2) か ら 返 さ れ る 。 通 常 の write(2) の エ ラ ー に 加 え 、 fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー に 書 き 込 み を 行 っ た 際 に 以 下 の エ ラ ー が 発 生 す る こ と が あ る 。

EINVAL

fanotify ア ク セ ス 許 可 が カ ー ネ ル の 設 定 で 有 効 に な っ て い な い 。 応 答 構 造 体 の response 値 が 無 効 で あ る 。

ENOENT

応 答 構 造 体 の フ ァ イ ル デ ィ ス ク リ プ タ ー fd が 無 効 で あ る 。 こ の エ ラ ー は ア ク セ ス 許 可 イ ベ ン ト に 対 す る 応 答 が す で に 書 き 込 ま れ て い る 際 に 発 生 す る 。

バ ー ジ ョ ン

fanotify API は Linux カ ー ネ ル の バ ー ジ ョ ン 2.6.36 で 導 入 さ れ 、 バ ー ジ ョ ン 2.6.37 で 有 効 に さ れ た 。 fdinfo の サ ポ ー ト は バ ー ジ ョ ン 3.8 で 追 加 さ れ た 。

準 拠

fanotify API は Linux 独 自 の も の で あ る 。

注 意

fanotify API が 利 用 で き る の は 、 カ ー ネ ル が CONFIG_FANOTIFY 設 定 オ プ シ ョ ン を 有 効 に し て 作 成 さ れ て い る 場 合 だ け で あ る 。 ま た 、 fanotify ア ク セ ス 許 可 の 処 理 が 利 用 で き る の は CONFIG_FANOTIFY_ACCESS_PERMISSIONS 設 定 オ プ シ ョ ン が 有 効 に な っ て い る 場 合 だ け で あ る 。 制 限 と 警 告
fanotify が 報 告 す る の は ユ ー ザ ー 空 間 プ ロ グ ラ ム が フ ァ イ ル シ ス テ ム API 経 由 で 行 っ た イ ベ ン ト だ け で あ る 。 そ の 結 果 、 fanotify で は ネ ッ ト ワ ー ク フ ァ イ ル シ ス テ ム 上 で 発 生 し た リ モ ー ト イ ベ ン ト は 捕 捉 で き な い 。

inotify API は mmap(2), msync(2), munmap(2) に よ り 起 こ っ た フ ァ イ ル の ア ク セ ス と 変 更 を 報 告 し な い 。 デ ィ レ ク ト リ の イ ベ ン ト は 、 デ ィ レ ク ト リ 自 身 が オ ー プ ン 、 読 み 出 し 、 ク ロ ー ズ さ れ た 場 合 に し か 作 成 さ れ な い 。 マ ー ク さ れ た デ ィ レ ク ト リ で の 子 要 素 の 追 加 、 削 除 、 変 更 で は 、 監 視 対 象 の デ ィ レ ク ト リ 自 身 へ の イ ベ ン ト は 作 成 さ れ な い 。

fanotify の デ ィ レ ク ト リ の 監 視 は 再 帰 的 で は な い 。 デ ィ レ ク ト リ 内 の サ ブ デ ィ レ ク ト リ を 監 視 す る に は 、 追 加 で 監 視 用 の マ ー ク を 作 成 し な け れ ば な ら な い 。 (た だ し 、 fanotify API で は 、 サ ブ デ ィ レ ク ト リ が 監 視 対 象 と し て マ ー ク さ れ て い る デ ィ レ ク ト リ に 作 成 さ れ た 際 に 検 出 す る 手 段 は 提 供 さ れ て い な い 点 に 注 意 す る こ と 。 ) マ ウ ン ト の 監 視 を 使 う こ と で 、 デ ィ レ ク ト リ ツ リ ー 全 体 を 監 視 す る こ と が で き る 。 ベ ン ト キ ュ ー は オ ー バ ー フ ロ ー す る こ と が あ る 。 こ の 場 合 、 イ ベ ン ト は 失 わ れ る 。

バ グ

Linux 3.17 時 点 で は 、 以 下 の バ グ が 存 在 す る 。

*

Linux で は 、 フ ァ イ ル シ ス テ ム オ ブ ジ ェ ク ト は 複 数 の パ ス で ア ク セ ス 可 能 で あ る 。 例 え ば 、 フ ァ イ ル シ ス テ ム の 一 部 は mount(8)−−bind オ プ シ ョ ン を 使 っ て 再 マ ウ ン ト さ れ る こ と が あ る 。 マ ー ク さ れ た マ ウ ン ト の 監 視 者 は 、 同 じ マ ウ ン ト を 使 っ た フ ァ イ ル オ ブ ジ ェ ク ト に つ い て の み イ ベ ン ト 通 知 を 受 け る 。 そ れ 以 外 の イ ベ ン ト は 通 知 さ れ な い 。

*

fallocate(2) の 呼 び 出 し で は fanotify イ ベ ン ト が 作 成 さ れ な い 。

*

イ ベ ン ト が 生 成 さ れ た 際 に 、 そ の フ ァ イ ル の フ ァ イ ル デ ィ ス ク リ プ タ ー を 渡 す 前 に 、 イ ベ ン ト を 受 信 す る プ ロ セ ス の ユ ー ザ ー ID が そ の フ ァ イ ル に 対 す る 読 み 出 し / 書 き 込 み 許 可 が あ る か の 確 認 は 行 わ れ な い 。 非 特 権 ユ ー ザ ー に よ っ て 実 行 さ れ た プ ロ グ ラ ム に CAP_SYS_ADMIN ケ ー パ ビ リ テ ィ ー が セ ッ ト さ れ て い る 場 合 に は 、 こ の こ と は セ キ ュ リ テ ィ ー リ ス ク と な る 。
*

read(2) の 呼 び 出 し が fanotify キ ュ ー か ら 複 数 の イ ベ ン ト を 処 理 し て い る 際 に 、 エ ラ ー が 発 生 し た 場 合 、 返 り 値 は エ ラ ー が 発 生 す る 前 ま で に ユ ー ザ ー 空 間 バ ッ フ ァ ー に 正 常 に コ ピ ー さ れ た イ ベ ン ト の 合 計 長 と な る 。 返 り 値 は −1 に な ら ず 、 errno も セ ッ ト さ れ な い 。 し た が っ て 、 読 み 出 し を 行 う ア プ リ ケ ー シ ョ ン で は エ ラ ー を 検 出 す る 方 法 は な い 。

以 下 の プ ロ グ ラ ム は fanotify API の 使 用 法 を 示 す も の で あ る 。 コ マ ン ド ラ イ ン 引 き 数 で 渡 さ れ た マ ウ ン ト ポ イ ン ト を 監 視 し 、 種 別 が FAN_PERM_OPENFAN_CLOSE_WRITE の イ ベ ン ト を 待 つ 。 ア ク セ ス 許 可 イ ベ ン ト が 発 生 に は 、 FAN_ALLOW 応 答 を 返 す 。 以 下 の 出 力 例 は フ ァ イ ル /home/user/temp/notes を 編 集 し た 際 に 記 録 さ れ た も の で あ る 。 フ ァ イ ル を オ ー プ ン す る 前 に FAN_OPEN_PERM イ ベ ン ト が 発 生 し て い る 。 フ ァ イ ル を ク ロ ー ズ し た 後 に FAN_CLOSE_WRITE イ ベ ン ト が 発 生 し て い る 。 エ ン タ ー キ ー を ユ ー ザ ー が 押 す と 、 こ の プ ロ グ ラ ム の 実 行 は 終 了 す る 。 出 力 例

# ./fanotify_example /home
Press enter key to terminate.
Listening for events.
FAN_OPEN_PERM: File /home/user/temp/notes
FAN_CLOSE_WRITE: File /home/user/temp/notes

Listening for events stopped. プ ロ グ ラ ム ソ ー ス

#define _GNU_SOURCE /* O_LARGEFILE の 定 義 を 得 る た め に 必 要 */
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/fanotify.h>
#include <unistd.h>

/* フ ァ イ ル デ ィ ス ク リ プ タ ー ’fd’ か ら 読 み 出 し で き る 全 fanotify イ ベ ン ト を 読 み 出 す */

static void
handle_events(int fd)
{
const struct fanotify_event_metadata *metadata;
struct fanotify_event_metadata buf[200];
ssize_t len;
char path[PATH_MAX];
ssize_t path_len;
char procfd_path[PATH_MAX];
struct fanotify_response response;

/* fanotify フ ァ イ ル デ ィ ス ク リ プ タ ー か ら イ ベ ン ト が 読 み 出 せ る 間 は ル ー プ す る */

for(;;) {

/* イ ベ ン ト を 読 み 出 す */

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

/* 読 み 出 せ る デ ー タ の 最 後 に 達 し て い る か チ ェ ッ ク す る */

if (len <= 0)
break;

/* バ ッ フ ァ ー の 最 初 の イ ベ ン ト を 参 照 す る */

metadata = buf;

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

while (FAN_EVENT_OK(metadata, len)) {

/* 実 行 時 と コ ン パ イ ル 時 の 構 造 体 が 一 致 す る か 確 認 す る */

if (metadata−>vers != FANOTIFY_METADATA_VERSION) {
fprintf(stderr,
"Mismatch of fanotify metadata version.\n");
exit(EXIT_FAILURE); }

/* metadata−>fd に は 、 キ ュ ー の オ ー バ ー フ ロ ー を 示 す FAN_NOFD か 、 フ ァ イ ル デ ィ ス ク リ プ タ ー
(負 で な い 整 数 ) の い ず れ か が 入 っ て い る 。 こ こ で は キ ュ ー の オ ー バ ー フ ロ ー は 無 視 し て い る 。
*/

if (metadata−>fd >= 0) {

/* オ ー プ ン 許 可 イ ベ ン ト を 処 理 す る */

if (metadata−>mask & FAN_OPEN_PERM) {
printf("FAN_OPEN_PERM: ");

/* フ ァ イ ル の オ ー プ ン を 許 可 す る */

response.fd = metadata−>fd;
response.response = FAN_ALLOW;
write(fd, &response,
sizeof(struct fanotify_response)); }

/* 書 き 込 み 可 能 フ ァ イ ル の ク ロ ー ズ イ ベ ン ト を 処 理 す る */

if (metadata−>mask & FAN_CLOSE_WRITE)
printf("FAN_CLOSE_WRITE: ");

/* ア ク セ ス さ れ た フ ァ イ ル の パ ス 名 を 取 得 し 表 示 す る */

snprintf(procfd_path, sizeof(procfd_path),
"/proc/self/fd/%d", metadata−>fd);
path_len = readlink(procfd_path, path,
sizeof(path) − 1);
if (path_len == −1) {
perror("readlink");
exit(EXIT_FAILURE); }

path[path_len] = ’\0’;
printf("File %s\n", path);

/* イ ベ ン ト の フ ァ イ ル デ ィ ス ク リ プ タ ー を ク ロ ー ズ す る */

close(metadata−>fd); }

/* 次 の イ ベ ン ト に 進 む */

metadata = FAN_EVENT_NEXT(metadata, len); } } }

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

/* マ ウ ン ト ポ イ ン ト が 指 定 さ れ た か 確 認 す る */

if (argc != 2) {
fprintf(stderr, "Usage: %s MOUNT\n", argv[0]);
exit(EXIT_FAILURE); }

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

/* fanotify API に ア ク セ ス す る た め の フ ァ イ ル デ ィ ス ク リ プ タ ー を 作 成 す る */

fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
O_RDONLY | O_LARGEFILE);
if (fd == −1) {
perror("fanotify_init");
exit(EXIT_FAILURE); }

/* 指 定 さ れ た マ ウ ン ト に 対 し て 以 下 を 監 視 す る よ う に マ ー ク を 付 け る :
− フ ァ イ ル の オ ー プ ン 前 の ア ク セ ス 許 可 イ ベ ン ト
− 書 き 込 み 可 能 な フ ァ イ ル デ ィ ス ク リ プ タ ー の ク ロ ー ズ 後 の 通 知 イ ベ ン ト
*/

if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,
argv[1]) == −1) {
perror("fanotify_mark");
exit(EXIT_FAILURE); }

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

nfds = 2;

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

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

/* fanotify の 入 力 */

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

/* イ ベ ン ト の 発 生 を 待 つ ル ー プ */

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

while (1) {
poll_num = poll(fds, nfds, −1);
if (poll_num == −1) {
if (errno == EINTR) /* シ グ ナ ル に 割 り 込 ま れ た 場 合 */
continue; /* poll() を 再 開 す る */

perror("poll"); /* 予 期 し な い エ ラ ー */
exit(EXIT_FAILURE); }

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

/* コ ン ソ ー ル か ら の 入 力 が あ る 場 合 : 空 の 標 準 入 力 で あ れ ば 終 了 */

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

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

/* fanotify イ ベ ン ト が あ る 場 合 */

handle_events(fd); } } }

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

関 連 項 目

fanotify_init(2), fanotify_mark(2), inotify(7)

こ の 文 書 に つ い て

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