0x0 前言
某些程序需要对文件或者目录进行监控,用来侦测是否发生了特定的事件.Windows平台提供了Sfilter和Minifilter等文件过滤驱动,可以通过对内核层的监控,反馈到应用层,使我们及时的看到磁盘上文件的变化.而Linux的桌面系统和Windows相比有太多不尽如人意的地方,为了改善这种状况,Linux提供了inotify机制.如果系统内核版本不低于2.6.13,那么就支持inotify.
0x1 概述
使用inotify有以下几个关键的步骤:
(1).应用程序使用inotify_init()创建inotify实例,返回一个系统调用的文件描述符.
int fd = inotify_init();
(2).应用程序使用inotify_add_watch()向inotify实例的监控列表添加条目,以此告诉内核哪些文件需要被监控.每个监控项都包含一个路径名以及相关的事件掩码.事件掩码针对路径名指明了所要监控的事件集合.然后返回一个监控描述符用于后续操作.
int wd = inotify_add_watch(fd,path,mask);
(3).为获得通知,应用程序要针对inotify文件描述符执行read()操作.每次对read()的成功调用,都会返回一个或多个inotify_event结构,其中各自记录了处于inotify实例监控下的某一路径所发生的事件.
struct inotify_event
{
__s32 wd; /* watch descriptor */
__u32 mask; /* watch mask */
__u32 cookie; /* cookie to synchronize two events */
__u32 len; /* length (including nulls) of name */
char name[0]; /* stub for possible name */
};
size_t len = read(fd,buf,MAX_LEN);
(4).结束监控时会关闭inotify文件描述符和监控描述符,清除与inotify实例相关的所有监控项.
int ret = inotify_rm_watch(fd, wd);
0x2 实现原理
在内核中,每个inotify实例对应一个inotify_device结构:
struct inotify_device
{
wait_queue_head_t wq; /* wait queue for i/o */
struct idr idr; /* idr mapping wd -> watch */
struct semaphore sem; /* protects this bad boy */
struct list_head events; /* list of queued events */
struct list_head watches; /* list of watches */
atomic_t count; /* reference count */
struct user_struct *user; /* user who opened this dev */
unsigned int queue_size; /* size of the queue (bytes) */
unsigned int event_count; /* number of pending events */
unsigned int max_events; /* max