Search code examples
clinuxinotify

inotify missing events


I want to monitor USB-Keys on my system. I know they are always mounted in /media so I use inotify to monitor /media. Some USB Keys create a folder (e.g. sda) when plugged which stays until they are unplugged, some create a folder (e.g. sda), delete it imediately and create a new one (e.g. sda1). That's due to the partitions on the key.

However, sometimes inotify catches only the events for creation and deletion of the first folder, but misses the creation of the second. When I manually check /media, the second folder exists, but it was never notified by inotify.

This happens very rarely and when it happens, it's always at the first plug of a device after reboot.

#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;

        }

    }

}

Any ideas what's going wrong?


Solution

  • In the meanwhile I found that this is a known issue of inotify. If two events appear virtually at the same time, inotify only catches one of them. My solution: I don't use inotify anymore, but took libudev instead to monitor the devices plugged to the machine...