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 2021-08-27 "Linux man-pages (unreleased)" "Linux Programmer's Manual"
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 file_handle[0];
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 is a variable length structure of type struct file_handle.
581 It is an opaque handle that corresponds to a specified object on a
582 filesystem as returned by
583 .BR name_to_handle_at (2).
584 It can be used to uniquely identify a file on a filesystem and can be
585 passed as an argument to
586 .BR open_by_handle_at (2).
590 .BR FAN_EVENT_INFO_TYPE_DFID_NAME ,
591 the file handle is followed by a null terminated string that identifies the
592 created/deleted/moved directory entry name.
593 For other events such as
596 .BR FAN_DELETE_SELF ,
602 .BR FAN_EVENT_INFO_TYPE_FID ,
605 identifies the object correlated to the event.
609 .BR FAN_EVENT_INFO_TYPE_DFID ,
612 identifies the directory object correlated to the event or the parent directory
613 of a non-directory object correlated to the event.
617 .BR FAN_EVENT_INFO_TYPE_DFID_NAME ,
620 identifies the same directory object that would be reported with
621 .B FAN_EVENT_INFO_TYPE_DFID
622 and the file handle is followed by a null terminated string that identifies the
623 name of a directory entry in that directory, or '.' to identify the directory
627 .I fanotify_event_info_pidfd
628 structure are as follows:
631 This is a structure of type
632 .IR fanotify_event_info_header .
633 When an fanotify group is initialized using
634 .BR FAN_REPORT_PIDFD ,
638 .I fanotify_event_info_header
640 .BR FAN_EVENT_INFO_TYPE_PIDFD .
643 This is a process file descriptor that refers to
644 the process responsible for generating the event.
645 The returned process file descriptor is no different from
646 one which could be obtained manually if
649 .IR fanotify_event_metadata.pid .
650 In the instance that an error is encountered during pidfd creation,
651 one of two possible error types represented by
652 a negative integer value may be returned in this
656 the process responsible for generating the event
657 has terminated prior to
658 the event listener being able to
659 read events from the notification queue,
662 The pidfd creation for an event is only performed at the time the
663 events are read from the notification queue.
664 All other possible pidfd creation failures are represented by
666 Once the event listener has dealt with an event
667 and the pidfd is no longer required,
668 the pidfd should be closed via
672 .I fanotify_event_info_error
673 structure are as follows:
676 This is a structure of type
677 .IR fanotify_event_info_header .
681 .BR FAN_EVENT_INFO_TYPE_ERROR .
684 Identifies the type of error that occurred.
687 This is a counter of the number of errors suppressed
688 since the last error was read.
690 The following macros are provided to iterate over a buffer containing
691 fanotify event metadata returned by a
693 from an fanotify file descriptor:
695 .B FAN_EVENT_OK(meta, len)
696 This macro checks the remaining length
700 against the length of the metadata structure and the
702 field of the first metadata structure in the buffer.
704 .B FAN_EVENT_NEXT(meta, len)
705 This macro uses the length indicated in the
707 field of the metadata structure pointed to by
709 to calculate the address of the next metadata structure that follows
712 is the number of bytes of metadata that currently remain in the buffer.
713 The macro returns a pointer to the next metadata structure that follows
717 by the number of bytes in the metadata structure that
718 has been skipped over (i.e., it subtracts
723 In addition, there is:
725 .B FAN_EVENT_METADATA_LEN
726 This macro returns the size (in bytes) of the structure
727 .IR fanotify_event_metadata .
728 This is the minimum size (and currently the only size) of any event metadata.
730 .SS Monitoring an fanotify file descriptor for events
731 When an fanotify event occurs, the fanotify file descriptor indicates as
732 readable when passed to
737 .SS Dealing with permission events
738 For permission events, the application must
740 a structure of the following form to the
741 fanotify file descriptor:
745 struct fanotify_response {
752 The fields of this structure are as follows:
755 This is the file descriptor from the structure
756 .IR fanotify_event_metadata .
759 This field indicates whether or not the permission is to be granted.
760 Its value must be either
762 to allow the file operation or
764 to deny the file operation.
766 If access is denied, the requesting application call will receive an
769 Additionally, if the notification group has been created with the
773 flag can be set in the
776 In that case, the audit subsystem will log information about the access
777 decision to the audit logs.
779 .SS Monitoring filesystems for errors
782 event is stored per filesystem at once.
783 Extra error messages are suppressed and accounted for in the
785 field of the existing
788 but details about the errors are lost.
795 but not all kinds of error types are reported by all filesystems.
797 Errors not directly related to a file (i.e. super block corruption)
798 are reported with an invalid
800 For these errors, the
806 and the handle buffer size set to
809 .SS Closing the fanotify file descriptor
810 When all file descriptors referring to the fanotify notification group are
811 closed, the fanotify group is released and its resources
812 are freed for reuse by the kernel.
815 outstanding permission events will be set to allowed.
818 .I /proc/[pid]/fdinfo/[fd]
819 contains information about fanotify marks for file descriptor
828 .\" commit 5b8fea65d197f408bb00b251c70d842826d6b70b
829 the following interfaces can be used to control the amount of
830 kernel resources consumed by fanotify:
832 .I /proc/sys/fs/fanotify/max_queued_events
833 The value in this file is used when an application calls
834 .BR fanotify_init (2)
835 to set an upper limit on the number of events that can be
836 queued to the corresponding fanotify group.
837 Events in excess of this limit are dropped, but an
839 event is always generated.
840 Prior to Linux kernel 5.13,
841 .\" commit 5b8fea65d197f408bb00b251c70d842826d6b70b
842 the hardcoded limit was 16384 events.
844 .I /proc/sys/fs/fanotify/max_user_group
845 This specifies an upper limit on the number of fanotify groups
846 that can be created per real user ID.
847 Prior to Linux kernel 5.13,
848 .\" commit 5b8fea65d197f408bb00b251c70d842826d6b70b
849 the hardcoded limit was 128 groups per user.
851 .I /proc/sys/fs/fanotify/max_user_marks
852 This specifies an upper limit on the number of fanotify marks
853 that can be created per real user ID.
854 Prior to Linux kernel 5.13,
855 .\" commit 5b8fea65d197f408bb00b251c70d842826d6b70b
856 the hardcoded limit was 8192 marks per group (not per user).
858 In addition to the usual errors for
860 the following errors can occur when reading from the
861 fanotify file descriptor:
864 The buffer is too small to hold the event.
867 The per-process limit on the number of open files has been reached.
868 See the description of
874 The system-wide limit on the total number of open files has been reached.
876 .I /proc/sys/fs/file\-max
881 This error is returned by
889 argument when calling
890 .BR fanotify_init (2)
891 and an event occurred for a monitored file that is currently being executed.
893 In addition to the usual errors for
895 the following errors can occur when writing to the fanotify file descriptor:
898 Fanotify access permissions are not enabled in the kernel configuration
901 in the response structure is not valid.
906 in the response structure is not valid.
907 This may occur when a response for the permission event has already been
910 The fanotify API was introduced in version 2.6.36 of the Linux kernel and
911 enabled in version 2.6.37.
912 Fdinfo support was added in version 3.8.
914 The fanotify API is Linux-specific.
916 The fanotify API is available only if the kernel was built with the
918 configuration option enabled.
919 In addition, fanotify permission handling is available only if the
920 .B CONFIG_FANOTIFY_ACCESS_PERMISSIONS
921 configuration option is enabled.
922 .SS Limitations and caveats
923 Fanotify reports only events that a user-space program triggers through the
926 it does not catch remote events that occur on network filesystems.
928 The fanotify API does not report file accesses and modifications that
935 Events for directories are created only if the directory itself is opened,
937 Adding, removing, or changing children of a marked directory does not create
938 events for the monitored directory itself.
940 Fanotify monitoring of directories is not recursive:
941 to monitor subdirectories under a directory,
942 additional marks must be created.
945 event can be used for detecting when a subdirectory has been created under
947 An additional mark must then be set on the newly created subdirectory.
948 This approach is racy, because it can lose events that occurred inside the
949 newly created subdirectory, before a mark is added on that subdirectory.
950 Monitoring mounts offers the capability to monitor a whole directory tree
951 in a race-free manner.
952 Monitoring filesystems offers the capability to monitor changes made from
953 any mount of a filesystem instance in a race-free manner.
955 The event queue can overflow.
956 In this case, events are lost.
960 did not generate fanotify events.
962 .\" commit 820c12d5d6c0890bc93dd63893924a13041fdc35
970 the following bugs exist:
972 On Linux, a filesystem object may be accessible through multiple paths,
973 for example, a part of a filesystem may be remounted using the
977 A listener that marked a mount will be notified only of events that were
978 triggered for a filesystem object using the same mount.
979 Any other event will pass unnoticed.
981 .\" FIXME . A patch was proposed.
982 When an event is generated,
983 no check is made to see whether the user ID of the
984 receiving process has authorization to read or write the file
985 before passing a file descriptor for that file.
986 This poses a security risk, when the
988 capability is set for programs executed by unprivileged users.
992 processes multiple events from the fanotify queue and an error occurs,
993 the return value will be the total length of the events successfully
994 copied to the user-space buffer before the error occurred.
995 The return value will not be \-1, and
998 Thus, the reading application has no way to detect the error.
1000 The two example programs below demonstrate the usage of the fanotify API.
1001 .SS Example program: fanotify_example.c
1002 The first program is an example of fanotify being
1003 used with its event object information passed in the form of a file
1005 The program marks the mount passed as a command-line argument and
1006 waits for events of type
1009 .BR FAN_CLOSE_WRITE .
1010 When a permission event occurs, a
1014 The following shell session shows an example of
1015 running this program.
1016 This session involved editing the file
1017 .IR /home/user/temp/notes .
1018 Before the file was opened, a
1021 After the file was closed, a
1024 Execution of the program ends when the user presses the ENTER key.
1028 # \fB./fanotify_example /home\fP
1029 Press enter key to terminate.
1030 Listening for events.
1031 FAN_OPEN_PERM: File /home/user/temp/notes
1032 FAN_CLOSE_WRITE: File /home/user/temp/notes
1034 Listening for events stopped.
1037 .SS Program source: fanotify_example.c
1040 #define _GNU_SOURCE /* Needed to get O_LARGEFILE definition */
1047 #include <sys/fanotify.h>
1050 /* Read all available fanotify events from the file descriptor \(aqfd\(aq. */
1053 handle_events(int fd)
1055 const struct fanotify_event_metadata *metadata;
1056 struct fanotify_event_metadata buf[200];
1058 char path[PATH_MAX];
1060 char procfd_path[PATH_MAX];
1061 struct fanotify_response response;
1063 /* Loop while events can be read from fanotify file descriptor. */
1067 /* Read some events. */
1069 len = read(fd, buf, sizeof(buf));
1070 if (len == \-1 && errno != EAGAIN) {
1075 /* Check if end of available data reached. */
1080 /* Point to the first event in the buffer. */
1084 /* Loop over all events in the buffer. */
1086 while (FAN_EVENT_OK(metadata, len)) {
1088 /* Check that run\-time and compile\-time structures match. */
1090 if (metadata\->vers != FANOTIFY_METADATA_VERSION) {
1092 "Mismatch of fanotify metadata version.\en");
1096 /* metadata\->fd contains either FAN_NOFD, indicating a
1097 queue overflow, or a file descriptor (a nonnegative
1098 integer). Here, we simply ignore queue overflow. */
1100 if (metadata\->fd >= 0) {
1102 /* Handle open permission event. */
1104 if (metadata\->mask & FAN_OPEN_PERM) {
1105 printf("FAN_OPEN_PERM: ");
1107 /* Allow file to be opened. */
1109 response.fd = metadata\->fd;
1110 response.response = FAN_ALLOW;
1111 write(fd, &response, sizeof(response));
1114 /* Handle closing of writable file event. */
1116 if (metadata\->mask & FAN_CLOSE_WRITE)
1117 printf("FAN_CLOSE_WRITE: ");
1119 /* Retrieve and print pathname of the accessed file. */
1121 snprintf(procfd_path, sizeof(procfd_path),
1122 "/proc/self/fd/%d", metadata\->fd);
1123 path_len = readlink(procfd_path, path,
1125 if (path_len == \-1) {
1130 path[path_len] = \(aq\e0\(aq;
1131 printf("File %s\en", path);
1133 /* Close the file descriptor of the event. */
1135 close(metadata\->fd);
1138 /* Advance to next event. */
1140 metadata = FAN_EVENT_NEXT(metadata, len);
1146 main(int argc, char *argv[])
1151 struct pollfd fds[2];
1153 /* Check mount point is supplied. */
1156 fprintf(stderr, "Usage: %s MOUNT\en", argv[0]);
1160 printf("Press enter key to terminate.\en");
1162 /* Create the file descriptor for accessing the fanotify API. */
1164 fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
1165 O_RDONLY | O_LARGEFILE);
1167 perror("fanotify_init");
1171 /* Mark the mount for:
1172 \- permission events before opening files
1173 \- notification events after closing a write\-enabled
1176 if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
1177 FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,
1179 perror("fanotify_mark");
1183 /* Prepare for polling. */
1187 fds[0].fd = STDIN_FILENO; /* Console input */
1188 fds[0].events = POLLIN;
1190 fds[1].fd = fd; /* Fanotify input */
1191 fds[1].events = POLLIN;
1193 /* This is the loop to wait for incoming events. */
1195 printf("Listening for events.\en");
1198 poll_num = poll(fds, nfds, \-1);
1199 if (poll_num == \-1) {
1200 if (errno == EINTR) /* Interrupted by a signal */
1201 continue; /* Restart poll() */
1203 perror("poll"); /* Unexpected error */
1208 if (fds[0].revents & POLLIN) {
1210 /* Console input is available: empty stdin and quit. */
1212 while (read(STDIN_FILENO, &buf, 1) > 0 && buf != \(aq\en\(aq)
1217 if (fds[1].revents & POLLIN) {
1219 /* Fanotify events are available. */
1226 printf("Listening for events stopped.\en");
1231 .SS Example program: fanotify_fid.c
1232 The second program is an example of fanotify being used with a group that
1233 identifies objects by file handles.
1234 The program marks the filesystem object that is passed as
1235 a command-line argument
1236 and waits until an event of type
1239 The event mask indicates which type of filesystem object\(emeither
1240 a file or a directory\(emwas created.
1241 Once all events have been read from the buffer and processed accordingly,
1242 the program simply terminates.
1244 The following shell sessions show two different invocations of
1245 this program, with different actions performed on a watched object.
1247 The first session shows a mark being placed on
1249 This is followed by the creation of a regular file,
1250 .IR /home/user/testfile.txt .
1253 event being generated and reported against the file's parent watched
1254 directory object and with the created file name.
1255 Program execution ends once all events captured within the buffer have
1260 # \fB./fanotify_fid /home/user\fP
1261 Listening for events.
1262 FAN_CREATE (file created):
1263 Directory /home/user has been modified.
1264 Entry \(aqtestfile.txt\(aq is not a subdirectory.
1265 All events processed successfully. Program exiting.
1267 $ \fBtouch /home/user/testfile.txt\fP # In another terminal
1271 The second session shows a mark being placed on
1273 This is followed by the creation of a directory,
1274 .IR /home/user/testdir .
1275 This specific action results in a
1277 event being generated and is reported with the
1279 flag set and with the created directory name.
1283 # \fB./fanotify_fid /home/user\fP
1284 Listening for events.
1285 FAN_CREATE | FAN_ONDIR (subdirectory created):
1286 Directory /home/user has been modified.
1287 Entry \(aqtestdir\(aq is a subdirectory.
1288 All events processed successfully. Program exiting.
1290 $ \fBmkdir \-p /home/user/testdir\fP # In another terminal
1293 .SS Program source: fanotify_fid.c
1302 #include <sys/types.h>
1303 #include <sys/stat.h>
1304 #include <sys/fanotify.h>
1307 #define BUF_SIZE 256
1310 main(int argc, char *argv[])
1312 int fd, ret, event_fd, mount_fd;
1313 ssize_t len, path_len;
1314 char path[PATH_MAX];
1315 char procfd_path[PATH_MAX];
1316 char events_buf[BUF_SIZE];
1317 struct file_handle *file_handle;
1318 struct fanotify_event_metadata *metadata;
1319 struct fanotify_event_info_fid *fid;
1320 const char *file_name;
1324 fprintf(stderr, "Invalid number of command line arguments.\en");
1328 mount_fd = open(argv[1], O_DIRECTORY | O_RDONLY);
1329 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.\en");
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.\en");
1386 if (metadata\->mask == FAN_CREATE)
1387 printf("FAN_CREATE (file created):\en");
1389 if (metadata\->mask == (FAN_CREATE | FAN_ONDIR))
1390 printf("FAN_CREATE | FAN_ONDIR (subdirectory created):\en");
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\(aqs 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\en");
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\e0\(aq;
1425 printf("\etDirectory \(aq%s\(aq has been modified.\en", path);
1428 ret = fstatat(event_fd, file_name, &sb, 0);
1430 if (errno != ENOENT) {
1434 printf("\etEntry \(aq%s\(aq does not exist.\en", file_name);
1435 } else if ((sb.st_mode & S_IFMT) == S_IFDIR) {
1436 printf("\etEntry \(aq%s\(aq is a subdirectory.\en", file_name);
1438 printf("\etEntry \(aq%s\(aq is not a subdirectory.\en",
1443 /* Close associated file descriptor for this event. */
1448 printf("All events processed successfully. Program exiting.\en");
1454 .BR fanotify_init (2),
1455 .BR fanotify_mark (2),