Сообщать о пропущенных событиях

Я хочу контролировать USB-ключи в моей системе. Я знаю, что они всегда монтируются в /media, поэтому я использую inotify для мониторинга /media. Некоторые USB-ключи при подключении создают папку (например, sda), которая остается до тех пор, пока они не будут отключены, некоторые создают папку (например, sda), немедленно ее удаляют и создают новую (например, sda1). Это связано с разделами на ключе.

Однако иногда 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;

        }

    }

}

Есть идеи, что не так?

3 ответа

Решение

Тем временем я обнаружил, что это известная проблема inotify. Если два события появляются практически одновременно, inotify ловит только одно из них. Мое решение: я больше не использую inotify, но вместо этого взял libudev для мониторинга устройств, подключенных к машине...

Проблема подпапок с inotify хорошо известна и легко воспроизводится:

  1. Запустите inotifywait, просматривая пустой каталог tmp:

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

  2. В другой оболочке введите:

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

  3. Скорее всего, вы получите уведомление только для первого подкаталога.

    СОЗДАТЬ: ИСДИР 0

Возможность потери событий (особенно событий создания подкаталога) между временем создания каталога, уведомлением вашего приложения и добавлением новых средств наблюдения inotify делает рекурсивный мониторинг слишком ненадежным. Единственным безопасным вариантом является сканирование содержимого вновь созданных каталогов.

Из документа inotify в разделе Ограничения и предостережения:

Если вы отслеживаете целое поддерево каталога, и в этом дереве создается новый подкаталог, имейте в виду, что к тому времени, когда вы создаете наблюдение для нового подкаталога, в этом подкаталоге уже могут быть созданы новые файлы. Поэтому вы можете захотеть сканировать содержимое подкаталога сразу после добавления часов.

  1. Ты можешь использовать inotifywait команда (из inotify-tools пакет) для мониторинга каталога / media, чтобы проверить, inotify события, которые вас интересуют, происходят.
    ссылка:
    http://www.noah.org/wiki/Inotify,_FAM,_Gamin

  2. Если inotify пропускает события, причина может быть:
    Inotify сообщает о некоторых, но не обо всех событиях в sysfs а также procfs,
    (Ну, я не могу сказать наверняка. Просто мое предположение.)

Ссылка:
http://en.wikipedia.org/wiki/Inotify
http://en.wikipedia.org/wiki/Sysfs
http://en.wikipedia.org/wiki/Procfs

Другие вопросы по тегам