首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >打开文件导致系统在处理fanotify事件时挂起

打开文件导致系统在处理fanotify事件时挂起
EN

Stack Overflow用户
提问于 2016-04-18 16:06:08
回答 2查看 419关注 0票数 0

我是个新手。

在处理文件打开和关闭事件时,我使用fanotify手册页的example将任何信息写入文件。对'fopen‘的系统调用导致系统挂起。当我将'FAN_OPEN_PERM‘改为'FAN_OPEN’时,一切正常,但‘FAN_OPEN_PERM’标志不允许记录到文件中。

是不是我在使用fanotify技术时遗漏了什么。或者在处理fanotify时存在任何限制?

或者有什么更好的办法在处理fanotify事件的同时记录一个文件?

我已经在'Ubuntu 14.04.3 64bit‘和'3.16.0-70-generic’内核版本下编译和测试过了。

我添加了一些如下代码:

代码语言:javascript
复制
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‘函数中

代码语言:javascript
复制
{
    char strBuf[PATH_MAX];
    sprintf(strBuf, "File %s\n", path);
    PrintToFile(strBuf);
}

请参阅修改后的'handle_events‘函数

代码语言:javascript
复制
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);
           }
       }
   }
EN

回答 2

Stack Overflow用户

发布于 2016-07-08 17:24:30

不确定,但在“文件打开”监视器处理程序中打开文件可能会导致无限循环。尝试在调用PrintToFile的代码块前添加:if (metadata->pid != getpid()),以忽略打印事件导致的打印,而不是您的程序本身。

票数 1
EN

Stack Overflow用户

发布于 2021-04-06 03:25:39

FAN_OPEN_PERM标志请求您响应是否允许打开文件或拒绝,并阻止事件,直到您回答内核应该如何处理该文件

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36688473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档