c - 通知丢失的事件

标签 c linux inotify

我想监控系统上的 USB key 。我知道它们总是安装在/media 中,所以我使用 inotify 来监视/media。一些 USB key 在插入时会创建一个文件夹(例如 sda),该文件夹会一直保留到拔出,有些会创建一个文件夹(例如 sda),然后立即将其删除并创建一个新文件夹(例如 sda1)。这是由于 key 上的分区。

然而,有时 inotify 只捕获第一个文件夹的创建和删除事件,而错过第二个文件夹的创建。当我手动检查/media 时,第二个文件夹存在,但 inotify 从未通知它。

这种情况很少发生,即使发生,也总是在重启后第一次插入设备时发生。

#include <sys/inotify.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

/* size of the event structure, not counting name */
#define EVENT_SIZE  (sizeof (struct inotify_event))

/* reasonable guess as to size of 32 events */
#define BUF_LEN        (32 * (EVENT_SIZE + 16))

int main(int argc, char **argv) {
    int fd,wd,len,i;
    char buf[BUF_LEN];
    struct inotify_event *event;
    fd_set watch_set;

    fd = inotify_init();
    if (fd < 0) {
        perror("init failed");
        exit(EXIT_FAILURE);
    }

    wd = inotify_add_watch(fd,"/media",IN_ALL_EVENTS);
    if (wd < 0) {
        perror("add watch failed");
        exit(EXIT_FAILURE);
    }

    /* put the file descriptor to the watch list for select() */
    FD_ZERO(&watch_set);
    FD_SET(fd,&watch_set);

    while(1) {
        select(fd+1,&watch_set,NULL,NULL,NULL);
        len = read(fd,buf,BUF_LEN);
        i=0;
        while(i < len) {

            event = (struct inotify_event *) &buf[i];

            if ((event->mask & IN_CREATE) != 0) {
                printf ("%s created\n",event->name);
            }
            else if ((event->mask & IN_DELETE) != 0) {
                printf ("%s deleted\n",event->name);
            }
            else {
                printf ("wd=%d mask=0x%X cookie=%u len=%u name=%s\n",
                                event->wd, event->mask,
                                event->cookie, event->len, event->name);
            }

            i += EVENT_SIZE + event->len;

        }

    }

}

知道出了什么问题吗?

最佳答案

inotify 的子文件夹问题众所周知并且很容易重现:

  1. 启动 inotifywait 观察一个空的 tmp 目录:

    inotifywait -e create -m -r --format '%:e %f' ./tmp

  2. 在另一个shell中输入:

    mkdir tmp/0 tmp/0/0 tmp/0/0/0 tmp/0/0/0/0

  3. 您很可能只会收到第一个子目录的通知。

    创建:ISDIR 0

在创建目录、您的应用程序收到通知和添加新的 inotify 监视之间丢失事件(尤其是子目录创建事件)的明显可能性使得递归监控太不可靠。唯一安全的选择是扫描新创建目录的内容。

来自inotify doc限制和注意事项下:

If monitoring an entire directory subtree, and a new subdirectory is created in that tree, be aware that by the time you create a watch for the new subdirectory, new files may already have been created in the subdirectory. Therefore, you may want to scan the contents of the subdirectory immediately after adding the watch.

关于c - 通知丢失的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15806488/

相关文章:

python - 如何使用 inotify Linux 内核子系统为 python 中的新文件创建创建最简单的目录观察器?

c - 如何缩短这个?有办法吗?

c - 为什么将 void 指针转换为 char 指针在这种情况下不起作用

c - 如何正确指向C中的结构体成员?

Python 脚本在一段时间后停止

linux - 面对不同步的时钟,inotify 是否有效?

c - 如何将汇编代码关联到 C 程序中的确切行?

linux - 有多少行包含字符串 “int” 而不包含 "integer".h 文件?

linux - 如何在 64 位 Linux red hat 6.2 服务器上安装 32 位软件包

linux - 在多线程程序中为 Inotify 添加 watch