我想监控系统上的 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 的子文件夹问题众所周知并且很容易重现:
启动 inotifywait 观察一个空的 tmp 目录:
inotifywait -e create -m -r --format '%:e %f' ./tmp
在另一个shell中输入:
mkdir tmp/0 tmp/0/0 tmp/0/0/0 tmp/0/0/0/0
您很可能只会收到第一个子目录的通知。
创建: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/