inotify机制在用户态下的使用方法

2011年9月24日 由 edsionte 留言 »

1.inotify是什么?

inotify机制用于监控文件系统,通过它可以监控一个或多个文件,如果该文件发生了指定事件,比如打开,读或写等,该机制会异步的响应用程序发出通知(或称为警告),应用程序根据文件系统发生的事件类型做出相应的反应。

2.inotify可以监控的事件

inotify使用一组宏来表示文件可以被监控的事件,这些宏在稍候介绍的inotify_add_watch()中使用。在没有特别说明的情况下,下面解释中的文件均指被监控的文件,并且即可以是普通文件又可以是目录文件。

IN_ACCESS:文件被访问,如果是目录文件,则指目录中的文件名被访问。

IN_MODIFY:文件被修改,如果是目录文件,则指目录中的文件名被修改。

IN_ATTRIB:文件属性被修改,比如使用chmod命令。

IN_CLOSE_WRITE:可写的文件被关闭。

IN_CLOSE_NOWRITE:不可写文件被关闭。

IN_CLOSE:文件被关闭,它等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)的效果。

IN_OPEN:文件被打开。

IN_MOVED_FROM:文件被移出监控区,比如使用mv命令将一个文件移出监控目录。

IN_MOVED_TO:文件(这个文件既可以是受监控的又可以是未受监控的)被移入监控区,比如使用mv和cp命令。

IN_MOVE:文件被移动,它等同于(IN_MOVED_FROM | IN_MOVED_TO)的作用效果。

IN_CREATE:在目录中创建一个新文件,比如touch或mkdir命令。

IN_DELETE:文件被删除,比如使用rm命令。

IN_DELETE_SELF:自删除,即一个可执行文件在执行时删除自己。

IN_MOVE_SELF:自移动,即一个可执行文件在执行时移动自己。

IN_UNMOUNT:宿主文件系统被 umount。

另外,IN_ISDIR宏用来判断被监控的文件是否为目录文件,该宏可以在应用程序对监控文件作监控处理时应用。

3.inotify用户态使用概述

inotify机制属于Linux在2.6.13之后增加的一个新特性,它属于dnotify机制的升级版。要使用inotify机制监控文件系统,那么必须先创建一个inotify的实例。由于Linux中的一切皆为文件,可以将inotify实例理解为一个“inotify类型的文件”,因此该实例会对应一个文件描述符,这也属于inotify优于dnotify的一大特性。

inotify机制的另一大特性即为监控程序对文件的监控不必轮询去查看,一旦监控的文件有指定的事件发生,它会异步通知监控程序,监控程序收到警告后会立马做出相应的响应。而在没有发生监控事件的时候,监控程序则一直处于阻塞状态。

这里的阻塞通过read()即可完成。当没有监控时间发生时,inotify实例中没有数据则read()阻塞;当有监控事件发生时,监控事件将被写入inotify实例中,此时read函数被唤醒读取该事件,监控程序根据读取的数据做出相应处理。这里的事件其实是通过字节流发送到inotify实例中的,因此可以通过read()函数来读取。为此,专门有一个数据结构来存储监控事件,即为struct inotify_event:

 struct inotify_event
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 */
}; 

该结构的定义位于用户态文件目录include/linux/inotify.h中,每个字段代表的含义如下:

wd:一个监视器(watch)的描述符,所谓监视器就是一个二元组(监视文件,事件掩码),其中事件掩码包含该文件被监视的所有事件。wd是通过inotify_add_watch()返回的,wd在此结构中与一个监视事件关联,即说明wd监视器上发生了当前inotify_event这个事件。

mask:该事件的类型即为当前结构中的mask,它是wd中所指定mask的一个子集。

len:表示当前结构中name的长度,但有时候name为了字节对齐会填充若干个0,因此len会大于等于name的长度。

name:表示监控文件的路径,这里通过GNU C中的0长度数组来表示变长的文件路径。

对inotify机制的典型使用方法如下:

1.创建并初始化一个inotify的实例,通过inotify_init()即可实现,该函数返回一个文件描述符。

2.添加一个或多个监控文件,即监视器,通过inotify_add_watch()即可实现,该函数就返回一个监视器的文件描述符。

3.循环等待监控事件的发生,通过循环read()inotify实例的fd即可实现。

4.如果有监控事件发生,则将fd中的字节流读取到inotify_event结构中,监控程序随之作适当处理,处理完毕后返回继续等待。

5.当不需要继续监控或收到某个代表监控结束的信号时,关闭inotify实例的文件描述符。

关于基本的使用流程还可以参考下图:

4.inotify用户态API

inotify的API都使用文件描述符,这样可以将监控粒度控制到单个文件,而dnotify机制的控制粒度则为单个目录。使用文件描述符更大的优势在于对inotify的操作也可以使用read()、close()、select()等这些传统的文件操作函数。

1.int inotify_init (void)

创建并初始化一个inotify实例,该函数返回一个文件描述符。可以认为这个函数是打开一个inotify类型的文件并返回该类型文件的描述符。

2.int inotify_add_watch (int __fd, const char *__name, uint32_t __mask)

增加监视文件(监视器),fd用于指明该文件被添加于哪个inotify实例,name用于指名该文件的路径,mask则指明了该文件所有的监控事件。该函数调用成功后返回一个监视器的描述符。

3.int inotify_rm_watch (int __fd, int __wd)

从fd中删除一个监视器,wd指名具体的监视器。

关于上述函数的详细的使用方法以及错误返回值等内容可以参考man手册。

参考:

IBM Developer Works:http://www.ibm.com/developerworks/cn/linux/l-ubuntu-inotify/index.html

广告位

2 条评论

  1. authurg说道:

    诶 亲 这个是为了我们毕设量身定制的么?

    [回复一下]

    edsionte 回复:

    @authurg, 你毕设是萨?

    [回复一下]

发表评论

windows 7 ultimate product key

windows 7 ultimate product key

winrar download free

winrar download free

winzip registration code

winzip registration code

winzip free download

winzip free download

winzip activation code

winzip activation code

windows 7 key generator

windows 7 key generator

winzip freeware

winzip freeware

winzip free download full version

winzip free download full version

free winrar download

free winrar download

free winrar

free winrar

windows 7 crack

windows 7 crack

windows xp product key

windows xp product key

windows 7 activation crack

windows7 activation crack

free winzip

free winzip

winrar free download

winrar free download

winrar free

winrar free

download winrar free

download winrar free

windows 7 product key

windows 7 product key