设为首页 收藏本站
查看: 1083|回复: 1

[经验分享] 关于linux下的inotify

[复制链接]

尚未签到

发表于 2018-5-25 06:59:04 | 显示全部楼层 |阅读模式
1. inotify主要功能
  它是一个内核用于通知用户空间程序文件系统变化的机制。
  众所周知,Linux 桌面系统与 MAC 或 Windows 相比有许多不如人意的地方,为了改善这种状况,开源社区提出用户态需要内核提供一些机制,以便用户态能够及时地得知内核或底层硬件设备发生了什么,从而能够更好地管理设备,给用户提供更好的服务,如 hotplug、udev 和 inotify 就是这种需求催生的。Hotplug 是一种内核向用户态应用通报关于热插拔设备一些事件发生的机制,桌面系统能够利用它对设备进行有效的管理,udev 动态地维护 /dev 下的设备文件,inotify 是一种文件系统的变化通知机制,如文件增加、删除等事件可以立刻让用户态得知,该机制是著名的桌面搜索引擎项目 beagle 引入的,并在 Gamin 等项目中被应用。
2. 用户接口
  在用户态,inotify 通过三个系统调用和在返回的文件描述符上的文件 I/ 操作来使用,使用 inotify 的第一步是创建 inotify 实例:
  

  

                int fd = inotify_init ();
      每一个 inotify 实例对应一个独立的排序的队列。
      文件系统的变化事件被称做 watches 的一个对象管理,每一个 watch 是一个二元组(目标,事件掩码),目标可以是文件或目录,事件掩码表示应用希望关注的 inotify 事件,每一个位对应一个 inotify 事件。Watch 对象通过 watch描述符引用,watches 通过文件或目录的路径名来添加。目录 watches 将返回在该目录下的所有文件上面发生的事件。
      下面函数用于添加一个 watch:
  

                int wd = inotify_add_watch (fd, path, mask);
      fd 是 inotify_init() 返回的文件描述符,path 是被监视的目标的路径名(即文件名或目录名),mask 是事件掩码, 在头文件linux/inotify.h 中定义了每一位代表的事件。可以使用同样的方式来修改事件掩码,即改变希望被通知的inotify 事件。Wd 是 watch 描述符。
      下面的函数用于删除一个 watch:
  

        int ret = inotify_rm_watch (fd, wd);

    fd 是 inotify_init() 返回的文件描述符,wd 是 inotify_add_watch() 返回的 watch 描述符。Ret 是函数的返回值。      文件事件用一个 inotify_event 结构表示,它通过由 inotify_init() 返回的文件描述符使用通常文件读取函数 read 来获得
  :

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

    结构中的 wd 为被监视目标的 watch 描述符,mask 为事件掩码,len 为 name字符串的长度,name 为被监视目标的路径名,该结构的 name 字段为一个桩,它只是为了用户方面引用文件名,文件名是变长的,它实际紧跟在该结构的后面,文件名将被 0 填充以使下一个事件结构能够 4 字节对齐。注意,len 也把填充字节数统计在内。      通过 read 调用可以一次获得多个事件,只要提供的 buf 足够大。
  

                size_t len = read (fd, buf, BUF_LEN);

      buf 是一个 inotify_event 结构的数组指针,BUF_LEN 指定要读取的总长度,buf 大小至少要不小于 BUF_LEN,该调用返回的事件数取决于 BUF_LEN 以及事件中文件名的长度。Len 为实际读去的字节数,即获得的事件的总长度。
      可以在函数 inotify_init() 返回的文件描述符 fd 上使用 select() 或poll(), 也可以在 fd 上使用 ioctl 命令 FIONREAD 来得到当前队列的长度。close(fd)将删除所有添加到 fd 中的 watch 并做必要的清理。
  

                int inotify_init (void);
int inotify_add_watch (int fd, const char *path, __u32 mask);
int inotify_rm_watch (int fd, __u32 mask);
  

  

用于 inotify 的 API
  Inotify 提供一个简单的 API,使用最小的文件描述符,并且允许细粒度监控。与 inotify 的通信是通过系统调用实现。可用的函数如下所示:
