View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0008450 | Rocky-Linux-9 | General | public | 2024-12-03 06:21 | 2024-12-05 23:42 |
| Reporter | Ryan Plaster | Assigned To | |||
| Priority | normal | Severity | minor | Reproducibility | always |
| Status | new | Resolution | open | ||
| Platform | Linux | OS | Rocky | OS Version | 9 |
| Summary | 0008450: FANotify FAN_ATTRIB event error | ||||
| Description | When watching for FAN_ATTRIB events on the 5.14.0-503.15.1 kernel, an endless loop of FAN_ATTRIB events are reported. This did not occur on the previous kernel release (5.14.0-427.13.1) . I am not sure how else to test this as far as I am aware fanotify is provided with the kernel. | ||||
| Steps To Reproduce | Watch an XFS filesystem for FAN_ATTRIB events. I attached a test program that can be compiled in C to monitor a filesystem. I tested this on the previous kernel and on the latest Ubuntu release and it works as expected, but on the latest kernel the FAN_ATTRIB event continuously reports. | ||||
| Additional Information | Example output after a file is moved into the watched filesystem. I had to kill the program since it continuously output the FAN_ATTRIB log. Kernel: 5.14.0-427.13.1 $ sudo ./fanotify_monitor Listening for events on /test1. Event info_type: 2 Directory: "/test1" FAN_CREATE "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_CLOSE_WRITE "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Kernel 5.14.0-503.15.1: $ sudo ./fanotify_monitor Listening for events on /test1. Event info_type: 2 Directory: "/test1" FAN_CREATE "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Directory: "/test1" FAN_CLOSE_WRITE "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) Event info_type: 2 Directory: "/test1" FAN_ATTRIB "testfile_001" (file) ^C | ||||
| Tags | kernel | ||||
| Attached Files | FANotify_test_program.txt (4,434 bytes)
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fanotify.h>
#include <unistd.h>
#define BUF_SIZE 256
int main() {
int fd, ret, event_fd, mount_fd;
ssize_t len, path_len;
char path[PATH_MAX];
char procfd_path[PATH_MAX];
char events_buf[BUF_SIZE];
struct file_handle *file_handle;
struct fanotify_event_metadata *metadata;
struct fanotify_event_info_fid *fid;
const char *file_name;
struct stat sb;
const char *monitor_dir = "/test1";
mount_fd = open(monitor_dir, O_DIRECTORY | O_RDONLY);
if (mount_fd == -1) {
perror(monitor_dir);
exit(EXIT_FAILURE);
}
fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME, O_CLOEXEC | O_NONBLOCK);
if (fd == -1) {
perror("fanotify_init");
exit(EXIT_FAILURE);
}
ret = fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_FILESYSTEM,
FAN_CREATE | FAN_ATTRIB | FAN_DELETE | FAN_MOVE | FAN_CLOSE_WRITE | FAN_ONDIR,
AT_FDCWD, monitor_dir);
if (ret == -1) {
perror("fanotify_mark");
exit(EXIT_FAILURE);
}
printf("Listening for events on %s.\n", monitor_dir);
while (1) {
len = read(fd, events_buf, sizeof(events_buf));
if (len == -1) {
if (errno == EAGAIN) continue;
perror("read");
exit(EXIT_FAILURE);
}
for (metadata = (struct fanotify_event_metadata *) events_buf;
FAN_EVENT_OK(metadata, len);
metadata = FAN_EVENT_NEXT(metadata, len)) {
fid = (struct fanotify_event_info_fid *) (metadata + 1);
// Print the info_type for debugging
printf("Event info_type: %d\n", fid->hdr.info_type);
file_handle = (struct file_handle *) fid->handle;
file_name = NULL;
if (fid->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID_NAME) {
file_name = file_handle->f_handle + file_handle->handle_bytes;
} else {
continue;
}
event_fd = open_by_handle_at(mount_fd, file_handle, O_RDONLY);
if (event_fd == -1) {
if (errno == ESTALE) {
printf("File handle is no longer valid. File has been deleted\n");
continue;
} else {
perror("open_by_handle_at");
exit(EXIT_FAILURE);
}
}
snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d", event_fd);
path_len = readlink(procfd_path, path, sizeof(path) - 1);
if (path_len == -1) {
perror("readlink");
exit(EXIT_FAILURE);
}
path[path_len] = '\0';
// Determine if it's a directory or file event based on FAN_ONDIR
const char *entry_type = (metadata->mask & FAN_ONDIR) ? "(directory)" : "(file)";
// Print event type with directory and file name in the specified format
if (metadata->mask & FAN_CREATE) {
printf("Directory: \"%s\" FAN_CREATE \"%s\" %s\n", path, file_name, entry_type);
}
if (metadata->mask & FAN_ATTRIB) {
printf("Directory: \"%s\" FAN_ATTRIB \"%s\" %s\n", path, file_name, entry_type);
}
if (metadata->mask & FAN_DELETE) {
printf("Directory: \"%s\" FAN_DELETE \"%s\" %s\n", path, file_name, entry_type);
}
if (metadata->mask & FAN_CLOSE_WRITE) {
printf("Directory: \"%s\" FAN_CLOSE_WRITE \"%s\" %s\n", path, file_name, entry_type);
}
if (metadata->mask & FAN_MOVE) {
if (metadata->mask & FAN_MOVED_FROM) {
printf("Directory: \"%s\" FAN_MOVED_FROM \"%s\" %s\n", path, file_name, entry_type);
} else if (metadata->mask & FAN_MOVED_TO) {
printf("Directory: \"%s\" FAN_MOVED_TO \"%s\" %s\n", path, file_name, entry_type);
}
}
close(event_fd);
}
}
close(fd);
close(mount_fd);
return EXIT_SUCCESS;
} | ||||
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2024-12-03 06:21 | Ryan Plaster | New Issue | |
| 2024-12-03 06:21 | Ryan Plaster | Tag Attached: kernel | |
| 2024-12-03 06:21 | Ryan Plaster | File Added: FANotify_test_program.txt | |
| 2024-12-05 23:42 | Ryan Plaster | Note Added: 0009026 |