我是个新手。
在处理文件打开和关闭事件时,我使用fanotify手册页的example将任何信息写入文件。对'fopen‘的系统调用导致系统挂起。当我将'FAN_OPEN_PERM‘改为'FAN_OPEN’时,一切正常,但‘FAN_OPEN_PERM’标志不允许记录到文件中。
是不是我在使用fanotify技术时遗漏了什么。或者在处理fanotify时存在任何限制?
或者有什么更好的办法在处理fanotify事件的同时记录一个文件?
我已经在'Ubuntu 14.04.3 64bit‘和'3.16.0-70-generic’内核版本下编译和测试过了。
我添加了一些如下代码:
static void PrintToFile(const char *pszMsg)
{
int err = 0;
if( NULL == pszMsg) {
printf("invalid message\n");
return ;
}
FILE *fp = fopen("/tmp/fanotify.log", "a+"); // <= here, system hangs
if( NULL == fp ) {
err = errno;
printf("file open fail ( %d ) \n", err);
return ;
}
size_t len = strlen(pszMsg);
feesk(fp, 0L, SEEK_END );
fwrite(pszMsg, 1, len, fp);
fclose(fp);
}然后,我将下一段代码添加到'handle_events‘函数中
{
char strBuf[PATH_MAX];
sprintf(strBuf, "File %s\n", path);
PrintToFile(strBuf);
}请参阅修改后的'handle_events‘函数
static void
handle_events(int fd)
{
const struct fanotify_event_metadata *metadata;
struct fanotify_event_metadata buf[200];
ssize_t len;
char path[PATH_MAX];
ssize_t path_len;
char procfd_path[PATH_MAX];
struct fanotify_response response;
/* Loop while events can be read from fanotify file descriptor */
for(;;) {
/* Read some events */
len = read(fd, (void *) &buf, sizeof(buf));
if (len == -1 && errno != EAGAIN) {
perror("read");
exit(EXIT_FAILURE);
}
/* Check if end of available data reached */
if (len <= 0)
break;
/* Point to the first event in the buffer */
metadata = buf;
/* Loop over all events in the buffer */
while (FAN_EVENT_OK(metadata, len)) {
/* Check that run-time and compile-time structures match */
if (metadata->vers != FANOTIFY_METADATA_VERSION) {
fprintf(stderr,
"Mismatch of fanotify metadata version.\n");
exit(EXIT_FAILURE);
}
/* metadata->fd contains either FAN_NOFD, indicating a
queue overflow, or a file descriptor (a nonnegative
integer). Here, we simply ignore queue overflow. */
if (metadata->fd >= 0) {
/* Handle open permission event */
if (metadata->mask & FAN_OPEN_PERM) {
printf("FAN_OPEN_PERM: ");
/* Allow file to be opened */
response.fd = metadata->fd;
response.response = FAN_ALLOW;
write(fd, &response,
sizeof(struct fanotify_response));
}
/* Handle closing of writable file event */
if (metadata->mask & FAN_CLOSE_WRITE)
printf("FAN_CLOSE_WRITE: ");
/* Retrieve and print pathname of the accessed file */
snprintf(procfd_path, sizeof(procfd_path),
"/proc/self/fd/%d", metadata->fd);
path_len = readlink(procfd_path, path,
sizeof(path) - 1);
if (path_len == -1) {
perror("readlink");
exit(EXIT_FAILURE);
}
path[path_len] = '\0';
printf("File %s\n", path);
//these code snipptets are added
{
char strBuf[PATH_MAX];
sprintf(strBuf, "File %s\n", path);
PrintToFile(strBuf);
}
/* Close the file descriptor of the event */
close(metadata->fd);
}
/* Advance to next event */
metadata = FAN_EVENT_NEXT(metadata, len);
}
}
}发布于 2016-07-08 17:24:30
不确定,但在“文件打开”监视器处理程序中打开文件可能会导致无限循环。尝试在调用PrintToFile的代码块前添加:if (metadata->pid != getpid()),以忽略打印事件导致的打印,而不是您的程序本身。
发布于 2021-04-06 03:25:39
FAN_OPEN_PERM标志请求您响应是否允许打开文件或拒绝,并阻止事件,直到您回答内核应该如何处理该文件
https://stackoverflow.com/questions/36688473
复制相似问题