Linux inotify机制 – 监控文件系统事件
描述信息
在Linux中,inotify API提供了一种机制来监控文件系统的事件信息。Inotify可以监控文件亦或者是目录。当一个目录被监控时,inotify会返回这个目录本身所发生的事件以及目录内的文件所发生的事件信息。
常用的API:
- inotify_init()函数创建一个inotify的实例,返回一个被inotify实例引用的文件描述符。inotify_init1()函数的功能和inotify_init()一致,只不过多了一个标志参数 ,提供对某些额外功能的访问。
- inotify_add_watch()函数操纵与inotify实例相关联的“watch list”,即监控列表。每一个在监控列表里的项目都被指定了相应文件或目录的路径,系统就是通过这些路径来监控相应的文件或者目录的事件集。inotify_add_watch()既不新建新的监控项目,也不会修改现有的监控项目。每一个监控项目都有属于自己独一无二的“监控描述符”,这是一个整数值,inotify_add_watch()调用成功后会返回这个值。
- 当被监控的文件或者目录发生了相应的事件后,这些事件信息可用通过read()函数来读取。
- inotify_rm_watch()将从监控列表里移除指定的监控项目。
- 当所有的监控项目都被关闭(使用close()函数),这些项目的资源会被内核释放。
从inotify文件描述符中读取事件信息
想要知道被监控的文件或目录发生了什么,需要用read()函数读取inotify文件描述符。如果在read()函数被调用时尚未发生任何事件,那么read()函数将会一直阻塞等待事件的发生,除非收到了中断信号。read()函数每一次成功的调用,都会返回一个包含着监控事件的结构体:
struct inotify_event {
int wd; /* Watch descriptor */
uint32_t mask; /* Mask describing event */
uint32_t cookie; /* Unique cookie associating related events (for rename(2)) */
uint32_t len; /* Size of name field */
char name[]; /* Optional null-terminated name */
};
wd
即为监控描述符独一无二的编号mask
包含着描述事件类型的位信息,下面还会介绍。cookie
是连接着相关联的事件的独一无二的一个整数。目前来说,这只能用于重命名事件,允许应用程序连接IN_MOVED_FROM
和IN_MOVED_TO
事件的结果集。除了这两个事件之外,其他的事件的cookie
都被设置为0。name
字段只会在监控一个目录的事件时才会被提供,如果只是监控一个文件,这个字段将为空。len
字段记录着name
字段的长度。每一个inotify_event
结构体的长度是sizeof(struct
,不要以为
inotify_event)+lenlen
就是inotify_event
结构体的长度。
当读取的buffer大小不足时,返回值会根据内核的不同而不同。内核2.6.21以前会返回0,从2.6.21以后会返回EINVAL
。sizeof(struct inotify_event) + NAME_MAX + 1
能够保证至少读取一个事件的信息。
inotify events
IN_ACCESS
:文件被访问IN_ATTRIB
:元数据被更改。比如访问权限、访问时间等等。IN_CLOSE_WRITE
:已写入的文件被关闭。(原文:File opened for writing was closed.)(可写文件被关闭)IN_CLOSE_NOWRITE
:未写入的文件或目录被关闭(原文:File or directory not opened for writing was closed)(文件不可写或目录已经关闭)IN_CREATE
:文件或目录被创建IN_DELETE
:文件或目录从监控的目录中删除IN_DELETE_SELF
:被监控的目录自己被删除IN_MODIFY
:文件被修改IN_MOVE_SELF
:监控的目录自己被移动IN_MOVED_FROM
:Generated for the directory containing the old filename when a file is renamedIN_MOVED_TO
:Generated for the directory containing the new filename when a file is renamedIN_OPEN
:文件或目录被打开IN_MOVE
:相当于IN_MOVED_FROM | IN_MOVED_TO
IN_CLOSE
:相当于IN_CLOSE_WRITE | IN_CLOSE_NOWRITE
IN_DONT_FOLLOW
(since Linux 2.6.15):如果是符号链接,不要取消引用路径名IN_EXCL_UNLINK
(since Linux 2.6.36):By default, when watching events on the children of a directory, events are generated for children even after they have been unlinked from the directory. This can result in large numbers of uninteresting events for some applications (e.g.,if watching /tmp, in which many applications create temporary files whose names are immediately unlinked). SpecifyingIN_EXCL_UNLINK
changes the default behavior, so that events are not g