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。}