Skip to content

Commit

Permalink
Document the new fanotify FAN_REPORT_PIDFD initialization flag.
Browse files Browse the repository at this point in the history
This provides an explanation on the kind of additional information
that can be returned alongside the generic fanotify_event_metadata
structure i.e. the fanotify_event_info_pidfd structure, and in what
form this additional contextual information is delievered to the
listening application.

Signed-off-by: Matthew Bobrowski <repnop@google.com>
Reviewed-by: Jan Kara <jack@suse.cz>
  • Loading branch information
matthewbobrowski committed Nov 22, 2021
1 parent 27d808e commit 070c144
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 44 deletions.
57 changes: 57 additions & 0 deletions man2/fanotify_init.2
Expand Up @@ -300,6 +300,63 @@ for additional details.
This is a synonym for
.RB ( FAN_REPORT_DIR_FID | FAN_REPORT_NAME ).
.PP
.TP
.B FAN_REPORT_PIDFD " (since Linux 5.15)"
.\" commit af579beb666aefb17e9a335c12c788c92932baf1
Events for fanotify groups initialized with this flag will contain an
additional information record object alongside the generic fanotify
event metadata structure.
This additional information record will be of type
.BR FAN_EVENT_INFO_TYPE_PIDFD
and will contain a pidfd for the process that was responsible for
generating an event.
The returned pidfd within the information object is indistinguishable
from a pidfd that is obtained via
.BR pidfd_open(2).
Usage of this additional information record object is for applications
that are interested in reliably determining whether the process
responsible for generating the event has either been recycled or
terminated.
In the instance that either
.BR FAN_REPORT_FID
or
.BR FAN_REPORT_DFID_NAME
are supplied along with
.BR FAN_REPORT_PIDFD ,
information record objects of type
.BR FAN_EVENT_INFO_TYPE_FID,
.BR FAN_EVENT_INFO_TYPE_DFID
or
.BR FAN_EVENT_INFO_TYPE_DFID_NAME
will be present along with an information object of type

This comment has been minimized.

Copy link
@amir73il

amir73il Nov 22, 2021

I would drop this entire paragraph starting with "In the instance..."? What will we do when we add more info types? add them to this list? Should we write in also near section about FAN_EVENT_INFO_TYPE_FID that it will reported along side FAN_EVENT_INFO_TYPE_PIDFD? it does not make much sense or add much value IMO.

This comment has been minimized.

Copy link
@matthewbobrowski

matthewbobrowski Nov 24, 2021

Author Owner

Fair point. I think this could be implicitly implied in the generic explanation paragraph in fanotify.7 anyway.

.BR FAN_EVENT_INFO_TYPE_PIDFD
for a single event within the read buffer.
An event listener should never make any assumptions around the
specific ordering of information record objects within an event and
must always check the
.I info_type
value set within the
.IR fanotify_event_info_header
of each information record object.

This comment has been minimized.

Copy link
@amir73il

amir73il Nov 22, 2021

This paragraph is important, but it does not belong in a section about FAN_REPORT_PIDFD. It should be in a generic section about fanotify_event_info_header, probably in fanotify.7.

This comment has been minimized.

Copy link
@matthewbobrowski

matthewbobrowski Nov 24, 2021

Author Owner

You're right. It applies generally to supplemental information record types. I'll shuffle this around.

