1 .\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk@gmx.de>
2 .\" and Copyright (C) 2014, Michael Kerrisk <mtk.manpages@gmail.com>
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .TH fanotify 7 (date) "Linux man-pages (unreleased)"
7 fanotify \- monitoring filesystem events
9 The fanotify API provides notification and interception of
11 Use cases include virus scanning and hierarchical storage management.
12 In the original fanotify API, only a limited set of events was supported.
13 In particular, there was no support for create, delete, and move events.
14 The support for those events was added in Linux 5.1.
17 for details of an API that did notify those events pre Linux 5.1.)
19 Additional capabilities compared to the
21 API include the ability to monitor all of the objects
22 in a mounted filesystem,
23 the ability to make access permission decisions, and the
24 possibility to read or modify files before access by other applications.
26 The following system calls are used with this API:
27 .BR fanotify_init (2),
28 .BR fanotify_mark (2),
33 .SS fanotify_init(), fanotify_mark(), and notification groups
36 system call creates and initializes an fanotify notification group
37 and returns a file descriptor referring to it.
39 An fanotify notification group is a kernel-internal object that holds
40 a list of files, directories, filesystems, and mounts for which
41 events shall be created.
43 For each entry in an fanotify notification group, two bit masks exist: the
48 The mark mask defines file activities for which an event shall be created.
49 The ignore mask defines activities for which no event shall be generated.
50 Having these two types of masks permits a filesystem, mount, or
51 directory to be marked for receiving events, while at the same time
52 ignoring events for specific objects under a mount or directory.
56 system call adds a file, directory, filesystem, or mount to a
57 notification group and specifies which events
58 shall be reported (or ignored), or removes or modifies such an entry.
60 A possible usage of the ignore mask is for a file cache.
61 Events of interest for a file cache are modification of a file and closing
63 Hence, the cached directory or mount is to be marked to receive these
65 After receiving the first event informing that a file has been modified,
66 the corresponding cache entry will be invalidated.
67 No further modification events for this file are of interest until the file
69 Hence, the modify event can be added to the ignore mask.
70 Upon receiving the close event, the modify event can be removed from the
71 ignore mask and the file cache entry can be updated.
73 The entries in the fanotify notification groups refer to files and
74 directories via their inode number and to mounts via their mount ID.
75 If files or directories are renamed or moved within the same mount,
76 the respective entries survive.
77 If files or directories are deleted or moved to another mount or if
78 filesystems or mounts are unmounted, the corresponding entries are deleted.
80 As events occur on the filesystem objects monitored by a notification group,
81 the fanotify system generates events that are collected in a queue.
82 These events can then be read (using
85 from the fanotify file descriptor
87 .BR fanotify_init (2).
89 Two types of events are generated:
94 Notification events are merely informative and require no action to be taken
95 by the receiving application with one exception: if a valid file descriptor
96 is provided within a generic event, the file descriptor must be closed.
97 Permission events are requests to the receiving application to decide
98 whether permission for a file access shall be granted.
99 For these events, the recipient must write a response which decides whether
100 access is granted or not.
102 An event is removed from the event queue of the fanotify group
103 when it has been read.
104 Permission events that have been read are kept in an internal list of the
105 fanotify group until either a permission decision has been taken by
106 writing to the fanotify file descriptor or the fanotify file descriptor
108 .SS Reading fanotify events
111 for the file descriptor returned by
112 .BR fanotify_init (2)
115 is not specified in the call to
116 .BR fanotify_init (2))
117 until either a file event occurs or the call is interrupted by a signal
123 the read buffer contains one or more of the following structures:
127 struct fanotify_event_metadata {
139 Information records are
140 supplemental pieces of information that
141 may be provided alongside the generic
142 .I fanotify_event_metadata
147 .BR fanotify_init (2)
148 have influence over the type of information records that
149 may be returned for an event.
151 if a notification group is initialized with
154 .BR FAN_REPORT_DIR_FID ,
155 then event listeners should also expect to receive a
156 .I fanotify_event_info_fid
157 structure alongside the
158 .I fanotify_event_metadata
160 whereby file handles are used to
161 identify filesystem objects
162 rather than file descriptors.
163 Information records may also be stacked,
164 meaning that using the various
166 flags in conjunction with one another is supported.
168 multiple information records can be returned for an event
169 alongside the generic
170 .I fanotify_event_metadata
173 if a notification group is initialized with
174 .B FAN_REPORT_TARGET_FID
176 .BR FAN_REPORT_PIDFD ,
177 then an event listener should expect to receive up to two
178 .I fanotify_event_info_fid
179 information records and one
180 .I fanotify_event_info_pidfd
181 information record alongside the generic
182 .I fanotify_event_metadata
185 fanotify provides no guarantee around
186 the ordering of information records
187 when a notification group is initialized with a
188 stacked based configuration.
189 Each information record has a nested structure of type
190 .IR fanotify_event_info_header .
191 It is imperative for event listeners to inspect the
193 field of this structure in order to
194 determine the type of information record that
195 had been received for a given event.
197 In cases where an fanotify group
198 identifies filesystem objects by file handles,
199 event listeners should also expect to
200 receive one or more of the below
201 information record objects alongside the generic
202 .I fanotify_event_metadata
203 structure within the read buffer:
207 struct fanotify_event_info_fid {
208 struct fanotify_event_info_header hdr;
209 __kernel_fsid_t fsid;
210 unsigned char handle[];
215 In cases where an fanotify group is initialized with
216 .BR FAN_REPORT_PIDFD ,
217 event listeners should expect to receive the below
218 information record object alongside the generic
219 .I fanotify_event_metadata
220 structure within the read buffer:
224 struct fanotify_event_info_pidfd {
225 struct fanotify_event_info_header hdr;
234 an additional information record describing the error that occurred
235 is returned alongside the generic
236 .I fanotify_event_metadata
237 structure within the read buffer.
238 This structure is defined as follows:
242 struct fanotify_event_info_error {
243 struct fanotify_event_info_header hdr;
250 All information records contain a nested structure of type
251 .IR fanotify_event_info_header .
252 This structure holds meta-information about the information record
253 that may have been returned alongside the generic
254 .I fanotify_event_metadata
256 This structure is defined as follows:
260 struct fanotify_event_info_header {
268 For performance reasons, it is recommended to use a large
269 buffer size (for example, 4096 bytes),
270 so that multiple events can be retrieved by a single
275 is the number of bytes placed in the buffer,
276 or \-1 in case of an error (but see BUGS).
279 .I fanotify_event_metadata
280 structure are as follows:
283 This is the length of the data for the current event and the offset
284 to the next event in the buffer.
285 Unless the group identifies filesystem objects by file handles, the value of
288 .BR FAN_EVENT_METADATA_LEN .
289 For a group that identifies filesystem objects by file handles,
291 also includes the variable length file identifier records.
294 This field holds a version number for the structure.
295 It must be compared to
296 .B FANOTIFY_METADATA_VERSION
297 to verify that the structures returned at run time match
298 the structures defined at compile time.
299 In case of a mismatch, the application should abandon trying to use the
300 fanotify file descriptor.
303 This field is not used.
306 This is the length of the structure.
307 The field was introduced to facilitate the implementation of
308 optional headers per event type.
309 No such optional headers exist in the current implementation.
312 This is a bit mask describing the event (see below).
315 This is an open file descriptor for the object being accessed, or
317 if a queue overflow occurred.
318 With an fanotify group that identifies filesystem objects by file handles,
319 applications should expect this value to be set to
321 for each event that is received.
322 The file descriptor can be used to access the contents
323 of the monitored file or directory.
324 The reading application is responsible for closing this file descriptor.
327 .BR fanotify_init (2),
328 the caller may specify (via the
330 argument) various file status flags that are to be set
331 on the open file description that corresponds to this file descriptor.
332 In addition, the (kernel-internal)
334 file status flag is set on the open file description.
335 This flag suppresses fanotify event generation.
336 Hence, when the receiver of the fanotify event accesses the notified file or
337 directory using this file descriptor, no additional events will be created.
343 .BR fanotify_init (2),
344 this is the TID of the thread that caused the event.
345 Otherwise, this the PID of the process that caused the event.
347 A program listening to fanotify events can compare this PID
348 to the PID returned by
350 to determine whether the event is caused by the listener itself,
351 or is due to a file access by another process.
355 indicates which events have occurred for a single filesystem object.
356 Multiple bits may be set in this mask,
357 if more than one event occurred for the monitored filesystem object.
359 consecutive events for the same filesystem object and originating from the
360 same process may be merged into a single event, with the exception that two
361 permission events are never merged into one queue entry.
363 The bits that may appear in
368 A file or a directory (but see BUGS) was accessed (read).
371 A file or a directory was opened.
374 A file was opened with the intent to be executed.
376 .BR fanotify_mark (2)
377 for additional details.
380 A file or directory metadata was changed.
383 A child file or directory was created in a watched parent.
386 A child file or directory was deleted in a watched parent.
389 A watched file or directory was deleted.
392 A filesystem error was detected.
395 A file or directory has been moved to or from a watched parent directory.
398 A file or directory has been moved from a watched parent directory.
401 A file or directory has been moved to a watched parent directory.
404 A watched file or directory was moved.
410 A file that was opened for writing
417 A file or directory that was opened read-only
422 The event queue exceeded the limit on number of events.
423 This limit can be overridden by specifying the
424 .B FAN_UNLIMITED_QUEUE
426 .BR fanotify_init (2).
429 An application wants to read a file or directory, for example using
433 The reader must write a response (as described below)
434 that determines whether the permission to
435 access the filesystem object shall be granted.
438 An application wants to open a file or directory.
439 The reader must write a response that determines whether the permission to
440 open the filesystem object shall be granted.
442 .B FAN_OPEN_EXEC_PERM
443 An application wants to open a file for execution.
444 The reader must write a response that determines whether the permission to
445 open the filesystem object for execution shall be granted.
447 .BR fanotify_mark (2)
448 for additional details.
450 To check for any close event, the following bit mask may be used:
454 This is a synonym for:
458 FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE
462 To check for any move event, the following bit mask may be used:
465 A file or directory was moved.
466 This is a synonym for:
470 FAN_MOVED_FROM | FAN_MOVED_TO
474 The following bits may appear in
476 only in conjunction with other event type bits:
479 The events described in the
481 have occurred on a directory object.
482 Reporting events on directories requires setting this flag in the mark mask.
484 .BR fanotify_mark (2)
485 for additional details.
488 flag is reported in an event mask only if the fanotify group identifies
489 filesystem objects by file handles.
491 Information records that are supplied alongside the generic
492 .I fanotify_event_metadata
493 structure will always contain a nested structure of type
494 .IR fanotify_event_info_header .
496 .I fanotify_event_info_header
500 A unique integer value representing
501 the type of information record object received for an event.
502 The value of this field can be set to one of the following:
503 .BR FAN_EVENT_INFO_TYPE_FID ,
504 .BR FAN_EVENT_INFO_TYPE_DFID ,
505 .BR FAN_EVENT_INFO_TYPE_DFID_NAME ,
507 .BR FAN_EVENT_INFO_TYPE_PIDFD .
508 The value set for this field
509 is dependent on the flags that have been supplied to
510 .BR fanotify_init (2).
511 Refer to the field details of each information record object type below
512 to understand the different cases in which the
517 This field is currently not used by any information record object type
518 and therefore is set to zero.
523 is set to the size of the information record object,
525 .IR fanotify_event_info_header .
526 The total size of all additional information records
527 is not expected to be larger than
533 .I fanotify_event_info_fid
534 structure are as follows:
537 This is a structure of type
538 .IR fanotify_event_info_header .
539 For example, when an fanotify file descriptor is created using
541 a single information record is expected to be attached to the event with
544 .BR FAN_EVENT_INFO_TYPE_FID .
545 When an fanotify file descriptor is created using the combination of
548 .BR FAN_REPORT_DIR_FID ,
549 there may be two information records attached to the event:
553 .BR FAN_EVENT_INFO_TYPE_DFID ,
554 identifying a parent directory object, and one with
557 .BR FAN_EVENT_INFO_TYPE_FID ,
558 identifying a child object.
559 Note that for the directory entry modification events
565 an information record identifying the created/deleted/moved child object
566 is reported only if an fanotify group was initialized with the flag
567 .BR FAN_REPORT_TARGET_FID .
570 This is a unique identifier of the filesystem containing the object
571 associated with the event.
572 It is a structure of type
574 and contains the same value as
580 This field contains a variable-length structure of type
581 .IR "struct file_handle" .
582 It is an opaque handle that corresponds to a specified object on a
583 filesystem as returned by
584 .BR name_to_handle_at (2).
585 It can be used to uniquely identify a file on a filesystem and can be
586 passed as an argument to
587 .BR open_by_handle_at (2).
591 .BR FAN_EVENT_INFO_TYPE_DFID_NAME ,
592 the file handle is followed by a null terminated string that identifies the
593 created/deleted/moved directory entry name.
594 For other events such as
597 .BR FAN_DELETE_SELF ,
603 .BR FAN_EVENT_INFO_TYPE_FID ,
606 identifies the object correlated to the event.
610 .BR FAN_EVENT_INFO_TYPE_DFID ,
613 identifies the directory object correlated to the event or the parent directory
614 of a non-directory object correlated to the event.
618 .BR FAN_EVENT_INFO_TYPE_DFID_NAME ,
621 identifies the same directory object that would be reported with
622 .B FAN_EVENT_INFO_TYPE_DFID
623 and the file handle is followed by a null terminated string that identifies the
624 name of a directory entry in that directory, or '.' to identify the directory
628 .I fanotify_event_info_pidfd
629 structure are as follows:
632 This is a structure of type
633 .IR fanotify_event_info_header .
634 When an fanotify group is initialized using
635 .BR FAN_REPORT_PIDFD ,
639 .I fanotify_event_info_header
641 .BR FAN_EVENT_INFO_TYPE_PIDFD .
644 This is a process file descriptor that refers to
645 the process responsible for generating the event.
646 The returned process file descriptor is no different from
647 one which could be obtained manually if
650 .IR fanotify_event_metadata.pid .
651 In the instance that an error is encountered during pidfd creation,
652 one of two possible error types represented by
653 a negative integer value may be returned in this
657 the process responsible for generating the event
658 has terminated prior to
659 the event listener being able to
660 read events from the notification queue,
663 The pidfd creation for an event is only performed at the time the
664 events are read from the notification queue.
665 All other possible pidfd creation failures are represented by
667 Once the event listener has dealt with an event
668 and the pidfd is no longer required,
669 the pidfd should be closed via
673 .I fanotify_event_info_error
674 structure are as follows:
677 This is a structure of type
678 .IR fanotify_event_info_header .
682 .BR FAN_EVENT_INFO_TYPE_ERROR .
685 Identifies the type of error that occurred.
688 This is a counter of the number of errors suppressed
689 since the last error was read.
691 The following macros are provided to iterate over a buffer containing
692 fanotify event metadata returned by a
694 from an fanotify file descriptor:
696 .B FAN_EVENT_OK(meta, len)
697 This macro checks the remaining length
701 against the length of the metadata structure and the
703 field of the first metadata structure in the buffer.
705 .B FAN_EVENT_NEXT(meta, len)
706 This macro uses the length indicated in the
708 field of the metadata structure pointed to by
710 to calculate the address of the next metadata structure that follows
713 is the number of bytes of metadata that currently remain in the buffer.
714 The macro returns a pointer to the next metadata structure that follows
718 by the number of bytes in the metadata structure that
719 has been skipped over (i.e., it subtracts
724 In addition, there is:
726 .B FAN_EVENT_METADATA_LEN
727 This macro returns the size (in bytes) of the structure
728 .IR fanotify_event_metadata .
729 This is the minimum size (and currently the only size) of any event metadata.
731 .SS Monitoring an fanotify file descriptor for events
732 When an fanotify event occurs, the fanotify file descriptor indicates as
733 readable when passed to
738 .SS Dealing with permission events
739 For permission events, the application must
741 a structure of the following form to the
742 fanotify file descriptor:
746 struct fanotify_response {
753 The fields of this structure are as follows:
756 This is the file descriptor from the structure
757 .IR fanotify_event_metadata .
760 This field indicates whether or not the permission is to be granted.
761 Its value must be either
763 to allow the file operation or
765 to deny the file operation.
767 If access is denied, the requesting application call will receive an
770 Additionally, if the notification group has been created with the
774 flag can be set in the
777 In that case, the audit subsystem will log information about the access
778 decision to the audit logs.
780 .SS Monitoring filesystems for errors
783 event is stored per filesystem at once.
784 Extra error messages are suppressed and accounted for in the
786 field of the existing
789 but details about the errors are lost.
796 but not all kinds of error types are reported by all filesystems.
798 Errors not directly related to a file (i.e. super block corruption)
799 are reported with an invalid
801 For these errors, the
807 and the handle buffer size set to
810 .SS Closing the fanotify file descriptor
811 When all file descriptors referring to the fanotify notification group are
812 closed, the fanotify group is released and its resources
813 are freed for reuse by the kernel.
816 outstanding permission events will be set to allowed.
819 .IR /proc/ pid /fdinfo/ fd
820 contains information about fanotify marks for file descriptor
828 Since Linux 5.13 (and 5.10.220),
829 .\" commit 5b8fea65d197f408bb00b251c70d842826d6b70b
830 the following interfaces can be used to control the amount of
831 kernel resources consumed by fanotify:
833 .I /proc/sys/fs/fanotify/max_queued_events
834 The value in this file is used when an application calls
835 .BR fanotify_init (2)
836 to set an upper limit on the number of events that can be
837 queued to the corresponding fanotify group.
838 Events in excess of this limit are dropped, but an
840 event is always generated.
841 Prior to Linux kernel 5.13,
842 .\" commit 5b8fea65d197f408bb00b251c70d842826d6b70b
843 the hardcoded limit was 16384 events.
845 .I /proc/sys/fs/fanotify/max_user_group
846 This specifies an upper limit on the number of fanotify groups
847 that can be created per real user ID.
848 Prior to Linux kernel 5.13,
849 .\" commit 5b8fea65d197f408bb00b251c70d842826d6b70b
850 the hardcoded limit was 128 groups per user.
852 .I /proc/sys/fs/fanotify/max_user_marks
853 This specifies an upper limit on the number of fanotify marks
854 that can be created per real user ID.
855 Prior to Linux kernel 5.13,
856 .\" commit 5b8fea65d197f408bb00b251c70d842826d6b70b
857 the hardcoded limit was 8192 marks per group (not per user).
859 In addition to the usual errors for
861 the following errors can occur when reading from the
862 fanotify file descriptor:
865 The buffer is too small to hold the event.
868 The per-process limit on the number of open files has been reached.
869 See the description of
875 The system-wide limit on the total number of open files has been reached.
877 .I /proc/sys/fs/file\-max
882 This error is returned by
890 argument when calling
891 .BR fanotify_init (2)
892 and an event occurred for a monitored file that is currently being executed.
894 In addition to the usual errors for
896 the following errors can occur when writing to the fanotify file descriptor:
899 Fanotify access permissions are not enabled in the kernel configuration
902 in the response structure is not valid.
907 in the response structure is not valid.
908 This may occur when a response for the permission event has already been
913 The fanotify API was introduced in Linux 2.6.36 and
914 enabled in Linux 2.6.37.
915 fdinfo support was added in Linux 3.8.
917 The fanotify API is available only if the kernel was built with the
919 configuration option enabled.
920 In addition, fanotify permission handling is available only if the
921 .B CONFIG_FANOTIFY_ACCESS_PERMISSIONS
922 configuration option is enabled.
923 .SS Limitations and caveats
924 Fanotify reports only events that a user-space program triggers through the
927 it does not catch remote events that occur on network filesystems.
929 The fanotify API does not report file accesses and modifications that
936 Events for directories are created only if the directory itself is opened,
938 Adding, removing, or changing children of a marked directory does not create
939 events for the monitored directory itself.
941 Fanotify monitoring of directories is not recursive:
942 to monitor subdirectories under a directory,
943 additional marks must be created.
946 event can be used for detecting when a subdirectory has been created under
948 An additional mark must then be set on the newly created subdirectory.
949 This approach is racy, because it can lose events that occurred inside the
950 newly created subdirectory, before a mark is added on that subdirectory.
951 Monitoring mounts offers the capability to monitor a whole directory tree
952 in a race-free manner.
953 Monitoring filesystems offers the capability to monitor changes made from
954 any mount of a filesystem instance in a race-free manner.
956 The event queue can overflow.
957 In this case, events are lost.
961 did not generate fanotify events.
963 .\" commit 820c12d5d6c0890bc93dd63893924a13041fdc35
971 the following bugs exist:
973 On Linux, a filesystem object may be accessible through multiple paths,
974 for example, a part of a filesystem may be remounted using the
978 A listener that marked a mount will be notified only of events that were
979 triggered for a filesystem object using the same mount.
980 Any other event will pass unnoticed.
982 .\" FIXME . A patch was proposed.
983 When an event is generated,
984 no check is made to see whether the user ID of the
985 receiving process has authorization to read or write the file
986 before passing a file descriptor for that file.
987 This poses a security risk, when the
989 capability is set for programs executed by unprivileged users.
993 processes multiple events from the fanotify queue and an error occurs,
994 the return value will be the total length of the events successfully
995 copied to the user-space buffer before the error occurred.
996 The return value will not be \-1, and
999 Thus, the reading application has no way to detect the error.
1001 The two example programs below demonstrate the usage of the fanotify API.
1002 .SS Example program: fanotify_example.c
1003 The first program is an example of fanotify being
1004 used with its event object information passed in the form of a file
1006 The program marks the mount passed as a command-line argument and
1007 waits for events of type
1010 .BR FAN_CLOSE_WRITE .
1011 When a permission event occurs, a
1015 The following shell session shows an example of
1016 running this program.
1017 This session involved editing the file
1018 .IR /home/user/temp/notes .
1019 Before the file was opened, a
1022 After the file was closed, a
1025 Execution of the program ends when the user presses the ENTER key.
1029 # \fB./fanotify_example /home\fP
1030 Press enter key to terminate.
1031 Listening for events.
1032 FAN_OPEN_PERM: File /home/user/temp/notes
1033 FAN_CLOSE_WRITE: File /home/user/temp/notes
1035 Listening for events stopped.
1038 .SS Program source: fanotify_example.c
1041 #define _GNU_SOURCE /* Needed to get O_LARGEFILE definition */
1048 #include <sys/fanotify.h>
1051 /* Read all available fanotify events from the file descriptor \[aq]fd\[aq]. */
1054 handle_events(int fd)
1056 const struct fanotify_event_metadata *metadata;
1057 struct fanotify_event_metadata buf[200];
1059 char path[PATH_MAX];
1061 char procfd_path[PATH_MAX];
1062 struct fanotify_response response;
1064 /* Loop while events can be read from fanotify file descriptor. */
1068 /* Read some events. */
1070 len = read(fd, buf, sizeof(buf));
1071 if (len == \-1 && errno != EAGAIN) {
1076 /* Check if end of available data reached. */
1081 /* Point to the first event in the buffer. */
1085 /* Loop over all events in the buffer. */
1087 while (FAN_EVENT_OK(metadata, len)) {
1089 /* Check that run\-time and compile\-time structures match. */
1091 if (metadata\->vers != FANOTIFY_METADATA_VERSION) {
1093 "Mismatch of fanotify metadata version.\[rs]n");
1097 /* metadata\->fd contains either FAN_NOFD, indicating a
1098 queue overflow, or a file descriptor (a nonnegative
1099 integer). Here, we simply ignore queue overflow. */
1101 if (metadata\->fd >= 0) {
1103 /* Handle open permission event. */
1105 if (metadata\->mask & FAN_OPEN_PERM) {
1106 printf("FAN_OPEN_PERM: ");
1108 /* Allow file to be opened. */
1110 response.fd = metadata\->fd;
1111 response.response = FAN_ALLOW;
1112 write(fd, &response, sizeof(response));
1115 /* Handle closing of writable file event. */
1117 if (metadata\->mask & FAN_CLOSE_WRITE)
1118 printf("FAN_CLOSE_WRITE: ");
1120 /* Retrieve and print pathname of the accessed file. */
1122 snprintf(procfd_path, sizeof(procfd_path),
1123 "/proc/self/fd/%d", metadata\->fd);
1124 path_len = readlink(procfd_path, path,
1126 if (path_len == \-1) {
1131 path[path_len] = \[aq]\[rs]0\[aq];
1132 printf("File %s\[rs]n", path);
1134 /* Close the file descriptor of the event. */
1136 close(metadata\->fd);
1139 /* Advance to next event. */
1141 metadata = FAN_EVENT_NEXT(metadata, len);
1147 main(int argc, char *argv[])
1152 struct pollfd fds[2];
1154 /* Check mount point is supplied. */
1157 fprintf(stderr, "Usage: %s MOUNT\[rs]n", argv[0]);
1161 printf("Press enter key to terminate.\[rs]n");
1163 /* Create the file descriptor for accessing the fanotify API. */
1165 fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
1166 O_RDONLY | O_LARGEFILE);
1168 perror("fanotify_init");
1172 /* Mark the mount for:
1173 \- permission events before opening files
1174 \- notification events after closing a write\-enabled
1177 if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
1178 FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,
1180 perror("fanotify_mark");
1184 /* Prepare for polling. */
1188 fds[0].fd = STDIN_FILENO; /* Console input */
1189 fds[0].events = POLLIN;
1191 fds[1].fd = fd; /* Fanotify input */
1192 fds[1].events = POLLIN;
1194 /* This is the loop to wait for incoming events. */
1196 printf("Listening for events.\[rs]n");
1199 poll_num = poll(fds, nfds, \-1);
1200 if (poll_num == \-1) {
1201 if (errno == EINTR) /* Interrupted by a signal */
1202 continue; /* Restart poll() */
1204 perror("poll"); /* Unexpected error */
1209 if (fds[0].revents & POLLIN) {
1211 /* Console input is available: empty stdin and quit. */
1213 while (read(STDIN_FILENO, &buf, 1) > 0 && buf != \[aq]\[rs]n\[aq])
1218 if (fds[1].revents & POLLIN) {
1220 /* Fanotify events are available. */
1227 printf("Listening for events stopped.\[rs]n");
1232 .SS Example program: fanotify_fid.c
1233 The second program is an example of fanotify being used with a group that
1234 identifies objects by file handles.
1235 The program marks the filesystem object that is passed as
1236 a command-line argument
1237 and waits until an event of type
1240 The event mask indicates which type of filesystem object\[em]either
1241 a file or a directory\[em]was created.
1242 Once all events have been read from the buffer and processed accordingly,
1243 the program simply terminates.
1245 The following shell sessions show two different invocations of
1246 this program, with different actions performed on a watched object.
1248 The first session shows a mark being placed on
1250 This is followed by the creation of a regular file,
1251 .IR /home/user/testfile.txt .
1254 event being generated and reported against the file's parent watched
1255 directory object and with the created file name.
1256 Program execution ends once all events captured within the buffer have
1261 # \fB./fanotify_fid /home/user\fP
1262 Listening for events.
1263 FAN_CREATE (file created):
1264 Directory /home/user has been modified.
1265 Entry \[aq]testfile.txt\[aq] is not a subdirectory.
1266 All events processed successfully. Program exiting.
1268 $ \fBtouch /home/user/testfile.txt\fP # In another terminal
1272 The second session shows a mark being placed on
1274 This is followed by the creation of a directory,
1275 .IR /home/user/testdir .
1276 This specific action results in a
1278 event being generated and is reported with the
1280 flag set and with the created directory name.
1284 # \fB./fanotify_fid /home/user\fP
1285 Listening for events.
1286 FAN_CREATE | FAN_ONDIR (subdirectory created):
1287 Directory /home/user has been modified.
1288 Entry \[aq]testdir\[aq] is a subdirectory.
1289 All events processed successfully. Program exiting.
1291 $ \fBmkdir \-p /home/user/testdir\fP # In another terminal
1294 .SS Program source: fanotify_fid.c
1303 #include <sys/types.h>
1304 #include <sys/stat.h>
1305 #include <sys/fanotify.h>
1308 #define BUF_SIZE 256
1311 main(int argc, char *argv[])
1313 int fd, ret, event_fd, mount_fd;
1314 ssize_t len, path_len;
1315 char path[PATH_MAX];
1316 char procfd_path[PATH_MAX];
1317 char events_buf[BUF_SIZE];
1318 struct file_handle *file_handle;
1319 struct fanotify_event_metadata *metadata;
1320 struct fanotify_event_info_fid *fid;
1321 const char *file_name;
1325 fprintf(stderr, "Invalid number of command line arguments.\[rs]n");
1329 mount_fd = open(argv[1], O_DIRECTORY | O_RDONLY);
1330 if (mount_fd == \-1) {
1335 /* Create an fanotify file descriptor with FAN_REPORT_DFID_NAME as
1336 a flag so that program can receive fid events with directory
1339 fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME, 0);
1341 perror("fanotify_init");
1345 /* Place a mark on the filesystem object supplied in argv[1]. */
1347 ret = fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_ONLYDIR,
1348 FAN_CREATE | FAN_ONDIR,
1351 perror("fanotify_mark");
1355 printf("Listening for events.\[rs]n");
1357 /* Read events from the event queue into a buffer. */
1359 len = read(fd, events_buf, sizeof(events_buf));
1360 if (len == \-1 && errno != EAGAIN) {
1365 /* Process all events within the buffer. */
1367 for (metadata = (struct fanotify_event_metadata *) events_buf;
1368 FAN_EVENT_OK(metadata, len);
1369 metadata = FAN_EVENT_NEXT(metadata, len)) {
1370 fid = (struct fanotify_event_info_fid *) (metadata + 1);
1371 file_handle = (struct file_handle *) fid\->handle;
1373 /* Ensure that the event info is of the correct type. */
1375 if (fid\->hdr.info_type == FAN_EVENT_INFO_TYPE_FID ||
1376 fid\->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID) {
1378 } else if (fid\->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID_NAME) {
1379 file_name = file_handle\->f_handle +
1380 file_handle\->handle_bytes;
1382 fprintf(stderr, "Received unexpected event info type.\[rs]n");
1386 if (metadata\->mask == FAN_CREATE)
1387 printf("FAN_CREATE (file created):\[rs]n");
1389 if (metadata\->mask == (FAN_CREATE | FAN_ONDIR))
1390 printf("FAN_CREATE | FAN_ONDIR (subdirectory created):\[rs]n");
1392 /* metadata\->fd is set to FAN_NOFD when the group identifies
1393 objects by file handles. To obtain a file descriptor for
1394 the file object corresponding to an event you can use the
1395 struct file_handle that\[aq]s provided within the
1396 fanotify_event_info_fid in conjunction with the
1397 open_by_handle_at(2) system call. A check for ESTALE is
1398 done to accommodate for the situation where the file handle
1399 for the object was deleted prior to this system call. */
1401 event_fd = open_by_handle_at(mount_fd, file_handle, O_RDONLY);
1402 if (event_fd == \-1) {
1403 if (errno == ESTALE) {
1404 printf("File handle is no longer valid. "
1405 "File has been deleted\[rs]n");
1408 perror("open_by_handle_at");
1413 snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d",
1416 /* Retrieve and print the path of the modified dentry. */
1418 path_len = readlink(procfd_path, path, sizeof(path) \- 1);
1419 if (path_len == \-1) {
1424 path[path_len] = \[aq]\[rs]0\[aq];
1425 printf("\[rs]tDirectory \[aq]%s\[aq] has been modified.\[rs]n", path);
1428 ret = fstatat(event_fd, file_name, &sb, 0);
1430 if (errno != ENOENT) {
1434 printf("\[rs]tEntry \[aq]%s\[aq] does not exist.\[rs]n", file_name);
1435 } else if ((sb.st_mode & S_IFMT) == S_IFDIR) {
1436 printf("\[rs]tEntry \[aq]%s\[aq] is a subdirectory.\[rs]n", file_name);
1438 printf("\[rs]tEntry \[aq]%s\[aq] is not a subdirectory.\[rs]n",
1443 /* Close associated file descriptor for this event. */
1448 printf("All events processed successfully. Program exiting.\[rs]n");
1454 .BR fanotify_init (2),
1455 .BR fanotify_mark (2),