linux文件系统变化通知机制—inotify

news/2024/7/9 16:08:33 标签: 操作系统, epoll

概述

 

inotify — a powerful yet simple file change notification system.
inotify是linux内核2.6.13以后支持的一种特性,功能是监视文件系统的变化,在监视到文件系统发生变化
以后,会向相应的应用程序发送变化事件。
inotify是一种文件系统的变化通知机制,如文件增加、删除等事件可以立刻让用户得知,该机制是著名的
桌面搜索引擎项目beagle引入的。

 

监测事件

 

头文件:#include <sys/inotify.h>

Supported events suitable for MASK parameter of inotify_add_watch.

/* File was accessed. 文件被访问。*/
#define IN_ACCESS 0x00000001 

/* FIle was modified. 文件被修改。*/
#define IN_MODIFY 0x00000002 

/* Metadata changed. 文件属性被修改,如chmod、chown、touch等。*/
#define IN_ATTRIB 0x00000004 

/* Writtable file was closed. 可写文件被关闭。*/
#define IN_CLOSE_WRITE 0x00000008 

/* Unwrittable file closed. 不可写文件被关闭。*/
#define IN_CLOSE_NOWRITE 0x00000010 

/* 文件被关闭。*/
#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) 

/* File was opened. 文件被打开。*/
#define IN_OPEN 0x00000020

/* File was moved from X. 文件被移走,如mv。*/
#define IN_MOVED_FROM 0x00000040 

/* File was moved to Y. 文件被移来,如mv、cp。*/
#define IN_MOVED_TO 0x00000080 

/* Moves. 文件被移动。*/
#define IN_MOVED (IN_MOVED_FROM | IN_MOVED_TO) 

/* Subfile was created. 创建新文件。*/
#define IN_CREATE 0x00000100

/* Subfile was deleted. 文件被删除,如rm。*/
#define IN_DELETE 0x00000200 

/* Self was deleted. 自删除,即一个可执行文件在执行时删除自己。*/
#define IN_DELETE_SELF 0x00000400 

/* Self was moved.  自移动,即一个可执行文件在执行时移动自己。*/
#define IN_MOVE_SELF 0x00000800

Events sent by the kernel.

/* Backing fs was unmounted. 宿主文件系统被unmount。*/
#define IN_UNMOUNT 0x00002000

/* Event queued overflowed. 在内核中,事件的数据超过了
 * inotify_device中的max_events。*/
#define IN_Q_OVERFLOW 0x00004000

/* File was ignored. 表示系统把该文件对应的watch从inotify实例中
 * 删除,因为文件已经被删除了!*/
#define IN_IGNORED 0x00008000  

Special flags.

/* Only watch the path if it is a directory. */
#define IN_ONLYDIR 0x01000000 

/* Do not follow a sym link. */
#define IN_DONT_FOLLOW 0x02000000

/* Add to the mask of an already existing watch. */
#define IN_MASK_ADD 0x20000000 

/* Event occurred against dir. */
#define IN_ISDIR 0x40000000 

/* Only send event once. */
#define IN_ONESHOT 0x80000000  

All events which a program can wait on.

#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE \
    | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | IN_MOVED_TO \
    | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF)

 

API函数

 

inotify主要提供如下API。

(1)创建inotify实体

/* Create and initialize inotify instance. */
extern int inotify_init (void) __THROW;

inotify_init()在内核中创建一个实体:inotify_device,并返回一个文件描述符。
使用:int fd = inotify_init();

(2)创建监视器

/* Add watch of object NAME to inotify instance FD. Notify about events 
 * specified by MASK. 
 */
extern int inotify_add_watch (int __fd, const char * __name, uint32_t __mask) 
    __THROW;

inotify_add_watch用于向inotify_device中的监视器列表添加监视器:inotify_watch。
创建监视器要提供:
(1) inotify实例inotify_device的文件描述符:fd
(2) 监视目标路径:name
(3) 监视事件列表:mask
如果成功,返回监视器描述符wd,否则返回-1。

(3)删除监视器

/* Remove the watch specified by WD from the inotify instance FD. */
extern int inotify_rm_watch (int __fd, uint32_t __wd) __THROW;

 用于从inotify_device的监视器列表中删除一个监视器。

 

读取事件

 

为了确定哪些文件系统事件发生,需要用read系统调用读取inotify_init()返回的文件描述符。
read()会返回一个或多个inotify_event。

/* Structure describing an inotify event. */

struct inotify_event
{
    int wd; /* Watch descriptor. */
    unit32_t mask; /* Watch mask */
    unit32_t cookie; /* Cookie to synchronize two events. */
    unit32_t len; /* Length (including NULLs) of name. */
    char name __flexarr; /* Name. */
};

inotify_event为文件系统事件。
其中wd为被监视目标的watch描述符,mask为事件掩码,name为监视目标的路径名,
len为name的长度。
每个notify_event的结构体大小为:sizeof(struct inotify_event) + len。
通过inotify_event可以看出:

