inotify

本页使用了标题或全文手工转换
维基百科,自由的百科全书

inotifyLinux核心子系统之一,做为文件系统的附加功能,它可监控文件系统并将异动通知应用程式。本系统的出现取代了旧有Linux核心里,拥有类似功能之dnotify模块。

inotify的原始开发者为John McCutchan罗伯特·拉姆Amy Griffis。于Linux核心2.6.13发行时(2005年六月十八日),被正式纳入Linux核心[1]。尽管如此,它仍可透过补丁的方式与2.6.12甚至更早期的Linux核心集成。

inotify的主要应用于桌面搜索软件,像:Beagle,得以针对有变动的文件重新索引,而不必没有效率地每隔几分钟就要扫描整个文件系统。相较于主动轮询文件系统,透过操作系统主动告知文件异动的方式,让Beagle等软件甚至可以在文件更动后一秒内更新索引。

此外,诸如:更新目录查看、重新加载配置文件、追踪变更、备份、同步甚至上传等许多自动化作业流程,都可因而受惠。

优点[编辑]

相较于被inotify取代较旧的 dnotify模块,inotify有诸多益处。[2][3]在旧的模块中,程序必须为每一个被监控的目录建立file descriptor,这种作法很容易让行程拥有的file descriptor逼近系统允许的上限,进而形成瓶颈。dnotify产生的file decriptor也会导致系统资源忙碌,使可移除装置无法被移除,徒增使用上的困扰。

由于dnotify只能让程序员监控目录层级的变化,“精细度”亦是“dnotify”的劣势之一。为此,程序员必须付出额外的心力,自行撰写代码以期追踪更细微的文件系统事件。

inotify相较之下使用较少的file descriptor,亦允许select()与poll()接口,优于dnotify使用的信号系统。这也使得inotify与既有以select()或poll()为基础之函式库(如:Glib)集成更加便利。

运作方式[编辑]

inotify拥有专为其设计的系统函数。十分容易上手。

 #include <sys/inotify.h>

要使用inotify必须先引用上面的头文件。

 int inotify_init(void)

建立一个inotify的实体并回传一个file descriptor,此文件描述符可供读取文件事件。随后,可透过read()接收事件,为了避免不断轮询文件,read()默认将采用同步I/O的模式,直到事件发生后才会返回。

 int inotify_add_watch(int fd, const char* pathname, int mask)

透过路径名称(pathname)并选定掩码(mask)以监控inode。inotify_add_watch()会回传一个监控器(watch descriptor),它代表pathname指向的inode(不同的pathname有可能指向相同的inode)。

 int inotify_rm_watch(int fd, int wd)

取消对某个路径之监控。

如同之前所描述的,当文件系统异动时,核心将会依据程序设置的条件,触发相应的事件。事件的结构如下:

字段名称 内容描述
wd 监控子
mask 事件掩码
cookie 用来辨别IN_MOVED_FROMIN_MOVED_TO事件
len name字段长度
name 触发该事件的文件名称(以上层目录为基准)

可供应用程式追踪的事件有:

  • IN_ACCESS - 读取文件
  • IN_MODIFY - 文件被修改
  • IN_ATTRIB - 文件属性变更
  • IN_OPEN - 文件被开启
  • IN_CLOSE_WRITE - 被开启为“可写入”状态的文件遭关闭
  • IN_CLOSE_NOWRITE - 被开启为“非写入”状态的文件遭关闭
  • IN_MOVED_FROM and IN_MOVED_TO - 文件被搬动或更名
  • IN_DELETE - 文件或目录被删除
  • IN_CREATE - 监控中的目录下有新文件产生
  • IN_DELETE_SELF - 监控中的文件遭删除

缺点[编辑]

inotify无法监控软链接型的子目录。

历史沿革[编辑]

相关条目[编辑]

参考资料[编辑]

  1. ^ Linux 2.6.13, kernelnewbies.org. [2012-03-06]. (原始内容存档于2020-10-19). 
  2. ^ Why inotify?. [2012-03-06]. (原始内容存档于2010-01-16). 
  3. ^ inotify README file. [2012-03-06]. (原始内容存档于2016-12-29). 

外部链接[编辑]