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

概述

inotify — a powerful yet simple file change notification system.

inotify是linux内核2.6.13以后支持的一种特性,功能是监视文件系统的变化,在监视到文件系统发生变化

以后,会向相应的应用程序发送变化事件。

inotify是一种文件系统的变化通知机制,如文件增加、删除等事件可以立刻让用户得知,该机制是著名的

桌面搜索引擎项目beagle引入的。

监测事件

头文件:#include

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值