Inotify是Linux文件系统监控的必要工具
本文主要介绍了如何使用inotify来控制Linux文件系统的事件。让我们看看什么是inotify和他的前一个具体的研究历史简介一看。我们还将介绍基于特定的应用和解决问题的方法。inotify介绍
文件系统事件监控各种程序是必要的,从文件管理器到一个安全的工具。由于内核的2.6.13版本开始,Linux将提供inotify功能,使得监控程序打开一个单独的文件描述符,和一系列具体事件监视一个或多个文件或目录,如打开、关闭、移动、重命名、删除、创建或更改属性。更多的改进是在以后的版本中提供,然后依靠这些特征,检查系统的内核版本。
在这篇文章中,您将学习如何在一个简单的监控程序使用inotify功能。下载示例代码和编译系统中准备以后的研究。
历史简介
基于之前,有dnotify。不幸的是,dnotify具有局限性,不能满足用户的需求,与inotify的优点如下:
Inotify使用简单的文件描述符,并dnotify需要每个监视的目录打开一个文件描述符,这使得它能同时监控多个目录的昂贵,也将遇到的每个进程的文件描述符的限制问题。
通过系统调用获得使用inotify文件描述符,并没有相关的设备或文件。为dnotify,文件描述符和目录是固定的关系,避免相关设备未加载的问题,这是手机媒体的一个典型问题。对于inotify,如果在监控文件或目录的文件系统不是装的,一个事件将产生,和显示器将被自动删除。
Inotify可以监视的文件或目录。dnotify监控目录,所以程序员必须保持数据结构或数据结构等效,反映的监控文件的目录,然后当一个事件发生时,当前的状态和比较已知发生什么目录条目。
如前所述,Inotify使用文件描述符,允许程序员监控事件与标准的select或poll函数。这允许高效的多我/ O或Glib的主循环一体化。相反,dnotify使用信号,这使得程序员更加困难或不流畅。在2.6.25版本的内核,文件还增加了信号驱动啊,通知功能。
API文件
文件提供了一个简单的API,用最小的文件描述符和允许细粒度的监控。通信与inotify是通过系统调用。
inotify_init
一个系统调用,用来创建一个inotify实例并返回一个文件描述符指向实例。
inotify_init1
类似inotify_init和额外的迹象。如果这些迹象都没有指定,作为inotify_init相同的值将被使用。
inotify_add_watch
增加对文件或目录的监视,并指定需要监视的事件。它用于控制是否将事件添加到现有监视中。是否需要一个路径代表一个目录来监视。我们需要跟踪符号链接吗我们是否有一次监控,在第一个事件发生时停止监视。
inotify_rm_watch
从监视列表中删除监视项。
读
读取包含一个或多个事件信息的缓存。
关闭
关闭文件描述符并删除描述符上的所有监视。当一个实例上的文件描述符关闭时,资源和下一个对象都将被释放,供内核再次使用。
因此,典型的监视器必须执行以下操作:
使用inotify_init打开的文件描述符;
添加一个或多个监视器;
等待事件;
处理事件,然后返回并等待更多事件;
当没有基于某些信号的主动监视或指示时,文件描述符被关闭、清空,然后退出。
在下一节中,您将看到可以监视的事件以及它们如何在简单的程序中运行。
通知
当应用程序读取通知时,事件的顺序也被读取到缓存中。事件以长变量结构返回,如清单1所示。如果数据充满缓存,则可能需要对最后一个条目进行本地事件信息或本地名称处理。
清单1。对于inotify事件结构
1.struct inotify_event
2。{
3.int WD表描述符。; / * * /
4.uint32_t面具看面具; / * * /
5.uint32_t曲奇饼干同步两个事件。; / * * /
6.uint32_t len长度(包括nuls); / * * /名称。
7.char名字__flexarr; / * * /名字。
8 };
注意,只有当被监测对象是一个目录和事件的相关项目内的相关目录,它将提供名称字段无论目录本身。如果in_moved_from事件和相应的in_moved_to事件都监测到的相关项目,饼干可用来将两事件类型返回。在面膜领域,是伴随着一个标志,可以设置内核。例如,如果一个事件是一个目录,旗in_isdir将由内核。
可以监视的事件
有几个能被监控的事件。有些事情,比如,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.if cookie,他们将能够看到这两个事件。如果只是移动或移动的非监控区,它只会看到一个事件。如果一个监测项目是移动或重命名,监测将继续看到in_move-self下面。
in_move
可以移动的事件就是前面提到的非常方便(in_moved_from in_moved_to |)逻辑或操作的面具。
in_create
在监视目录中创建子目录或文件。
in_delete
被监视目录中的子目录或文件被删除。
in_delete_self
监测项目本身被删除。监控是终止了in_ignored事件接受。
in_move_self
监测项目本身被移动了。
除了事件的旗帜,其他几个迹象可以在文件头文件发现( / usr / / /文件系统包括。H)。例如,如果你只想监视的第一个事件,你可以设置in_oneshot旗当你增加监测。
基于简单的应用
这里的简单应用遵循以上的一般逻辑,我们使用一个信号处理器监控Ctrl-C(SIGINT)和复位标志(keep_running)使应用程序能够理解终止操作。真正的inotify的调用是在实用程序完成。注意,我们还创建了一个队列,事件可以从潜在的对象inotify除去,留下以后处理。在实际应用中,您可能希望使用其他(高优先级)线程做这,这里只是列举了应用给出的一般原理的一个例子。我们采用一个简单的事件链。队列中的每个项目包含原始事件,以及将指针存储到队列中下一个事件的空间。
主程序
信号处理程序和主程序,如清单2所示。在这种情况下,所有的文件或目录,在命令行出现进行监测和事件掩盖in_all_events用于监控每个对象的每个事件。在实际应用中,你可能只想跟踪或文件和目录的创建删除事件,所以可以屏蔽打开,关闭和属性更改事件。如果你不是在重命名和移动文件或目录感兴趣,你也可以屏蔽各种移动事件。详情见inotify的帮助信息。
清单2的简单主程序。基于C的测试。
1、简单地重置标志以导致终止的信号处理程序。
2.void signal_handler(int正负号)
3。{
4.keep_running = 0;
5。}
6.int主要(int argc、argv char *)
7。{
8 / *这是inotify看文件描述符。
9.int inotify_fd;
10.keep_running = 1;
11 / *设置Ctrl-C信号处理程序。
12.if(信号(SIGINT,signal_handler)= sig_ign)
13。{
14 / *复位sig_ign(忽略)如果是之前的状态。
15.signal(SIGINT,sig_ign);
16。}
17 / *首先打开inotify开发入门。
18.inotify_fd = open_inotify_fd();
19.if(inotify_fd > 0)
20。{
21 / *我们将需要一个地方将inotify事件,
22.this是必要的因为如果你不读事件
23.fast足够,你会想念他们。这个队列
24.probably太小,如果你是监测点
25.like有很多文件和目录的目录
26.is删除。
27。
28.queue_t Q;
29。Q = queue_create(128);
30。这是我们为每个项目返回的表描述符。
31.watching。一个真正的应用程序可能会保留这些用于某些用途。
32.in应用。这个样品只确保没有
33.the表描述符小于0。
34。
35.int WD;
36 / *看所有的事件(in_all_events)的目录
37.files作为参数传入。
38、阅读文章,说明你为什么要改变这一点。
39.more有效使用您的应用程序文件。
40。
41.int指数;
42.wd = 0;
43.printf();
44.for(指数= 1;((指数= 0);指数+ +)
45。{
46.wd = watch_dir(inotify_fd,argv {指数},in_all_events);
47。}
48.if(WD > 0)
49。{
50、等待事件并将其处理到a
检测51.termination条件
52。
53.process_inotify_events(Q,inotify_fd);
54。}
55.printf(nterminatingn );
56、结束关闭FD,结束队列,
57.and返回正确的代码
58。
59.close_inotify_fd(inotify_fd);
60.queue_destroy(Q);
61。}
62.return 0;
63。}