基于inotify的文件监控方案

2024-02-24 05:08
文章标签 监控 方案 inotify

本文主要是介绍基于inotify的文件监控方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近在做一个linux上的文件监控程序,2.6内核提供了inotify机制,这仅仅是个机制,任何策略都必须自己实现,这一点从inotify不提供递归接口就可以看出来,如果我实时监控到目录被创建,那么马上将这个新目录加入监控表,这个想法是最初的想法,也是最直接的想法,可是仔细推敲一下就会发现这个实现有问题,比如在检测到目录被创建到新目录添加到监控表的时间间隔内,新的子目录的文件事件以及目录事件将被遗漏,而且会像丝袜脱丝一样一发不可收拾,新子目录内又创建了一个目录没有被监控到,那么这个子子目录内的事件将递归的丢失,看来这个事情很严重,那么有没有办法呢?前面说了一种补救的办法,可是难度太大,没有必要,仔细想想这种丢失并不是频繁发生,只有在像cp -r或者tar快速创建目录时才会发生,既然我们没有办法实现补救方案,那么可以从进程执行这个大框架入手,如果我们可以让cp或者tar在监控程序加入新目录之前不执行就可以了,于是可以通过优先级来实现,将监控程序设置为实时FIFO优先级就可以了。当文件系统的系统调用执行完,inotify开始执行的时候,最后会wake up等待inotify描述符的监控进程,而在系统调用返回用户空间的时候会检查need_sched标志位,因为监控进程是实时调度类,优先级是很高的,因此必定会抢占当前的文件操作的进程,可是在多cpu上怎么能保证这个文件操作进程不被调度到别的cpu上呢?说实话,不能,于是有了下面的解决方案。

文件同步方案已经找到,还是用inotify,利用inotify-tools工具的inotifywait程序对目录进行监控,并且实时加入新创建的子目录,为了避免遗漏,我的做法是:

单cpu方案:

解决办法:将监控进程的优先级设置为FIFO实时优先级,根据inotify的内核实现和2.6内核的进程调度原理(根据是2.6.X的内核源代码),实时优先级的监控进程总是可以在新子目录创建文件前首先加入该子目录,这样就不会遗漏了。

多cpu方案:

问题:因为在多cpu的情况下,即使将监控进程设置为FIFO的实时进程,那么还是可能将cp -r或者tar等快速创建子目录和文件的进程调度到别的cpu,从而和我们的监控进程构成竞争最终造成事件遗漏。

解决办法:将监控进程分解为多个线程,每个cpu绑定一个线程,这些线程共享一个inotify描述符,这样就不会造成读取的事件重复。如此一来,在新目录被添加以后,每个cpu上的均会运行实时FIFO线程,从而把任何非实时进程的执行拦截。在多cpu上,实际只要有一个文件操作,就会唤醒所有cpu上的监控进程,这是靠ipi(处理器间中断)实现的。

效果:经过测试,发现没有遗漏。

仍然具有的问题:从内核源代码来看,如果没有将内核编译成内核抢占,那么还是有可能遗漏,只不过这种可能性非常之小,我用tar和cp -r没有测试出来。

虽然每个cpu一个监控进程解决了大致框架问题,但是又引入了新的问题,怎么处理这么多的进程间的通信,inotifywait是用红黑树实现的文件索引,那么多的线程肯定会打乱红黑树的,于是又有了新的想法。想想看设置多个线程,每个cpu一个线程的原因就是靠这些线程的优先级是实时FIFO来阻止新目录加入监控表前的文件操作,于是我们只要保证一个cpu上进行实际工作,别的cpu上的线程不做任何监控,只是一个桩就可以了,现在问题就是这个桩怎么设计,很简单,办法有两个,一个就是在别的cpu的线程随便实现一个无限的等待循环,另一个方案就是在别的cpu上执行inotify描述符的select而不做read,这种方案一定可以,相信我没错的。

这篇关于基于inotify的文件监控方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/741016

相关文章

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

IDEA中Git版本回退的两种实现方案

《IDEA中Git版本回退的两种实现方案》作为开发者,代码版本回退是日常高频操作,IntelliJIDEA集成了强大的Git工具链,但面对reset和revert两种核心回退方案,许多开发者仍存在选择... 目录一、版本回退前置知识二、Reset方案:整体改写历史1、IDEA图形化操作(推荐)1.1、查看提

Python实现html转png的完美方案介绍

《Python实现html转png的完美方案介绍》这篇文章主要为大家详细介绍了如何使用Python实现html转png功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 1.增强稳定性与错误处理建议使用三层异常捕获结构:try: with sync_playwright(

Java使用多线程处理未知任务数的方案介绍

《Java使用多线程处理未知任务数的方案介绍》这篇文章主要为大家详细介绍了Java如何使用多线程实现处理未知任务数,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 知道任务个数,你可以定义好线程数规则,生成线程数去跑代码说明:1.虚拟线程池:使用 Executors.newVir

MySQL中闪回功能的方案讨论及实现

《MySQL中闪回功能的方案讨论及实现》Oracle有一个闪回(flashback)功能,能够用户恢复误操作的数据,这篇文章主要来和大家讨论一下MySQL中支持闪回功能的方案,有需要的可以了解下... 目录1、 闪回的目标2、 无米无炊一3、 无米无炊二4、 演示5、小结oracle有一个闪回(flashb

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式

Java嵌套for循环优化方案分享

《Java嵌套for循环优化方案分享》介绍了Java中嵌套for循环的优化方法,包括减少循环次数、合并循环、使用更高效的数据结构、并行处理、预处理和缓存、算法优化、尽量减少对象创建以及本地变量优化,通... 目录Java 嵌套 for 循环优化方案1. 减少循环次数2. 合并循环3. 使用更高效的数据结构4

Vue中动态权限到按钮的完整实现方案详解

《Vue中动态权限到按钮的完整实现方案详解》这篇文章主要为大家详细介绍了Vue如何在现有方案的基础上加入对路由的增、删、改、查权限控制,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、数据库设计扩展1.1 修改路由表(routes)1.2 修改角色与路由权限表(role_routes)二、后端接口设计

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

通过prometheus监控Tomcat运行状态的操作流程

《通过prometheus监控Tomcat运行状态的操作流程》文章介绍了如何安装和配置Tomcat,并使用Prometheus和TomcatExporter来监控Tomcat的运行状态,文章详细讲解了... 目录Tomcat安装配置以及prometheus监控Tomcat一. 安装并配置tomcat1、安装