fanotify - 内核 5.1 中引入的新标志的问题
fanotify - problem with new flags introduced in Kernel 5.1
从内核 5.1 开始,新标志 FAN_ATTRIB
、FAN_CREATE
、FAN_DELETE
、FAN_DELETE_SELF
、FAN_MOVED_FROM
、FAN_MOVED_TO
和 FAN_MOVE_SELF
进行了介绍。不幸的是,当我在函数 fanotify_mark()
中使用它们时,出现此错误:
fanotify_mark: Invalid argument
但是当我使用像 FAN_ACCESS
、FAN_OPEN
和 FAN_CLOSE_WRITE
这样的旧标志时,一切正常。
我不知道这是我的错还是 fanotify 实现中的错误。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/fanotify.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int fan;
char buf[4096];
char fdpath[32];
char path[PATH_MAX + 1];
ssize_t buflen, linklen;
struct fanotify_event_metadata *metadata;
// Init fanotify structure
fan = fanotify_init(FAN_CLASS_NOTIF, O_RDWR);
if(fan == -1)
{
perror("fanotify_init");
exit(EXIT_FAILURE);
}
int ret = fanotify_mark(fan,
FAN_MARK_ADD,
FAN_CREATE | FAN_EVENT_ON_CHILD,
//FAN_ACCESS | FAN_OPEN | FAN_EVENT_ON_CHILD,
AT_FDCWD,
"/tmp/myfolder"
);
if(ret == -1)
{
perror("fanotify_mark");
exit(EXIT_FAILURE);
}
while(1)
{
buflen = read(fan, buf, sizeof(buf));
metadata = (struct fanotify_event_metadata*)&buf;
while(FAN_EVENT_OK(metadata, buflen))
{
if (metadata->mask & FAN_Q_OVERFLOW)
{
printf("Queue overflow!\n");
continue;
}
// Resolve path, using automatically opened fd
sprintf(fdpath, "/proc/self/fd/%d", metadata->fd);
linklen = readlink(fdpath, path, sizeof(path) - 1);
path[linklen] = '[=10=]';
printf("%s\n", path);
close(metadata->fd);
metadata = FAN_EVENT_NEXT(metadata, buflen);
}
}
}
root 用户在 Ubuntu 服务器 19.10(GNU/Linux 5.3.0-23-generic x86_64)上 运行 代码。
您正在使用来自 fanotify_example.c
的代码
此示例不包括内核 5.1 中依赖于 FAN_REPORT_FID 标志的新功能。
尝试使用 fanotify 的最新联机帮助页中提供的示例 "fanotify_fid.c"。
从内核 5.1 开始,新标志 FAN_ATTRIB
、FAN_CREATE
、FAN_DELETE
、FAN_DELETE_SELF
、FAN_MOVED_FROM
、FAN_MOVED_TO
和 FAN_MOVE_SELF
进行了介绍。不幸的是,当我在函数 fanotify_mark()
中使用它们时,出现此错误:
fanotify_mark: Invalid argument
但是当我使用像 FAN_ACCESS
、FAN_OPEN
和 FAN_CLOSE_WRITE
这样的旧标志时,一切正常。
我不知道这是我的错还是 fanotify 实现中的错误。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/fanotify.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int fan;
char buf[4096];
char fdpath[32];
char path[PATH_MAX + 1];
ssize_t buflen, linklen;
struct fanotify_event_metadata *metadata;
// Init fanotify structure
fan = fanotify_init(FAN_CLASS_NOTIF, O_RDWR);
if(fan == -1)
{
perror("fanotify_init");
exit(EXIT_FAILURE);
}
int ret = fanotify_mark(fan,
FAN_MARK_ADD,
FAN_CREATE | FAN_EVENT_ON_CHILD,
//FAN_ACCESS | FAN_OPEN | FAN_EVENT_ON_CHILD,
AT_FDCWD,
"/tmp/myfolder"
);
if(ret == -1)
{
perror("fanotify_mark");
exit(EXIT_FAILURE);
}
while(1)
{
buflen = read(fan, buf, sizeof(buf));
metadata = (struct fanotify_event_metadata*)&buf;
while(FAN_EVENT_OK(metadata, buflen))
{
if (metadata->mask & FAN_Q_OVERFLOW)
{
printf("Queue overflow!\n");
continue;
}
// Resolve path, using automatically opened fd
sprintf(fdpath, "/proc/self/fd/%d", metadata->fd);
linklen = readlink(fdpath, path, sizeof(path) - 1);
path[linklen] = '[=10=]';
printf("%s\n", path);
close(metadata->fd);
metadata = FAN_EVENT_NEXT(metadata, buflen);
}
}
}
root 用户在 Ubuntu 服务器 19.10(GNU/Linux 5.3.0-23-generic x86_64)上 运行 代码。
您正在使用来自 fanotify_example.c
的代码此示例不包括内核 5.1 中依赖于 FAN_REPORT_FID 标志的新功能。
尝试使用 fanotify 的最新联机帮助页中提供的示例 "fanotify_fid.c"。