「inotify」の版間の差分
(同じ利用者による、間の6版が非表示) | |||
行1: | 行1: | ||
− | [[inotify]] とは、[[Linux]] の [[ファイルシステム]] のイベントを監視するための仕組みです。[[FreeBSD]] における | + | [[inotify]] とは、[[Linux]] の [[ファイルシステム]] のイベントを監視するための仕組みです。[[FreeBSD]] における kevent/kqueue といえます。 |
'''読み方''' | '''読み方''' | ||
行6: | 行6: | ||
== 概要 == | == 概要 == | ||
+ | [[inotify]] は、[[Linux]] において [[ファイル改竄検知]](セキュリティ監視)に役立つ仕組みです。[[inotify-tools]]を利用することで、リアルタイム[[監視]]を簡単に実現できます。 | ||
+ | |||
+ | [[inotify]] は、[[ファイルシステム]] を監視するための[[システムコール]]を提供します。[[inotify-tools]] は、[[inotify]]の機能を利用するためのプログラムを提供します。 | ||
+ | |||
[[inotify]] は、[[Linuxカーネル]] 2.6.13 で、組み込まれました。 | [[inotify]] は、[[Linuxカーネル]] 2.6.13 で、組み込まれました。 | ||
− | [[ | + | [[ファイルシステム]]のイベント監視は、ファイルマネージャーやセキュリティのツールなどに必要不可欠です。[[inotify]] は、1つのファイル記述子を開くことで、1つ以上のファイルやディレクトリのオープン、クローズ、移動・名前の変更、削除、作成、属性の変更などのイベントを指定して監視できます。 |
− | イベント監視に | + | イベント監視に select や poll を使用できます。 |
+ | [[inotify]] は、再帰的に監視できません。サブディレクトリの監視には、サブディレクトリを inotify_add_watch() で追加する必要があります。 | ||
− | [[inotify]] 以前の | + | [[inotify]] 以前の'''dnotify''' では、ディレクトリごとにファイル記述子を開く必要があり、複数の監視対象が存在する場合、コストが大きく、シグナルハンドリングの扱いにくさも問題でした。また、'''dnotify''' では、変更を調べるために stat の情報を持ち続けて、比較しなければなりませんでした。 |
== インストール == | == インストール == | ||
− | + | [[inotify]] の API を C言語から利用する場合には、インストールするものはありません。 | |
+ | [[inotify-tools]]は、インストールが必要です。[[inotify-tools]]を参照してください。 | ||
== サンプルコード inotify.c == | == サンプルコード inotify.c == | ||
このプログラムは、一度だけ、イベントを拾って、終了します。 | このプログラムは、一度だけ、イベントを拾って、終了します。 | ||
行27: | 行33: | ||
#include <sys/inotify.h> | #include <sys/inotify.h> | ||
+ | #include <linux/limits.h> | ||
− | #define INOTIFY_BUFFER_SIZE ( | + | #define INOTIFY_BUFFER_SIZE ((sizeof(struct inotify_event) + NAME_MAX + 1) * 4096) |
int | int | ||
行54: | 行61: | ||
int r = -1; | int r = -1; | ||
char buffer [INOTIFY_BUFFER_SIZE] = { 0 }; | char buffer [INOTIFY_BUFFER_SIZE] = { 0 }; | ||
− | struct inotify_event *event_ptr; | + | struct inotify_event *event_ptr = NULL; |
r = read (fd, buffer, INOTIFY_BUFFER_SIZE); | r = read (fd, buffer, INOTIFY_BUFFER_SIZE); | ||
行77: | 行84: | ||
main (int argc, char *argv[]) | main (int argc, char *argv[]) | ||
{ | { | ||
− | |||
int inotify_fd = Inotify_init(); | int inotify_fd = Inotify_init(); | ||
if (inotify_fd < 0) { | if (inotify_fd < 0) { | ||
行114: | 行120: | ||
name=b | name=b | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | == カーネルパラメーター == | |
+ | [[inotify]] に関連する[[カーネル]]のパラメーターがあります。 | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | $ ls /proc/sys/fs/inotify/ | ||
+ | max_queued_events max_user_instances max_user_watches | ||
+ | </syntaxhighlight> | ||
== 関連項目 == | == 関連項目 == | ||
− | + | {{inotify}} | |
* [[Linuxカーネル]] | * [[Linuxカーネル]] | ||
* [[Linux]] | * [[Linux]] | ||
* [[ファイルシステム]] | * [[ファイルシステム]] | ||
− | <!-- | + | <!-- vim: filetype=mediawiki |
− | vim: filetype=mediawiki | + | |
--> | --> |
2015年9月22日 (火) 17:55時点における最新版
inotify とは、Linux の ファイルシステム のイベントを監視するための仕組みです。FreeBSD における kevent/kqueue といえます。
読み方
- inotify
- あいのーてぃふぁい
概要
inotify は、Linux において ファイル改竄検知(セキュリティ監視)に役立つ仕組みです。inotify-toolsを利用することで、リアルタイム監視を簡単に実現できます。
inotify は、ファイルシステム を監視するためのシステムコールを提供します。inotify-tools は、inotifyの機能を利用するためのプログラムを提供します。
inotify は、Linuxカーネル 2.6.13 で、組み込まれました。 ファイルシステムのイベント監視は、ファイルマネージャーやセキュリティのツールなどに必要不可欠です。inotify は、1つのファイル記述子を開くことで、1つ以上のファイルやディレクトリのオープン、クローズ、移動・名前の変更、削除、作成、属性の変更などのイベントを指定して監視できます。 イベント監視に select や poll を使用できます。 inotify は、再帰的に監視できません。サブディレクトリの監視には、サブディレクトリを inotify_add_watch() で追加する必要があります。
inotify 以前のdnotify では、ディレクトリごとにファイル記述子を開く必要があり、複数の監視対象が存在する場合、コストが大きく、シグナルハンドリングの扱いにくさも問題でした。また、dnotify では、変更を調べるために stat の情報を持ち続けて、比較しなければなりませんでした。
インストール
inotify の API を C言語から利用する場合には、インストールするものはありません。 inotify-toolsは、インストールが必要です。inotify-toolsを参照してください。
サンプルコード inotify.c
このプログラムは、一度だけ、イベントを拾って、終了します。 一回の read で取得できるイベントだけを取得します。 バッファサイズの上限を超える場合は、うまくハンドリングできないでしょう。
#include <stdio.h> #include <stdlib.h> #include <err.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/inotify.h> #include <linux/limits.h> #define INOTIFY_BUFFER_SIZE ((sizeof(struct inotify_event) + NAME_MAX + 1) * 4096) int Inotify_init (void) { int fd = inotify_init (); if (fd < 0) { perror ("inotify_init"); return (fd); } return (fd); } int Inotify_add_watch (int fd, const char *pathname, uint32_t mask) { int watch_fd = inotify_add_watch (fd, pathname, mask); if (watch_fd == -1) { warn ("can not add inotify:fd=%d, path=%s, mask=%u", fd, pathname, mask); } return (watch_fd); } int read_events (int fd) { int r = -1; char buffer [INOTIFY_BUFFER_SIZE] = { 0 }; struct inotify_event *event_ptr = NULL; r = read (fd, buffer, INOTIFY_BUFFER_SIZE); if (r <= 0) { return (r); } int offset = 0; while (offset < r) { event_ptr = (struct inotify_event *) & buffer [offset]; (void) printf ("name=%s\n", event_ptr->name); offset += sizeof (struct inotify_event) + event_ptr->len; } return r; } int main (int argc, char *argv[]) { int inotify_fd = Inotify_init(); if (inotify_fd < 0) { errx (EXIT_FAILURE, "can not init inotify"); } long mask = IN_ALL_EVENTS; char *path1 = "/tmp"; int wd1 = Inotify_add_watch (inotify_fd, path1, mask); read_events (inotify_fd); exit (EXIT_SUCCESS); }
使い方
$ cc inotify.c
a.out を実行し、 /tmp のファイルを適当にいじります。
$ ./a.out
/tmp/b に追記してみました。
$ echo hoge >> /tmp/b
/tmp/b に追記したとき、3つのイベントが取得されました。
$ ./a.out name=b name=b name=b
カーネルパラメーター
inotify に関連するカーネルのパラメーターがあります。
$ ls /proc/sys/fs/inotify/ max_queued_events max_user_instances max_user_watches
関連項目
- inotify
- inotify-tools
- inotifywait
- inotifywatch
- libinotify
- Tripwire
- Linuxカーネル
- Linux
- ファイルシステム