7eRoM
7eRoM

Reputation: 453

fanotify - problem with new flags introduced in Kernel 5.1

Since Kernel 5.1, new flags FAN_ATTRIB, FAN_CREATE, FAN_DELETE, FAN_DELETE_SELF, FAN_MOVED_FROM, FAN_MOVED_TO and FAN_MOVE_SELF are introduced. Unfortunately, when I use them in function fanotify_mark() I get this error:

fanotify_mark: Invalid argument

But when I use the old flags like FAN_ACCESS, FAN_OPEN and FAN_CLOSE_WRITE, everything works fine.

I don`t know that is my fault or a bug in fanotify's implementation.

Here is my code:

#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] = '\0';
            printf("%s\n", path);

            close(metadata->fd);
            metadata = FAN_EVENT_NEXT(metadata, buflen);
        }
    }
}

The code is running on Ubuntu Server 19.10 (GNU/Linux 5.3.0-23-generic x86_64) by a root user.

Upvotes: 3

Views: 1103

Answers (1)

Josh Jameson
Josh Jameson

Reputation: 80

You are using the code from fanotify_example.c

This example does not include the new features from kernel 5.1, which rely on the FAN_REPORT_FID flag.

Try using the example "fanotify_fid.c" provided in the latest manpage for fanotify.

Upvotes: 6

Related Questions