inotify_init是用于创建一个 inotify 实例的系统调用,并返回一个指向该实例的文件描述符。inotify_init1与 inotify_init 相似,并带有附加标志。如果这些附加标志没有指定,将采用与 inotify_init 相同的值。inotify_add_watch增加对文件或者目录的监控,并指定需要监控哪些事件。标志用于控制是否将事件添加到已有的监控中,是否只有路径代表一个目录才进行监控,是否要追踪符号链接,是否进行一次性监控,当首次事件出现后就停止监控。inotify_rm_watch从监控列表中移出监控项目。read读取包含一个或者多个事件信息的缓存。close关闭文件描述符,并且移除所有在该描述符上的所有监控。当关于某实例的所有文件描述符都关闭时,资源和下层对象都将释放,以供内核再次使用。  因此,典型的监控程序需要进行如下操作:

  •   使用 inotify_init 打开一个文件描述符
  •   添加一个或者多个监控
  •   等待事件
  •   处理事件,然后返回并等待更多事件
  •   当监控不再活动时,或者接到某个信号之后,关闭文件描述符,清空,然后退出。
  在下一部分中,您将看到可以监控的事件,它们如何在简单的程序中运行。最后,您将看到事件监控如何进行。
  

可监控的事件
  有几种事件能够被监控。一些事件,比如 IN_DELETE_SELF 只适用于正在被监控的项目,而另一些,比如 IN_ATTRIB 或者 IN_OPEN 则只适用于监控过的项目,或者如果该项目是目录,则可以应用到其所包含的目录或文件。
IN_ACCESS被监控项目或者被监控目录中的条目被访问过。例如,一个打开的文件被读取。IN_MODIFY被监控项目或者被监控目录中的条目被修改过。例如,一个打开的文件被修改。IN_ATTRIB 被监控项目或者被监控目录中条目的元数据被修改过。例如,时间戳或者许可被修改。IN_CLOSE_WRITE 一个打开的,等待写入的文件或目录被关闭。IN_CLOSE_NOWRITE一个以只读方式打开的文件或目录被关闭。IN_CLOSE 一个掩码,可以很便捷地对前面提到的两个关闭事件(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)进行逻辑操作。IN_OPEN 文件或目录被打开。IN_MOVED_FROM 被监控项目或者被监控目录中的条目被移出监控区域。该事件还包含一个 cookie 来实现 IN_MOVED_FROM 与 IN_MOVED_TO 的关联。IN_MOVED_TO文件或目录被移入监控区域。该事件包含一个针对 IN_MOVED_FROM 的 cookie。如果文件或目录只是被重命名,将能看到这两个事件,如果它只是被移入或移出非监控区域,将只能看到一个事件。如果移动或重命名一个被监控项目,监控将继续进行。参见下面的 IN_MOVE-SELF。IN_MOVE 可以很便捷地对前面提到的两个移动事件(IN_MOVED_FROM | IN_MOVED_TO)进行逻辑操作的掩码。IN_CREATE 在被监控目录中创建了子目录或文件。IN_DELETE 被监控目录中有子目录或文件被删除。IN_DELETE_SELF 被监控项目本身被删除。监控终止,并且将收到一个 IN_IGNORED 事件。IN_MOVE_SELF 监控项目本身被移动。  除了事件标志以外,还可以在 inotify 头文件(/usr/include/sys/inotify.h)中找到其他几个标志。例如,如果只想监控第一个事件,可以在增加监控时设置 IN_ONESHOT 标志。
  

  相关链接

  http://www.ibm.com/developerworks/cn/linux/l-inotify/

  http://blog.csdn.net/sunrock/article/details/5675067

  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-480762-1-1.html 上篇帖子: linux gdb 条件断点 下篇帖子: Linux 分区小觑
累计签到:38 天
连续签到:1 天
发表于 2018-7-17 11:19:05 | 显示全部楼层
inotify在选中根文件内文件内容过大的情况下,检查会非常慢,有什么好的解决方案吗。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表