能否用fanotify监控Linux整个文件系统的文件创建事件?
问题:使用fanotify监控Ubuntu系统全文件系统的文件创建事件
我需要在Ubuntu系统中用fanotify库监控整个文件系统的文件创建事件,要求能轮询事件并获取新创建文件的完整路径。
尝试的配置及结果
配置1:监控根目录(/)
fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME, O_RDONLY | O_LARGEFILE); fanotify_mark(fd, FAN_MARK_FILESYSTEM | FAN_MARK_ADD, FAN_CREATE, AT_FDCWD, "/");
- 效果:无效,仅能捕获
/test.file的创建事件,无法监控/home/test.file这类非根目录下的文件。
配置2:监控/home目录
fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME, O_RDONLY | O_LARGEFILE); fanotify_mark(fd, FAN_MARK_FILESYSTEM | FAN_MARK_ADD, FAN_CREATE, AT_FDCWD, "/home");
- 效果:有效,但仅能监控
/home/下的文件创建事件,范围有限。
配置3:尝试使用FAN_MARK_MOUNT
fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME, O_RDONLY | O_LARGEFILE); fanotify_mark(fd, FAN_MARK_MOUNT | FAN_MARK_ADD, FAN_CREATE, AT_FDCWD, "/");
- 效果:报错,
FAN_MARK_MOUNT与FAN_CREATE不兼容。
解决方案:遍历所有挂载点逐个监控
问题核心:FAN_MARK_FILESYSTEM仅监控指定路径所属的单个文件系统,而/home通常是独立挂载的文件系统,因此根目录的监控无法覆盖它;FAN_MARK_MOUNT仅支持挂载/卸载这类挂载点级事件,不兼容文件创建事件。
要实现全文件系统监控,需按以下步骤操作:
- 读取
/proc/mounts获取系统所有已挂载文件系统的挂载点路径 - 对每个挂载点,调用
fanotify_mark添加FAN_CREATE事件监控
示例代码片段
// 读取/proc/mounts获取所有挂载点 FILE *mounts = fopen("/proc/mounts", "r"); char line[256], dev[64], path[128], fs[64], opts[128]; int freq, pass; while (fscanf(mounts, "%s %s %s %s %d %d", dev, path, fs, opts, &freq, &pass) != EOF) { // 跳过无需监控的虚拟文件系统(可根据需求调整) if (strcmp(fs, "proc") == 0 || strcmp(fs, "sysfs") == 0 || strcmp(fs, "tmpfs") == 0) { continue; } // 为每个挂载点添加文件创建事件监控 if (fanotify_mark(fd, FAN_MARK_FILESYSTEM | FAN_MARK_ADD, FAN_CREATE, AT_FDCWD, path) == -1) { perror("fanotify_mark failed for path"); } } fclose(mounts);
关键注意事项
- 程序必须以root权限运行,fanotify需要特权才能监控系统级事件
- 处理事件时,通过
struct fanotify_event_metadata获取事件信息,结合FAN_REPORT_DFID_NAME拿到的文件名,与挂载点路径拼接即可得到完整文件路径 - 若需监控动态挂载的设备(如U盘),需额外监听挂载事件(用
FAN_MARK_MOUNT配合FAN_MOUNT事件),并在挂载完成后自动为新挂载点添加监控
内容的提问来源于stack exchange,提问作者Jeffrey W.
相关产品推荐
相关产品推荐

