土法炼钢兴趣小组的算法知识备份

【操作系统百科】文件变化通知

文章导航

分类入口
os
标签入口
#inotify#fanotify#fsnotify#dnotify#file-watch

目录

文件编辑器要感知外部修改、搜索引擎要索引新文件、杀毒软件要扫描打开的文件——都需要”文件变化通知”。Linux 经历了 dnotify → inotify → fanotify 三代。

一、先看图

flowchart LR
    VFS[VFS 操作<br/>create/write/rename...] --> FSN[fsnotify 框架]
    FSN --> INOT[inotify 后端<br/>per-watch fd]
    FSN --> FAN[fanotify 后端<br/>per-mount/sb]
    FSN --> AUDIT[audit 后端]
    INOT --> APP1[用户进程<br/>read 事件]
    FAN --> APP2[用户进程<br/>read + 拦截]
    classDef kern fill:#388bfd22,stroke:#388bfd,color:#adbac7;
    classDef user fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    class VFS,FSN kern
    class INOT,FAN,AUDIT kern
    class APP1,APP2 user

二、fsnotify 内核框架

所有文件通知共享 fsnotify 基础设施:

三、dnotify(已废弃)

fcntl(dirfd, F_NOTIFY, DN_MODIFY | DN_CREATE);

缺点:只能监控目录 fd、用 signal 通知(不安全)、不告诉你是哪个文件变了。

四、inotify

4.1 API

int ifd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
int wd = inotify_add_watch(ifd, "/tmp", IN_CREATE | IN_MODIFY | IN_DELETE);
// read(ifd, buf, ...) → struct inotify_event
inotify_rm_watch(ifd, wd);

4.2 优势

4.3 限制

4.4 递归监控

应用需要手动递归添加 watch → 大目录树要加几万个 watch → 消耗内存(每 watch ~1KB 内核内存)。

sysctl fs.inotify.max_user_watches=524288

VS Code、IntelliJ、webpack 都靠 inotify。

五、fanotify

5.1 特点

5.2 API

int fan_fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_REPORT_FID, O_RDONLY);
fanotify_mark(fan_fd, FAN_MARK_ADD | FAN_MARK_FILESYSTEM,
    FAN_CREATE | FAN_DELETE | FAN_MODIFY | FAN_ONDIR,
    AT_FDCWD, "/mnt");
// read(fan_fd, buf, ...) → struct fanotify_event_metadata

5.3 拦截模式

// 读到 FAN_OPEN_PERM 事件
struct fanotify_response resp = {
    .fd = event->fd,
    .response = FAN_ALLOW,  // 或 FAN_DENY
};
write(fan_fd, &resp, sizeof(resp));

杀毒软件(ClamAV on-access scanner)用这个。

5.4 FAN_REPORT_FID

fanotify_init(FAN_REPORT_FID | FAN_REPORT_DIR_FID | FAN_REPORT_NAME, ...);

事件包含目录 file handle + 文件名 → 可以定位到完整路径,不需要 per-directory watch。

六、对比

特性 dnotify inotify fanotify
粒度 目录 目录(+文件名) mount/sb/文件系统
递归 手动 FAN_REPORT_FID 原生
拦截 FAN_*_PERM
通知方式 signal fd (read) fd (read)
权限 用户 用户 需要 CAP_SYS_ADMIN

七、高频场景与 overflow

npm install 创建几万文件 → inotify 事件风暴 → queue overflow。

缓解:

八、audit 联动

audit 子系统也用 fsnotify:

auditctl -w /etc/passwd -p wa -k passwd_changes

每次写 /etc/passwd 产生 audit 记录。与 inotify/fanotify 并行。

九、观察

# inotify watch 使用
find /proc/*/fdinfo -name '*' -exec grep -l inotify {} \; 2>/dev/null
cat /proc/sys/fs/inotify/max_user_watches

# fanotify
cat /proc/sys/fs/fanotify/max_user_marks

十、小结


参考文献

工具


上一篇xattr/ACL/capabilities 下一篇OverlayFS

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-05-06 · os

【操作系统百科】内核内存调试

内核内存 bug 是最难追的:UAF、OOB、double free、leak 都可能沉默数月。本文讲 KASAN 三种模式、KFENCE 生产采样、kmemleak、SLUB_DEBUG、UBSAN/KCSAN 联动。

2026-05-08 · os

【操作系统百科】VFS 四层抽象

Linux 的一切皆文件靠 VFS 实现——superblock、inode、dentry、file 四层抽象加 ops 表。本文讲 VFS 核心数据结构、dcache、inode cache、RCU lookup,以及文件系统如何插入 VFS。

2026-04-22 · os

操作系统百科

Linux 6.x 视角下的操作系统系列索引:110 篇覆盖调度、虚拟内存、文件系统与 I/O、并发、隔离、可观测性,按主题、阅读路径与关键问题三种入口组织。

2026-05-27 · os

【操作系统百科】用户态分配器:jemalloc vs tcmalloc

jemalloc 与 tcmalloc 都想解决多线程分配器的老问题:锁争抢、碎片、RSS 膨胀与回收抖动。但两者把优化重点放在了不同位置:tcmalloc 更激进地把热路径推到 per-CPU,jemalloc 则把 arena、extent、decay 和 profiling 做成了一套更完整的内存治理工具箱。


By .