Re: [PATCH v3] fanotify.7, fanotify_init.2, fanotify_mark.2: Document FAN_REPORT_FID and directory modification events

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Michael,

On Sat, Jun 08, 2019 at 01:58:00PM +0200, Michael Kerrisk (man-pages) wrote:
> Thanks for the excellent patch! I've already applied it, and made a
> few light edits

Thank you for the review! :-)
 
> I have a few comments and questions below.

Sure. Inline responses provided below.

> On 6/6/19 11:48 AM, Matthew Bobrowski wrote:
> > Details relating to the new initialization flag FAN_REPORT_FID has been
> > added. As part of the FAN_REPORT_FID feature, a new set of event masks are
> > available and have been documented accordingly.
> > 
> > A simple example program has been added to also support the understanding
> > and use of FAN_REPORT_FID and directory modification events.
> > 
> > Signed-off-by: Matthew Bobrowski <mbobrowski@xxxxxxxxxxxxxx>
> > Reviewed-by: Amir Goldstein <amir73il@xxxxxxxxx>
> > Reviewed-by: Jan Kara <jack@xxxxxxx>
> > ---
> > 
> > Changes since version 2:
> > 	* A minor addition to both fanotify_init.2 and fanotify_mark.2
> > 	  highlighting that directory modification events are not permitted
> > 	  when also using FAN_MARK_MOUNT. It wasn't immediately obvious to the
> > 	  reader before this update.
> > 
> > 
> >   man2/fanotify_init.2 |  36 ++++-
> >   man2/fanotify_mark.2 |  96 ++++++++++++-
> >   man7/fanotify.7      | 331 +++++++++++++++++++++++++++++++++++++++++--
> >   3 files changed, 448 insertions(+), 15 deletions(-)
> > 
> > diff --git a/man2/fanotify_init.2 b/man2/fanotify_init.2
> > index 9be15be51..ece4ae6a6 100644
> > --- a/man2/fanotify_init.2
> > +++ b/man2/fanotify_init.2
> > @@ -40,8 +40,8 @@ queue associated with the group.
> >   .PP
> >   The file descriptor is used in calls to
> >   .BR fanotify_mark (2)
> > -to specify the files, directories, and mounts for which fanotify events
> > -shall be created.
> > +to specify the files, directories, mounts or filesystems for which fanotify
> > +events shall be created.
> >   These events are received by reading from the file descriptor.
> >   Some events are only informative, indicating that a file has been accessed.
> >   Other events can be used to determine whether
> > @@ -94,6 +94,36 @@ already contain their final content.
> >   This notification class might be used by malware detection programs, for
> >   example.
> >   .TP
> > +.BR FAN_REPORT_FID " (since Linux 5.1)"
> > +.\" commit a8b13aa20afb69161b5123b4f1acc7ea0a03d360
> > +This value allows the receipt of events which contain additional information
> > +about the underlying object correlated to an event.
> 
> In a few places, I changed "object" to "filesystem object", just to
> reduce the chance of ambiguity a little.

Good thought. This does read better.
 
