Linux INotif机制详解及实例代码

2019-10-12 17:23:28丽君

可以在函数 inotify_init() 返回的文件描述符 fd 上使用 select() 或poll(), 也可以在 fd 上使用 ioctl 命令 FIONREAD 来得到当前队列的长度。close(fd)将删除所有添加到 fd 中的 watch 并做必要的清理。

    int inotify_init (void); 
int inotify_add_watch (int fd, const char *path, __u32 mask); 
int inotify_rm_watch (int fd, __u32 mask); 

三、内核实现原理

在内核中,每一个 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;   /* maximum number of events */ 
    u32           last_wd;    /* the last wd allocated */ 
}; 

wq 是等待队列,被 read 调用阻塞的进程将挂在该等待队列上,idr 用于把 watch 描述符映射到对应的 inotify_watch,sem 用于同步对该结构的访问,events 为该 inotify 实例上发生的事件的列表,被该 inotify 实例监视的所有事件在发生后都将插入到这个列表,watches 是给 inotify 实例监视的 watch 列表,inotify_add_watch 将把新添加的 watch 插入到该列表,count 是引用计数,user 用于描述创建该 inotify 实例的用户,queue_size 表示该 inotify 实例的事件队列的字节数,event_count 是 events 列表的事件数,max_events 为最大允许的事件数,last_wd 是上次分配的 watch 描述符。

每一个 watch 对应一个 inotify_watch 结构:

struct inotify_watch { 
    struct list_head    d_list; /* entry in inotify_device's list */ 
    struct list_head    i_list; /* entry in inode's list */ 
    atomic_t        count; /* reference count */ 
    struct inotify_device  *dev;  /* associated device */ 
    struct inode      *inode; /* associated inode */ 
    s32           wd;   /* watch descriptor */ 
    u32           mask;  /* event mask for this watch */ 
}; 

d_list 指向所有 inotify_device 组成的列表的,i_list 指向所有被监视 inode 组成的列表,count 是引用计数,dev 指向该 watch 所在的 inotify 实例对应的 inotify_device 结构,inode 指向该 watch 要监视的 inode,wd 是分配给该 watch 的描述符,mask 是该 watch 的事件掩码,表示它对哪些文件系统事件感兴趣。

结构 inotify_device 在用户态调用 inotify_init() 时创建,当关闭 inotify_init()返回的文件描述符时将被释放。结构 inotify_watch 在用户态调用 inotify_add_watch()时创建,在用户态调用 inotify_rm_watch() 或 close(fd) 时被释放。