(1) 监视目标(什么文件/目录) —> name,len
(2) 监视器 —> wd
(3) 监视目标的什么事件 —> mask

通过read()可以一次性获得多个事件,只要提供的buf足够大。
size_t len = read(fd, buf , MAX_BUF_SIZE);
len为实际获得的事件集总长度。
可以在函数inotify()返回的文件描述符fd上使用select()或poll()、epoll(),也可以在fd上使用ioctl命令
FIONREAD来得到当前队列的长度。
close(fd)将删除所有添加到fd中的watch并做必要的清理。 

 

内核实现简述

 

Each inotify instance is represented by an inotify_handle structure.
Inotify's userspace consumers also have an inotify_device which is
associated with the inotify_handle, and on which events are queued.
Each watch is associated with an inotify_watch structure. Watches are chained
off of each associated inotify_handle and each associated inode.
See fs/notify/inotify/inotify_fsnotify.c and fs/notify/inotify/inotify_user.c for
the locking and lifetime rules.

无论是目录还是文件,在内核中都对应一个inode结构,inotify系统再inode结构中增加了两个字段:
#ifdef CONFIG_INOTIFY
        struct list_head inotify_watches; /* watches on this  inode */
        struct semaphore inotify_sem; /* protects the watches list */
#endif

 

Reference

 

1. documentation \ filesystems \ inotify.txt
2. include \ linux \ inotify.h
3. http://www.ibm.com/developerworks/cn/linux/l-inotifynew/
4. http://tianyapiaozi.blogbus.com/logs/61783047.html

转载于:https://www.cnblogs.com/aiwz/archive/2012/05/18/6333384.html


http://www.niftyadmin.cn/n/1423415.html

相关文章

ExtAspNet v3.1.6

如果曾经你听到别人这么说&#xff1a; ExtAspNet简单&#xff0c;易用&#xff0c;稳定&#xff0c;而且有100多个中文示例照顾了开发中的各个方面&#xff0c;唯独的缺陷是少了一个文档&#xff0c;想查个参数都麻烦.... 那么&#xff0c;从今天起忘掉这句话吧。 ExtAspNet终…

Microsoft AjaxToolkits之14. DropShadow控件

DropShadow主要功能是为控件设置阴影效果&#xff08;锐化边角效果&#xff0c;阴影效果&#xff0c;阴影透明&#xff09; 属性列表&#xff1a;TargetControlID - 要应用阴影的控件的IDWidth – 阴影的宽度&#xff0c;默认是5Opacity -阴影的透明度&#xff08;0(不透明)-1.…

DNN 社交挂件模块和DNN天气模块

1、DNN 社交挂件模块 该模块可以使你轻松的将各种社交部件添加到你的站点。 下载地址&#xff1a; http://socialhelpers.codeplex.com/ 2、DNN天气模块 该模块展示天气预报 下载地址 http://weather.codeplex.com/转载于:https://www.cnblogs.com/zgblog/archive/2012/05/23/2…

在Windows64位环境下.net访问Oracle解决方案

在Windows64位环境下.net访问Oracle解决方案 引用地址&#xff1a;http://blog.csdn.net/zouyujie1127/article/details/6371165目前&#xff0c;Windows操作系统可以分成两类&#xff0c;32位和64位&#xff08;64位也区分x86_64位和 Itanium &#xff09;&#xff0c;同时Ora…

SDUT 2129树结构练习——判断给定森林中有多少棵树(并查集)

题目链接&#xff1a;http://acm.sdut.edu.cn/sdutoj/problem.php?actionshowproblem&problemid2129 最裸的并查集。。模板代码&#xff0c;好久没打过了。 #include<stdio.h> int p[1001]; int find(int x) {int ax;while(p[a]!a)ap[a];return a; } void mermge(in…

Python练习—Google’s Python Class

首先介绍下正则表达式&#xff1a; 1)python中提供了re模块来进行正则表达式支持&#xff0c;因此第一步 import re 2)几个常用的方法&#xff1a; match re.search(pat, str) 注意点&#xff1a;1.match是个对象,使用match.group()来输出匹配文本,若失败返回None 2.search从…

Cowboy 源码分析(十)

在上一篇中&#xff0c;由于我对 erlang:decode_packet/3 方法的不理解&#xff0c;所以造成了对 cowboy_http_protocol:request/2 方法的困惑&#xff0c;这一篇&#xff0c;我将结合 erlang Debugger 工具 和 HttpFox 工具来看看&#xff0c;究竟是怎么回事。Debugger 我就不…

漫反射光照模型

Lambertian漫反射模型假设反射光均匀分布在所有方向&#xff0c;简单方便。 1、Oren-Nayar漫反射 一些粗糙的表面具有很大程度逆反射的性质(反射向量和入射光线在发现的同一边)。 sigma是表面的粗糙度 该算法在光照向量和观察向量比较接近时最有效。 效果&#xff1a; roughnes…