> > +An additional structure encapsulates the information about the object and is
> > +included alongside the generic event metadata structure.
> > +The file descriptor that is used to represent the object correlated to an
> > +event is instead substituted with a file handle.
> > +It is intended for applications that may find the use of a file handle to
> > +identify an object more suitable than a file descriptor.
> > +Additionally, it may be used for applications that are interested in
> > +directory entry events, such as
> > +.BR FAN_CREATE ,
> > +.BR FAN_ATTRIB ,
> > +.BR FAN_MOVE
> > +and
> > +.BR FAN_DELETE
> > +for example.
> > +Note that the use of directory modification events are not supported when
> > +monitoring a mount point.
> > +The use of
> > +.BR FAN_CLASS_CONTENT
> > +or
> > +.BR FAN_CLASS_PRE_CONTENT
> > +is not permitted with this flag and will result in the error
> > +.BR EINVAL .
> > +See
> > +.BR fanotify (7)
> > +for additional information.
> > +.TP
> >   .B FAN_CLASS_NOTIF
> >   This is the default value.
> >   It does not need to be specified.
> > @@ -224,6 +254,8 @@ An invalid value was passed in
> >   or
> >   .IR event_f_flags .
> >   .B FAN_ALL_INIT_FLAGS
> > +(deprecated since Linux kernel version 4.20)
> > +.\" commit 23c9deeb3285d34fd243abb3d6b9f07db60c3cf4
> >   defines all allowable bits for
> >   .IR flags .
> >   .TP
> > diff --git a/man2/fanotify_mark.2 b/man2/fanotify_mark.2
> > index 3c6e9565a..ce7aa9804 100644
> > --- a/man2/fanotify_mark.2
> > +++ b/man2/fanotify_mark.2
> > @@ -126,6 +126,15 @@ is not itself a mount point, the mount point containing
> >   will be marked.
> >   All directories, subdirectories, and the contained files of the mount point
> >   will be monitored.
> > +This value cannot be used if the
> > +.I fanotify_fd
> > +file descriptor has been initialized with the flag
> > +.BR FAN_REPORT_FID
> > +or if any of the new directory modification events are provided as a
> > +.IR mask .
> > +Attempting to do so will result in the error
> > +.B EINVAL
> > +being returned.
> >   .TP
> >   .BR FAN_MARK_FILESYSTEM " (since Linux 4.20)"
> >   .\" commit d54f4fba889b205e9cd8239182ca5d27d0ac3bc2
> > @@ -171,6 +180,28 @@ Create an event when a file or directory is opened.
> >   Create an event when a file is opened with the intent to be executed.
> >   See NOTES for additional details.
> >   .TP
> > +.B FAN_ATTRIB
> > +Create an event when the metadata for a file or directory has changed.
> > +.TP
> > +.B FAN_CREATE
> > +Create an event when a file or directory has been created in a marked
> > +parent directory.
> > +.TP
> > +.B FAN_DELETE
> > +Create an event when a file or directory has been deleted in a marked
> > +parent directory.
> > +.TP
> > +.B FAN_DELETE_SELF
> > +Create an event when a marked file or directory itself is deleted.
> > +.TP
> > +.B FAN_MOVED_FROM
> > +Create an event when a file or directory has been moved from a marked
> > +parent directory.
> > +.TP
> > +.B FAN_MOVED_TO
> > +Create an event when a file or directory has been moved to a marked parent
> > +directory.
> > +.TP
> >   .B FAN_Q_OVERFLOW
> >   Create an event when an overflow of the event queue occurs.
> >   The size of the event queue is limited to 16384 entries if
> > @@ -205,13 +236,33 @@ or
> >   is required.
> >   .TP
> >   .B FAN_ONDIR
> > -Create events for directories\(emfor example, when
> > +Create events for directories \(em for example, when
> 
> Best not to make unrelated changes in the same patch. And in fact
> according to most English style guides, an em-dash should not be
> surrounded by spaces. (I reverted this.)

Apologies about this noise. But sure, happy to revert this.
 
> >   .BR opendir (3),
> >   .BR readdir (3)
> >   (but see BUGS), and
> >   .BR closedir (3)
> >   are called.
> >   Without this flag, only events for files are created.
> > +The
> > +.BR FAN_ONDIR
> > +flag is reported in an event mask only if the
> > +.I fanotify_fd
> > +file descriptor has been initialized with the flag
> > +.BR FAN_REPORT_FID .
> > +In the context of directory entry events, such as
> > +.BR FAN_CREATE ,
> > +.BR FAN_DELETE ,
> > +.BR FAN_MOVED_FROM
> > +and
> > +.BR FAN_MOVED_TO
> > +for example, specifying the flag
> > +.BR FAN_ONDIR
> > +is required in order to create events when subdirectory entries are
> > +modified (i.e. mkdir/rmdir).
> > +Subdirectory entry modification events will never be merged with non
> > +subdirectory entry modification events.
> > +This flag is never reported individually within an event and is always
> > +supplied in conjunction with another event type.
> >   .TP
> >   .B FAN_EVENT_ON_CHILD
> >   Events for the immediate children of marked directories shall be created.
> > @@ -221,11 +272,15 @@ of marked directories.
> >   To monitor complete directory trees it is necessary to mark the relevant
> >   mount.
> >   .PP
> > -The following composed value is defined:
> > +The following composed values are defined:
> >   .TP
> >   .B FAN_CLOSE
> >   A file is closed
> >   .RB ( FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE ).
> > +.TP
> > +.B FAN_MOVE
> > +A file or directory has been moved
> > +.RB ( FAN_MOVED_FROM | FAN_MOVED_TO ).
> >   .PP
> >   The filesystem object to be marked is determined by the file descriptor
> >   .I dirfd
> > @@ -297,6 +352,8 @@ was not an fanotify file descriptor.
> >   .B EINVAL
> >   The fanotify file descriptor was opened with
> >   .B FAN_CLASS_NOTIF
> > +or
> > +.B FAN_REPORT_FID
> >   and mask contains a flag for permission events
> >   .RB ( FAN_OPEN_PERM
> >   or
> > @@ -335,6 +392,41 @@ and
> >   and
> >   .I pathname
> >   do not specify a directory.
> > +.TP
> > +.B EXDEV
> > +The object indicated by
> > +.I pathname
> > +resides within a filesystem subvolume (e.g. btrfs) which uses a different
> > +.I fsid
> > +than its root superblock.
> > +This error can only be returned when an fanotify file descriptor returned
> > +by
> > +.BR fanotify_init (2)
> > +has been created with
> > +.BR FAN_REPORT_FID .
> > +.TP
> > +.B ENODEV
> > +The object indicated by
> > +.I pathname
> > +is not associated with a filesystem that supports
> > +.I fsid
> > +(e.g. tmpfs).
> > +This error can only be returned when an fanotify file descriptor returned
> > +by
> > +.BR fanotify_init (2)
> > +has been created with
> > +.BR FAN_REPORT_FID .
> > +.TP
> > +.B EOPNOTSUPP
> > +The object indicated by
> > +.I pathname
> > +is associated with a filesystem that does not support the encoding of file
> > +handles.
> > +This error can only be returned when an fanotify file descriptor returned
> > +by
> > +.BR fanotify_init (2)
> > +has been created with
> > +.BR FAN_REPORT_FID .
> >   .SH VERSIONS
> >   .BR fanotify_mark ()
> >   was introduced in version 2.6.36 of the Linux kernel and enabled in version
> > diff --git a/man7/fanotify.7 b/man7/fanotify.7
> > index 74246063e..788f23f1d 100644
> > --- a/man7/fanotify.7
> > +++ b/man7/fanotify.7
> > @@ -112,8 +112,12 @@ events and
> >   events.
> >   Notification events are merely informative
> >   and require no action to be taken by
> > -the receiving application except for closing the file descriptor passed
> > -in the event (see below).
> > +the receiving application with the exception being that the file
> > +descriptor provided within a generic event must be closed.
> > +The closing of file descriptors for each event only applies to
> > +applications that have initialized fanotify without using
> > +.BR FAN_REPORT_FID
> > +(see below).
> >   Permission events are requests to the receiving application to decide
> >   whether permission for a file access shall be granted.
> >   For these events, the recipient must write a response which decides whether
> > @@ -138,6 +142,12 @@ until either a file event occurs or the call is interrupted by a signal
> >   (see
> >   .BR signal (7)).
> >   .PP
> > +Depending on whether
> > +.BR FAN_REPORT_FID
> > +is supplied as one of the flags when calling
> > +.BR fanotify_init (2)
> > +determines what structure(s) are returned for an event within the read
> > +buffer.
> 
> The wording here in the preceding sentence is a bit off:
> 
>      "Depending on... determines"
> 
> Can you clarify?

OK. So, if FAN_REPORT_FID is provided as a flag to fanotify_init(), then
the use of this flag influences what data structure(s) an event listener
can expect to receive for each event i.e.

- For an event listener that does _not_ make use of the FAN_REPORT_FID
  flag should expect to _only_ receive the data structure of type
  fanotify_event_metadata used to describe a single event.

However, on the other hand.

- For an event listener that _does_ make use of the FAN_REPORT_FID flag
  should expect to receive data structures of type
  fanotify_event_metadata and fanotify_event_info_fid used to describe a
  single event.

With that being said, depending on whether FAN_REPORT_FID is, or is not
specified, determines the type of data structures that an event
listener can expect to receive for a single event.

I'm happy to reword this if necessary.
 
> >   After a successful
> >   .BR read (2),
> >   the read buffer contains one or more of the following structures:
> > @@ -156,6 +166,25 @@ struct fanotify_event_metadata {
> >   .EE
> >   .in
> >   .PP
> > +In the instance that
> > +.BR FAN_REPORT_FID
> > +is supplied as one of the flags to
> > +.BR fanotify_init (2),
> > +you should also expect to receive the structure detailed below following
> > +the generic
> > +.I fanotify_event_metadata
> > +structure within the read buffer:
> > +.PP
> > +.in +4n
> > +.EX
> > +struct fanotify_event_info_fid {
> > +    struct fanotify_event_info_header hdr;
> > +    __kernel_fsid_t fsid;
> > +    unsigned char file_handle[0];
> > +};
> > +.EE
> > +.in
> > +.PP
> >   For performance reasons, it is recommended to use a large
> >   buffer size (for example, 4096 bytes),
> >   so that multiple events can be retrieved by a single
> > @@ -173,12 +202,16 @@ structure are as follows:
> >   .I event_len
> >   This is the length of the data for the current event and the offset
> >   to the next event in the buffer.
> > -In the current implementation, the value of
> > +Without
> > +.BR FAN_REPORT_FID ,
> > +the value of
> >   .I event_len
> >   is always
> >   .BR FAN_EVENT_METADATA_LEN .
> > -However, the API is designed to allow
> > -variable-length structures to be returned in the future.
> > +With
> > +.BR FAN_REPORT_FID ,
> > +.I event_len
> > +also includes the variable length file identifier.
> >   .TP
> >   .I vers
> >   This field holds a version number for the structure.
> > @@ -205,6 +238,11 @@ This is a bit mask describing the event (see below).
> >   This is an open file descriptor for the object being accessed, or
> >   .B FAN_NOFD
> >   if a queue overflow occurred.
> > +If the fanotify file descriptor has been initialized using
> > +.BR FAN_REPORT_FID ,
> > +applications should expect this value to be set to
> > +.B FAN_NOFD
> > +for each event that is received.
> >   The file descriptor can be used to access the contents
> >   of the monitored file or directory.
> >   The reading application is responsible for closing this file descriptor.
> > @@ -262,6 +300,27 @@ See NOTES in
> >   .BR fanotify_mark (2)
> >   for additional details.
> >   .TP
> > +.B FAN_ATTRIB
> > +A file or directory metadata was changed.
> > +.TP
> > +.B FAN_CREATE
> > +A child file or directory was created in a watched parent.
> > +.TP
> > +.B FAN_DELETE
> > +A child file or directory was deleted in a watched parent.
> > +.TP
> > +.B FAN_DELETE_SELF
> > +A watched file or directory was deleted.
> > +.TP
> > +.B FAN_MOVED_FROM
> > +A file or directory has been moved from a watched parent directory.
> > +.TP
> > +.B FAN_MOVED_TO
> > +A file or directory has been moved to a watched parent directory.
> > +.TP
> > +.B FAN_MOVE_SELF
> > +A watched file or directory was moved.
> > +.TP
> >   .B FAN_MODIFY
> >   A file was modified.
> >   .TP
> > @@ -314,6 +373,76 @@ This is a synonym for:
> >   .IP
> >       FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE
> >   .PP
> > +To check for any move event, the following bit mask may be used:
> > +.TP
> > +.B FAN_MOVE
> > +A file or directory was moved.
> > +This is a synonym for:
> > +.IP
> > +    FAN_MOVED_FROM | FAN_MOVED_TO
> > +.PP
> > +The fields of the
> > +.I fanotify_event_info_fid
> > +structure are as follows:
> > +.TP
> > +.I hdr
> > +This is a structure of type
> > +.IR fanotify_event_info_header .
> > +It is a generic header that contains information used to describe
> > +additional information attached to the event.
> > +For example, when an fanotify file descriptor is created using
> > +.B FAN_REPORT_FID
> > +the
> > +.I info_type
> > +field of this header is set to
> > +.BR FAN_EVENT_INFO_TYPE_FID .
> > +Event listeners can use this field to check that the additional
> > +information received for an event is of the correct type.
> > +Additionally, the
> > +.I fanotify_event_info_header
> > +also contains a
> > +.I len
> > +field.
> > +In the current implementation, the value of
> > +.I len
> > +is always (event_len - FAN_EVENT_METADATA_LEN).
> > +.TP
> > +.I fsid
> > +This is a unique identifier of the filesystem containing the object
> > +associated with the event.
> > +It is a structure of type
> > +.I __kernel_fsid_t
> > +and contains the same value as
> > +.I f_fsid
> > +when calling
> > +.BR statfs (2).
> > +.TP
> > +.I file_handle
> > +This is a variable length structure of type
> > +.IR file_handle .
> > +It is an opaque handle that corresponds to a specified object on a
> > +filesystem as returned by
> > +.BR name_to_handle_at (2) .
> > +It can be used to uniquely identify a file on a filesystem and can be
> > +passed as an argument to
> > +.BR open_by_handle_at (2) .
> > +Note that for directory entry events, such as
> > +.BR FAN_CREATE ,
> > +.BR FAN_DELETE ,
> > +.BR FAN_MOVE
> > +the
> > +.IR file_handle
> > +describes the modified directory and not the created/deleted/moved child
> > +object.
> > +The events
> > +.BR FAN_ATTRIB ,
> > +.BR FAN_DELETE_SELF
> > +and
> > +.BR FAN_MOVE_SELF
> > +will carry the
> > +.IR file_handle
> > +information for the child object if the child object is being watched.
> > +.PP
> >   The following macros are provided to iterate over a buffer containing
> >   fanotify event metadata returned by a
> >   .BR read (2)
> > @@ -549,9 +678,12 @@ The return value will not be \-1, and
> >   will not be set.
> >   Thus, the reading application has no way to detect the error.
> >   .SH EXAMPLE
> > -The following program demonstrates the usage of the fanotify API.
> > -It marks the mount point passed as a command-line argument
> > -and waits for events of type
> > +The two example programs below demonstrate the usage of the fanotify API.
> > +The first program (fanotify_example.c) is an example of fanotify being
> > +used with its event object information passed in the form of a file
> > +descriptor.
> > +It marks the mount point passed as a command-line argument and waits for
> > +events of type
> >   .B FAN_OPEN_PERM
> >   and
> >   .BR FAN_CLOSE_WRITE .
> > @@ -559,7 +691,21 @@ When a permission event occurs, a
> >   .B FAN_ALLOW
> >   response is given.
> >   .PP
> > -The following output was recorded while editing the file
> > +The second program (fanotify_fid.c) is an example of fanotify being used
> > +with
> > +.B FAN_REPORT_FID
> > +enabled.
> > +It attempts to mark the object that is passed as a command-line argument
> 
> Why the wording "It attempts to mark the" vs "It marks"?
> 
> Your wording implies that the attempt may fail, but if that
> is the case, I thing some further words are needed here.

That's correct. I was in fact implying that this could fail and that's
certainly the reality. However, for the sake of illustration, I do think
it can be changed to "It marks" as oppose to "It attempts to mark". I
don't really have any strong points as to why it can't be changed "It
marks".

> > +and waits until an event of type
> > +.B FAN_CREATE
> > +has occurred.
> > +Depending on whether a file or directory is created depends on what mask
> > +is returned in the event mask.
> 
> That last sentence is not quite right. Is one of these alternatives
> correct?
> 
> "Whether or not a filesystem object (a file or directory) was created
> depends on what mask is returned in the event mask."
> 
> "The event mask indicates which type of filesystem object--either
> a file or a directory--was created".

This ^ is more accurate. Let's go with that.
 
> > +Once all events have been read from the buffer and processed accordingly,
> > +the program simply terminates.
> > +.PP
> > +The first example program output was captured from fanotify_example.
> > +This session involved editing the file
> >   .IR /home/user/temp/notes .
> >   Before the file was opened, a
> >   .B FAN_OPEN_PERM
> > @@ -568,7 +714,34 @@ After the file was closed, a
> >   .B FAN_CLOSE_WRITE
> >   event occurred.
> >   Execution of the program ends when the user presses the ENTER key.
> > -.SS Example output
> > +.PP
> > +The second example program output was captured from fanotify_fid.
> > +There are two discrete invocations to this program with each invocation
> > +accommodating a different action performed on a watched object.
> > +This first session shows a mark being placed on
> > +.IR /home/user .
> > +This is followed by a subsequent regular file
> > +.IR /home/user/testfile.txt
> > +being created.
> > +This results in a
> > +.B FAN_CREATE
> > +event being created and reported against the file's parent watched
> > +directory object.
> > +Program execution ends once all events captured within the buffer have
> > +been processed.
> > +The second session shows a mark being placed on
> > +.IR /home/user .
> > +This is followed by a directory
> > +.IR /home/user/testdir
> > +being created.
> > +This specific action results in the program producing a
> > +.B FAN_CREATE
> > +and
> > +.B FAN_ONDIR
> > +event.
> > +Program execution ends once all events captured within the buffer are
> > +processed.
> > +.SS Example output (fanotify_example.c)
> >   .in +4n
> >   .EX
> >   # ./fanotify_example /home
> > @@ -579,8 +752,27 @@ FAN_CLOSE_WRITE: File /home/user/temp/notes
> >   Listening for events stopped.
> >   .EE
> > +.SS Example output (fanotify_fid.c)
> > +.in +4n
> > +.EX
> > +# ./fanotify_fid /home/user
> > +Listening for events.
> > +FAN_CREATE (file created): Directory /home/user has been modified.
> > +All events processed successfully. Program exiting.
> > +
> > +$ touch /home/user/testing
> > +
> > +---
> > +
> > +# ./fanotify_fid /home/user
> > +Listening for events.
> > +FAN_CREATE | FAN_ONDIR (subdirectory created): Directory /home/user has been modified.
> > +All events processed successfully. Program exiting.
> > +
> > +$ mkdir -p /home/user/testing
> > +.EE
> >   .in
> > -.SS Program source
> > +.SS Program source: fanotify_example.c
> >   \&
> >   .EX
> >   #define _GNU_SOURCE     /* Needed to get O_LARGEFILE definition */
> > @@ -778,6 +970,123 @@ main(int argc, char *argv[])
> >       exit(EXIT_SUCCESS);
> >   }
> >   .EE
> > +.in
> > +.SS Program source: fanotify_fid.c
> > +\&
> > +.EX
> > +#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 argc, char **argv)
> > +{
> > +    int fd, ret, event_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;
> > +
> > +    if (argc != 2) {
> > +        fprintf(stderr, "Invalid number of command line arguments.\\n");
> > +        exit(EXIT_FAILURE);
> > +    }
> > +
> > +    /* Create an fanotify file descriptor with FAN_REPORT_FID as a flag
> > +     * so that program can receive fid events.
> > +     */
> > +    fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, 0);
> > +    if (fd == -1) {
> > +        perror("fanotify_init");
> > +        exit(EXIT_FAILURE);
> > +    }
> > +
> > +    /* Place a mark on the filesystem object supplied in argv[1]. */
> > +    ret = fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_ONLYDIR,
> > +                        FAN_CREATE | FAN_ONDIR,
> > +                        AT_FDCWD, argv[1]);
> > +    if (ret == -1) {
> > +        perror("fanotify_mark");
> > +        exit(EXIT_FAILURE);
> > +    }
> > +
> > +    printf("Listening for events.\\n");
> > +
> > +    /* Read events from the event queue into a buffer */
> > +    len = read(fd, (void *) &events_buf, sizeof(events_buf));
> > +    if (len == -1 && errno != EAGAIN) {
> > +        perror("read");
> > +        exit(EXIT_FAILURE);
> > +    }
> > +
> > +    /* Process all events within the buffer */
> > +    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);
> > +        file_handle = (struct file_handle *) fid->handle;
> > +
> > +        /* Ensure that the event info is of the correct type */
> > +        if (fid->hdr.info_type != FAN_EVENT_INFO_TYPE_FID) {
> > +            fprintf(stderr, "Received unexpected event info type.\\n");
> > +            exit(EXIT_FAILURE);
> > +        }
> > +
> > +        if (metadata->mask == FAN_CREATE)
> > +            printf("FAN_CREATE (file created): ");
> > +
> > +        if (metadata->mask == FAN_CREATE | FAN_ONDIR)
> > +            printf("FAN_CREATE | FAN_ONDIR (subdirectory created): ");
> > +
> > +        /* metadata->fd is set to FAN_NOFD when FAN_REPORT_FID is enabled.
> > +         * To obtain a file descriptor for the file object corresponding to
> > +         * an event you can use the struct file_handle that's provided
> > +         * within the fanotify_event_info_fid in conjunction with the
> > +         * open_by_handle_at(2) system call. A check for -ESTALE is done
> > +         * to accommodate for the situation where the file handle was
> > +         * deleted for the object prior to this system call.
> 
> Would that last sentence read better as:
> 
> "... where the file handle for the object was deleted prior to
> this system call."
> 
> ?

Yes, that's definitely better.
 
> > +         */
> > +        event_fd = open_by_handle_at(AT_FDCWD, file_handle, O_RDONLY);
> > +        if (ret == -1 && errno == ESTALE) {
> > +            printf("File handle is no longer valid. File has been deleted\\n");
> > +            continue;
> > +        } else if (ret == -1) {
> > +            perror("open_by_handle_at");
> > +            exit(EXIT_FAILURE);
> > +        }
> > +
> > +        snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d", event_fd);
> > +
> > +        /* Retreive and print the path of the modified dentry */
> > +        path_len = readlink(procfd_path, path, sizeof(path) - 1);
> > +        if (path_len == -1) {
> > +            perror("readlink");
> > +            exit(EXIT_FAILURE);
> > +        }
> > +
> > +        path[path_len] = '\\0';
> > +        printf("Directory '%s' has been modified.\\n", path);
> > +
> > +        /* Close associated file descriptor for this event */
> > +        close(event_fd);
> > +    }
> > +
> > +    printf("All events processed successfully. Program exiting.\\n");
> > +    exit(EXIT_SUCCESS);
> > +}
> > +.EE
> >   .SH SEE ALSO
> >   .ad l
> >   .BR fanotify_init (2),
> > 

-- 
Matthew Bobrowski



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux