我想在我的系统上监控USB密钥。我知道它们总是安装在/ media中,因此我使用inotify监视/媒体。一些USB密钥在插入时创建一个文件夹(例如sda),直到它们被拔出,一些创建一个文件夹(例如sda),立即删除它并创建一个新文件夹(例如sda1)。这是由于密钥上的分区。
但是,有时inotify仅捕获用于创建和删除第一个文件夹的事件,但是错过了第二个文件夹的创建。当我手动检查/媒体时,第二个文件夹存在,但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;
}
}
}
任何想法出了什么问题?
答案 0 :(得分:4)
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 :
如果监视整个目录子树,并且是一个新的子目录 在该树中创建,请注意,当您为其创建手表时 在新的子目录中,可能已经在新的文件中创建了新文件 子目录。因此,您可能想要扫描内容 添加手表后立即进行子目录。
答案 1 :(得分:1)
您可以使用inotifywait
命令(来自inotify-tools
包)来监控 / media 目录,以检查inotify
是否inotify
你感兴趣的事件
参考:
http://www.noah.org/wiki/Inotify,_FAM,_Gamin#Examples_with_inotify-tools
如果Inotify
确实错过了活动,原因可能是:
sysfs
会报告procfs
和{{1}}中的部分但非全部事件
(好吧,我不能肯定地说。只是我的猜测。)
参考:
http://en.wikipedia.org/wiki/Inotify#Limitations
http://en.wikipedia.org/wiki/Sysfs
http://en.wikipedia.org/wiki/Procfs
答案 2 :(得分:0)
同时我发现这是一个已知的inotify问题。如果两个事件几乎同时出现,则inotify仅捕获其中一个事件。 我的解决方案:我不再使用inotify,而是使用libudev来监控插入机器的设备......