The use of the
.BR FAN_REPORT_TID
flag along with
.BR FAN_REPORT_PIDFD
is currently not supported and attempting to do so will result in the
error
.BR EINVAL
being returned.
This limitation is imposed by the pidfd API as it currently only
supports the creation of pidfds for thread-group leaders.
Creating pidfds for non-thread-group leaders may be supported at some
point in the future, so this restriction may eventually be lifted.
Additional pidfd specific error cases can be reported back to the
listening application in an information record object of type
.BR FAN_EVENT_INFO_TYPE_PIDFD.
See
.BR fanotify(7)
for additional details.
.PP
The
.I event_f_flags
argument
Expand Down
202 changes: 158 additions & 44 deletions man7/fanotify.7
Expand Up @@ -141,12 +141,24 @@ until either a file event occurs or the call is interrupted by a signal
The use of one of the flags
.BR FAN_REPORT_FID ,
.BR FAN_REPORT_DIR_FID
or
.BR FAN_REPORT_PIDFD
in
.BR fanotify_init (2)
influences what data structures are returned to the event listener for each
event.
Events reported to a group initialized with one of these flags will
use file handles to identify filesystem objects instead of file descriptors.
Events reported to a group initialized with one of either
.BR FAN_REPORT_FID
or
.BR FAN_REPORT_DIR_FID
flags will use file handles to identify filesystem objects instead of
file descriptors.
Events reported to a group initialized with
.BR FAN_REPORT_PIDFD
will attempt to also create a process file descriptor, commonly
referred to as a pidfd, for the process responsible for generating the
event and provide that alongside the generic fanotify metadata event
structure.
.PP
After a successful
.BR read (2),
Expand Down Expand Up @@ -174,12 +186,6 @@ structure within the read buffer:
.PP
.in +4n
.EX
struct fanotify_event_info_header {
__u8 info_type;
__u8 pad;
__u16 len;
};
struct fanotify_event_info_fid {
struct fanotify_event_info_header hdr;
__kernel_fsid_t fsid;
Expand All @@ -188,6 +194,47 @@ struct fanotify_event_info_fid {
.EE
.in
.PP
In the instance that the fanotify group has been initialized with
.BR FAN_REPORT_PIDFD ,
the event listener should expect to receive a single information

This comment has been minimized.

Copy link
@amir73il

amir73il Nov 22, 2021

"single information record"? it sound like the only info record, maybe receive "an information record"?

This comment has been minimized.

Copy link
@matthewbobrowski

matthewbobrowski Nov 24, 2021

Author Owner

ACK, will update this.

record object as detailed below alongside the generic
.I fanotify_event_metadata
structure:
.PP
.in +4n
.EX
struct fanotify_event_info_pidfd {
struct fanotify_event_info_header hdr;
__s32 pidfd;
};
.EE
.in
.PP
All information record object types, including
.I fanotify_event_info_fid
and
.IR fanotify_event_info_pidfd ,
contain a nested structure of type
.IR fanotify_event_info_header .
This nested structure holds the meta-information about each
supplemental information record that may be provided alongside the
generic
.I fanotify_event_metadata
structure.
The
.I fanotify_event_info_header
structure is defined as follows:
.PP
.in +4n
.EX
struct fanotify_event_info_header {
__u8 info_type;
__u8 pad;
__u16 len;
};
.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
Expand Down Expand Up @@ -397,52 +444,78 @@ The
flag is reported in an event mask only if the fanotify group identifies
filesystem objects by file handles.
.PP
All information record object types that are supplied alongside a
generic
.I fanotify_event_metadata
record will contain a nested
.I fanotify_event_info_header
structure.
The fields of the
.I fanotify_event_info_header
structure are as follows:
.TP
.I info_type
A unique integer value representing the type of information record
object received for an event.
The value of this field can be set to either
.BR FAN_EVENT_INFO_TYPE_FID ,
.BR FAN_EVENT_INFO_TYPE_DFID ,
.B FAN_EVENT_INFO_TYPE_DFID_NAME
or
.BR FAN_EVENT_INFO_TYPE_PIDFD .
The value set within each information record object type is dependent
on the flags that have been supplied to
.BR fanotify_init (2) .
Refer to the field details of each information record object type
below to understand the different situations in which these
.I info_type
values can be set.
.TP
.I pad
This field is currently not used by any information record object
type. The value is set to zero.
.TP
.I len
The value of
.I len
is set to the size of the information record object, including the
.IR fanotify_event_info_header .
The total size of all additional information records is not expected
to be larger than
(
.IR event_len
\-
.IR metadata_len
).
.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 an
additional information record attached to the event.
For example, when an fanotify file descriptor is created using
When an fanotify group is initialized using

This comment has been minimized.

Copy link
@amir73il

amir73il Nov 22, 2021

Why remove "For example:" this is an example.

This comment has been minimized.

Copy link
@matthewbobrowski

matthewbobrowski Nov 24, 2021

Author Owner

It read better IMO, but I can revert it. It implied like there are a ton of different info_type's one could expect and this was one of the many examples. The text then went on to explain all the other info_type's one could receive in the different FID modes.

.BR FAN_REPORT_FID ,
a single information record is expected to be attached to the event with
a single information record is returned alongside the generic metadata
event with the
.I info_type
field value of
field value set to
.BR FAN_EVENT_INFO_TYPE_FID .
When an fanotify file descriptor is created using the combination of
If an fanotify group is initialized with
.BR FAN_REPORT_FID
and
.BR FAN_REPORT_DIR_FID ,
there may be two information records attached to the event:
one with
then there may be two information records attached to a single event.
One having the

This comment has been minimized.

Copy link
@amir73il

amir73il Nov 22, 2021

I think those examples are a bit out of place for the description of the hdr field.
I would add a generic paragraph explaining about "information records" (like the one I asked you to remove from fanotify_init.2) just after "struct fanotify_event_metadata", including the text about no ordering guarantees and perhaps those examples.
I think it will be a good prelude for the fanotify_event_info_* structs that follow.

This comment has been minimized.

Copy link
@matthewbobrowski

matthewbobrowski Nov 24, 2021

Author Owner

Hm, OK. On the contrary, I was thinking that we should be keeping specific examples of the info_type's one could expect to receive alongside each different fanotify_event_info_* record. I definitely did consider a generic paragraph which covers all the cases, but I thought that would lead to more confusion and guessing. Leave it with me, I'll give it another crack and see whether I can come up with something better.

.I info_type
field value of
field value set to
.BR FAN_EVENT_INFO_TYPE_DFID ,
identifying a parent directory object, and one with
identifying a parent directory object, while the other having the
.I info_type
field value of
field value set to
.BR FAN_EVENT_INFO_TYPE_FID ,
identifying a non-directory object.
The
.I fanotify_event_info_header
contains a
.I len
field.
The value of
.I len
is the size of the additional information record including the
.IR fanotify_event_info_header
itself.
The total size of all additional information records is not expected
to be bigger than
(
.IR event_len
\-
.IR metadata_len
).
.TP
.I fsid
This is a unique identifier of the filesystem containing the object
Expand Down Expand Up @@ -471,8 +544,8 @@ the
.IR file_handle
identifies the modified directory and not the created/deleted/moved child
object.
If the value of
.I info_type
If the value of the
.I hdr.info_type
field is
.BR FAN_EVENT_INFO_TYPE_DFID_NAME ,
the file handle is followed by a null terminated string that identifies the
Expand All @@ -483,23 +556,23 @@ For other events such as
.BR FAN_DELETE_SELF ,
and
.BR FAN_MOVE_SELF ,
if the value of
.I info_type
if the value of the
.I hdr.info_type
field is
.BR FAN_EVENT_INFO_TYPE_FID ,
the
.IR file_handle
identifies the object correlated to the event.
If the value of
.I info_type
If the value of the
.I hdr.info_type
field is
.BR FAN_EVENT_INFO_TYPE_DFID ,
the
.IR file_handle
identifies the directory object correlated to the event or the parent directory
of a non-directory object correlated to the event.
If the value of
.I info_type
If the value of the
.I hdr.info_type
field is
.BR FAN_EVENT_INFO_TYPE_DFID_NAME ,
the
Expand All @@ -510,6 +583,47 @@ and the file handle is followed by a null terminated string that identifies the
name of a directory entry in that directory, or '.' to identify the directory
object itself.
.PP
The fields of the
.I fanotify_event_info_pidfd
structure are as follows:
.TP
.I hdr
This is a structure of type
.IR fanotify_event_info_header .
When an fanotify group is initialized using
.BR FAN_REPORT_PIDFD ,
a single information record object type is returned alongside the

This comment has been minimized.

Copy link
@amir73il

amir73il Nov 22, 2021

"single" inforamtion record is missleading IMO

This comment has been minimized.

Copy link
@matthewbobrowski

matthewbobrowski Nov 24, 2021

Author Owner

ACK, will update.

generic metadata event with the
.I info_type
field value set to
.BR FAN_EVENT_INFO_TYPE_PIDFD .
.TP
.I pidfd
This is a file descriptor that refers to the process responsible for
generating the event.
This returned file descriptor is no different from one which could be
obtained manually if
.BR pidfd_open(2)
were to be called on
.IR fanotify_event_metadata.pid .
In the instance that an error is encountered during pidfd creation for
an event, one of two possible error types represented by a negative
integer value may be returned in this
.I pidfd
field.
In cases where the process responsible for generating the event has
terminated prior to the event listener being able to read events from the
notification queue,
.B FAN_NOPIDFD
is returned.
The pidfd allocation for an event is only performed at the time the events
are read from the notification queue.
All other possible pidfd creation failures are represented by
.BR FAN_EPIDFD .
Once the event listener has dealt with an event and the pidfd is no
longer required, the pidfd should be closed via
.BR close(2) .
.PP
The following macros are provided to iterate over a buffer containing
fanotify event metadata returned by a
.BR read (2)
Expand Down

0 comments on commit 070c144

Please sign in to comment.