inotify événements manquants

Je souhaite surveiller les clés USB sur mon système. Je sais qu’ils sont toujours montés dans / media, j’utilise donc inotify pour surveiller / media. Certaines clés USB créent un dossier (p.ex. sda) une fois branché, jusqu’à ce qu’elles soient débranchées, d’autres créent un dossier (p.ex. sda), le suppriment immédiatement et en créent un nouveau (p.ex. sda1). Cela est dû aux partitions sur la clé.

Cependant, parfois inotify intercepte uniquement les événements pour la création et la suppression du premier dossier, mais manque la création du second. Lorsque je vérifie / media manuellement, le deuxième dossier existe, mais il n’a jamais été notifié par inotify.

Cela arrive très rarement et quand cela arrive, c’est toujours à la première prise d’un périphérique après le redémarrage.

#include  #include  #include  #include  #include  /* 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 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; } } } 

Des idées sur ce qui ne va pas?

Le problème de sous-dossier avec inotify est bien connu et facilement reproduit:

  1. Commencez inotifywait en regardant un répertoire tmp vide:

    inotifywait -e crée -m -r –format ‘%: e% f’ ./tmp

  2. Dans une autre coquille, entrez:

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

  3. Vous ne recevrez probablement qu’une notification pour le premier sous-répertoire.

    CRÉER: ISDIR 0

La possibilité distincte de perdre des événements (en particulier des événements de création de sous-répertoires) entre le moment où un répertoire est créé, votre application est notifiée et une nouvelle surveillance inotify est ajoutée, rend la surveillance récursive trop peu fiable. La seule option sûre consiste à parsingr le contenu des répertoires nouvellement créés.

De la doc inotify sous Limitations et mises en garde :

Si vous surveillez tout un sous-répertoire et qu’un nouveau sous-répertoire est créé dans cette arborescence, sachez qu’au moment où vous créez une surveillance pour le nouveau sous-répertoire, de nouveaux fichiers ont peut-être déjà été créés dans le sous-répertoire. Par conséquent, vous souhaiterez peut-être parsingr le contenu du sous-répertoire immédiatement après avoir ajouté la montre.

  1. Vous pouvez utiliser la commande inotifywait (du paquet inotify-tools ) pour surveiller le répertoire / media , afin de vérifier si les événements inotify qui vous intéressent se produisent.
    référence:
    http://www.noah.org/wiki/Inotify,_FAM,_Gamin#Examples_with_inotify-tools

  2. Si inotify manque des événements, la raison peut être:
    Inotify signale certains événements mais pas tous dans sysfs et procfs .
    (Eh bien, je ne peux pas dire avec certitude. Juste ma supposition.)

Référence:
http://en.wikipedia.org/wiki/Inotify#Limitations
http://en.wikipedia.org/wiki/Sysfs
http://en.wikipedia.org/wiki/Procfs

En attendant, j’ai trouvé que c’était un problème connu d’inotify. Si deux événements apparaissent pratiquement simultanément, inotify n’en capture qu’un. Ma solution: je n’utilise plus inotify, mais j’ai pris libudev pour surveiller les périphériques connectés à la machine …