inotify框架的使用和原理!如何添加对于目标文件的watch呢?

1. 概论
inotify是linux中用于监控文件系统变化的一个框架,不同于前一个框架dnotify, inotify可以实现基于inode的文件监控。也就是说监控对象不再局限于目录,也包含了文件。不仅如此,在事件的通知方面,inotify摈弃了dnotify的信号方式,采用在文件系统的处理函数中放置hook函数的方式实现。
2. 用户层
2.1 数据结构
在inotify中,对于一个文件或目录的监控被称为一个watch。 给某一个文件或目录添加一个watch就表示要对该文件添加某一类型的监控。监控的类型由一个掩码mask表示,mask有:
in_access : 文件的读操作
in_attrib : 文件属性变化
in_close_write : 文件被关闭之前被写
in_close_nowrite : 文件被关闭
in_create : 新建文件
in_delete : 删除文件
in_modify : 修改文件
in_move_self : 被监控的文件或者目录被移动
in_moved_from : 文件从被监控的目录中移出
in_moved_to : 文件从被监控的目录中移入
in_open : 文件被打开
事件的类型有了,我们还需要一个结构体去表示一次事件, 在用户空间,inotify使用inotify_event表示一个事件,每一个事件都有一个特定的身份标示wd, wd是一个整型变量。每一个事件都有一组事件类型与其关联(in_create | in_open)。 事件中还应包含文件名。
struct inotify_event {
int wd;/* watch descriptor */
uint32_t mask;/* mask of events */
uint32_t cookie;/* unique cookie associating related
events (for rename(2)) */
uint32_t len;/* size of name field */
char name[];/* optional null-terminated name */
};
2.2函数及inotify的使用
为了防止文件描述符fd的快速消耗,inotify提出了一个inotify instance(inotify实例)的概念。每一个inotify实例表示一个可读写的fd, 一个inotify实例链接有多个对于文件的watch。而函数inotify_init的工作就是生成一个inotify实例。
如何添加对于目标文件的watch呢?使用inotify_add_watch完成该任务,inotify_add_watch有三个参数,第一个参数是该watch所属的实例的fd, 第二个参数是被监控的文件名,第三个参数要监控的事件类型。
有添加就有删除, inotify_rm_watch(int fd, int wd)完成watch的删除工作,类似的, fd表示实例,wd表示即将删除的watch.
void handle_event(int fd){
for(;;){
int len =0;
char buf[bufsize];
read(fd, buf, bufsize);
int i =0;
char*p;
for(p = buf; p len){
event =(struct inotify_event *)p;
if(event -> mask & in_open)
printf(in_open);
}
}
}
int main(void){
int fd;
if((fd = inotify_init())<0){
perror(init error);
}
if(inotify_add_watch(fd,/home, in_open|in_delete) 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 */
unsignedint queue_size; /* size of the queue (bytes) */
unsignedint event_count; /* number of pending events */
unsignedint max_events; /* maximum number of events */
u32 last_wd; /* the last wd allocated */
};
图3-7
3.2.2 inotify_kernel_event
kernel_event结构封装了一个用户态的event结构, 代表相应文件产生的一次事件, 该结构链接在inotify_device中的events链表.
struct inotify_kernel_event {
struct inotify_event event;/* the user-space event */
struct list_head list;/* entry in inotify_device's list */
char *name;/* filename, if any */
};
3.2.2 inotify_watch
inotify_watch表示我们向文件添加一个监控. 他分别链接到两个链表,一个链表头在inode结构中, 另一个在inotify_device结构中.
struct inotify_watch {
struct list_head d_list;/* entry in inotify_device's list */
struct list_head i_list;/* entry in inde'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 */
};
3.3 深入api
接下来我以inotify的用户接口为例, 带大家深入探索一下这些函数究竟做了什么.
3.3.1 inotify_init
inotify_init函数的作用是给进程分配一个用于读写inotify事件缓冲区的一个fd.
图3-8
3.3.2 inotify_add_watch
inotify_add_watch有三个参数, watch所属的文件描述符,被监控的目标文件或者目录的路径, 事件掩码.
究竟add_watch是怎样的一个过程, 让我们拭目以待.
图3-9
3.4 事件究竟从何而来
上文提到, inotify在文件系统的每个文件操作函数中插入了一系列的钩子函数, 由此inotify就可以记录用户对于文件的各种操作. 简单粗暴有没有 … …
其中一个主要的函数是 inotify_inode_queue_event, 该函数的主要功能是遍历inode的inotify_watches链表, 由watch为根, 找到挂在inotify_device上的事件, 并将事件插入事件队列(inotify_dev_queue_event).
图3-10
可以看到这个函数最终还是调用了inotify_dev_queue_event函数, inotify_dev_queue_event的主要功能是将生成事件并将其插入inotify_device结构的events链表.
总结
以上我以2.6.13版本的内核为例阐述了inotify框架的使用和原理. 本来打算是以最新版本内核为例的, 但是在4.15中, 内核合并dnotify inotify fanotify这三个框架并且抽象出一个新的接口fsnotify, 代码改动较大, 不利于讲解inotify的原理, 所以我选择了第一次合并inotify的2.6.13内核.

中国正式开始从工业大国迈向商业大国
成飞成功研发新款无人机--风影,歼20只是开始
索尼TX7高清卡片虎年受宠
手机界回归大戏,夏普手机备了什么“秘密武器”?
iPhone15Pro系列搭载全球首款3nm手机芯片——A17 Pro
inotify框架的使用和原理!如何添加对于目标文件的watch呢?
小米10系列参数总览 快速看懂小米10系列
三星S8、三星S7 edge、iPhone 7 Plus测评对比,谁才是真正的一代机皇?
各国5G套餐资费已陆续公布我国的5G资费水平会是怎样的
怎么用手机远程控制开关?
超过M1芯片?苹果A17芯片与M1芯片的对比
卢伟冰:搭载联发科的红米Note8,可以实现游戏手机的大众化?
什么是CRM (Customer Relationship
我国制造企业数字转型陷入僵局面临着三大困难和瓶颈
我国有了全新独立自主知识产权的新能源汽车的核心部件
热对LED影响分析及不同材质LED的温度系数
Google Cloud将向远程医疗平台供应商注资1亿美元
LTC3625/LTC3625-1-具自动电池平衡功能的1A
静电放电保护器件种类与特点
极海功能安全设计套件满足客户不同产品功能安全认证需求