]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man7/fanotify.7
standards.7: Add some more standards
[thirdparty/man-pages.git] / man7 / fanotify.7
CommitLineData
597aaea2 1.\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk@gmx.de>
89613d50 2.\" and Copyright (C) 2014, Michael Kerrisk <mtk.manpages@gmail.com>
597aaea2
HS
3.\"
4.\" %%%LICENSE_START(VERBATIM)
5.\" Permission is granted to make and distribute verbatim copies of this
6.\" manual provided the copyright notice and this permission notice are
7.\" preserved on all copies.
8.\"
9.\" Permission is granted to copy and distribute modified versions of
10.\" this manual under the conditions for verbatim copying, provided that
11.\" the entire resulting derived work is distributed under the terms of
12.\" a permission notice identical to this one.
13.\"
14.\" Since the Linux kernel and libraries are constantly changing, this
15.\" manual page may be incorrect or out-of-date. The author(s) assume.
16.\" no responsibility for errors or omissions, or for damages resulting.
17.\" from the use of the information contained herein. The author(s) may.
18.\" not have taken the same level of care in the production of this.
19.\" manual, which is licensed free of charge, as they might when working.
20.\" professionally.
21.\"
22.\" Formatted or processed versions of this manual, if unaccompanied by
23.\" the source, must acknowledge the copyright and authors of this work.
24.\" %%%LICENSE_END
63121bd4 25.TH FANOTIFY 7 2019-08-02 "Linux" "Linux Programmer's Manual"
597aaea2
HS
26.SH NAME
27fanotify \- monitoring filesystem events
28.SH DESCRIPTION
1b24e2ee
MK
29The fanotify API provides notification and interception of
30filesystem events.
597aaea2
HS
31Use cases include virus scanning and hierarchical storage management.
32Currently, only a limited set of events is supported.
7ea227bd 33In particular, there is no support for create, delete, and move events.
d9b086d6
MK
34(See
35.BR inotify (7)
36for details of an API that does notify those events.)
a721e8b2 37.PP
597aaea2
HS
38Additional capabilities compared to the
39.BR inotify (7)
4a57583f
MK
40API include the ability to monitor all of the objects
41in a mounted filesystem,
42the ability to make access permission decisions, and the
597aaea2 43possibility to read or modify files before access by other applications.
a721e8b2 44.PP
597aaea2
HS
45The following system calls are used with this API:
46.BR fanotify_init (2),
47.BR fanotify_mark (2),
597aaea2
HS
48.BR read (2),
49.BR write (2),
50and
51.BR close (2).
6c693f6d 52.SS fanotify_init(), fanotify_mark(), and notification groups
397ff1fd 53The
597aaea2 54.BR fanotify_init (2)
397ff1fd
MK
55system call creates and initializes an fanotify notification group
56and returns a file descriptor referring to it.
597aaea2 57.PP
7ea227bd 58An fanotify notification group is a kernel-internal object that holds
953d1e07 59a list of files, directories, filesystems, and mount points for which
b2f8214d 60events shall be created.
597aaea2 61.PP
7ea227bd
MK
62For each entry in an fanotify notification group, two bit masks exist: the
63.I mark
64mask and the
65.I ignore
66mask.
67The mark mask defines file activities for which an event shall be created.
68The ignore mask defines activities for which no event shall be generated.
953d1e07 69Having these two types of masks permits a filesystem, mount point, or
b2f8214d
AG
70directory to be marked for receiving events, while at the same time
71ignoring events for specific objects under a mount point or directory.
597aaea2 72.PP
ffb30e75 73The
6c693f6d 74.BR fanotify_mark (2)
b2f8214d
AG
75system call adds a file, directory, filesystem or mount point to a
76notification group and specifies which events
6c693f6d
MK
77shall be reported (or ignored), or removes or modifies such an entry.
78.PP
597aaea2
HS
79A possible usage of the ignore mask is for a file cache.
80Events of interest for a file cache are modification of a file and closing
81of the same.
82Hence, the cached directory or mount point is to be marked to receive these
83events.
1b24e2ee
MK
84After receiving the first event informing that a file has been modified,
85the corresponding cache entry will be invalidated.
86No further modification events for this file are of interest until the file
87is closed.
597aaea2 88Hence, the modify event can be added to the ignore mask.
5e443a5f 89Upon receiving the close event, the modify event can be removed from the
597aaea2
HS
90ignore mask and the file cache entry can be updated.
91.PP
1b24e2ee
MK
92The entries in the fanotify notification groups refer to files and
93directories via their inode number and to mounts via their mount ID.
7d3c593b 94If files or directories are renamed or moved within the same mount,
1b24e2ee 95the respective entries survive.
b2f8214d
AG
96If files or directories are deleted or moved to another mount or if
97filesystems or mounts are unmounted, the corresponding entries are deleted.
ad02dd1f 98.SS The event queue
77bba7b5 99As events occur on the filesystem objects monitored by a notification group,
c9120323
MK
100the fanotify system generates events that are collected in a queue.
101These events can then be read (using
102.BR read (2)
103or similar)
104from the fanotify file descriptor
105returned by
106.BR fanotify_init (2).
a721e8b2 107.PP
c9120323 108Two types of events are generated:
4a57583f
MK
109.I notification
110events and
111.I permission
112events.
c9120323
MK
113Notification events are merely informative
114and require no action to be taken by
0a4db6dc
MB
115the receiving application with the exception being that the file
116descriptor provided within a generic event must be closed.
817c8240 117The closing of file descriptors for each event applies only to
0a4db6dc
MB
118applications that have initialized fanotify without using
119.BR FAN_REPORT_FID
120(see below).
1b24e2ee
MK
121Permission events are requests to the receiving application to decide
122whether permission for a file access shall be granted.
597aaea2
HS
123For these events, the recipient must write a response which decides whether
124access is granted or not.
a721e8b2 125.PP
33022419
MK
126An event is removed from the event queue of the fanotify group
127when it has been read.
a6625006 128Permission events that have been read are kept in an internal list of the
33022419
MK
129fanotify group until either a permission decision has been taken by
130writing to the fanotify file descriptor or the fanotify file descriptor
131is closed.
ad02dd1f 132.SS Reading fanotify events
597aaea2
HS
133Calling
134.BR read (2)
135for the file descriptor returned by
136.BR fanotify_init (2)
137blocks (if the flag
138.B FAN_NONBLOCK
139is not specified in the call to
140.BR fanotify_init (2))
141until either a file event occurs or the call is interrupted by a signal
142(see
143.BR signal (7)).
a721e8b2 144.PP
f5230cf1 145The use of the
0a4db6dc 146.BR FAN_REPORT_FID
f5230cf1 147flag in
0a4db6dc 148.BR fanotify_init (2)
58ba48e4 149influences what data structures are returned to the event listener for each
f5230cf1 150event.
597aaea2 151After a successful
7ea227bd 152.BR read (2),
597aaea2 153the read buffer contains one or more of the following structures:
a721e8b2 154.PP
597aaea2 155.in +4n
b8302363 156.EX
597aaea2
HS
157struct fanotify_event_metadata {
158 __u32 event_len;
159 __u8 vers;
160 __u8 reserved;
161 __u16 metadata_len;
162 __aligned_u64 mask;
163 __s32 fd;
164 __s32 pid;
165};
b8302363 166.EE
597aaea2 167.in
f2ac23e7 168.PP
817c8240 169In the case where
0a4db6dc
MB
170.BR FAN_REPORT_FID
171is supplied as one of the flags to
172.BR fanotify_init (2),
173you should also expect to receive the structure detailed below following
174the generic
175.I fanotify_event_metadata
176structure within the read buffer:
177.PP
178.in +4n
179.EX
180struct fanotify_event_info_fid {
181 struct fanotify_event_info_header hdr;
182 __kernel_fsid_t fsid;
183 unsigned char file_handle[0];
184};
185.EE
186.in
187.PP
3253bbc3
MK
188For performance reasons, it is recommended to use a large
189buffer size (for example, 4096 bytes),
190so that multiple events can be retrieved by a single
191.BR read (2).
a721e8b2 192.PP
3253bbc3
MK
193The return value of
194.BR read (2)
195is the number of bytes placed in the buffer,
f96adfdc 196or \-1 in case of an error (but see BUGS).
a721e8b2 197.PP
4a57583f
MK
198The fields of the
199.I fanotify_event_metadata
200structure are as follows:
9d76d630 201.TP
597aaea2 202.I event_len
1b24e2ee
MK
203This is the length of the data for the current event and the offset
204to the next event in the buffer.
0a4db6dc
MB
205Without
206.BR FAN_REPORT_FID ,
207the value of
597aaea2
HS
208.I event_len
209is always
210.BR FAN_EVENT_METADATA_LEN .
0a4db6dc
MB
211With
212.BR FAN_REPORT_FID ,
213.I event_len
214also includes the variable length file identifier.
597aaea2
HS
215.TP
216.I vers
6d8c5d01 217This field holds a version number for the structure.
597aaea2
HS
218It must be compared to
219.B FANOTIFY_METADATA_VERSION
29c0586f 220to verify that the structures returned at run time match
6d8c5d01 221the structures defined at compile time.
597aaea2
HS
222In case of a mismatch, the application should abandon trying to use the
223fanotify file descriptor.
224.TP
225.I reserved
226This field is not used.
227.TP
228.I metadata_len
229This is the length of the structure.
1b24e2ee
MK
230The field was introduced to facilitate the implementation of
231optional headers per event type.
597aaea2
HS
232No such optional headers exist in the current implementation.
233.TP
234.I mask
4a57583f 235This is a bit mask describing the event (see below).
597aaea2
HS
236.TP
237.I fd
238This is an open file descriptor for the object being accessed, or
239.B FAN_NOFD
240if a queue overflow occurred.
0a4db6dc
MB
241If the fanotify file descriptor has been initialized using
242.BR FAN_REPORT_FID ,
243applications should expect this value to be set to
244.B FAN_NOFD
245for each event that is received.
1b24e2ee
MK
246The file descriptor can be used to access the contents
247of the monitored file or directory.
4a57583f
MK
248The reading application is responsible for closing this file descriptor.
249.IP
a4cd12a9 250When calling
ce87be97 251.BR fanotify_init (2),
a4cd12a9
MK
252the caller may specify (via the
253.I event_f_flags
254argument) various file status flags that are to be set
255on the open file description that corresponds to this file descriptor.
256In addition, the (kernel-internal)
597aaea2 257.B FMODE_NONOTIFY
a4cd12a9 258file status flag is set on the open file description.
597aaea2
HS
259This flag suppresses fanotify event generation.
260Hence, when the receiver of the fanotify event accesses the notified file or
261directory using this file descriptor, no additional events will be created.
597aaea2
HS
262.TP
263.I pid
ebfb6fee 264If flag
265.B FAN_REPORT_TID
266was set in
267.BR fanotify_init (2),
268this is the TID of the thread that caused the event.
269Otherwise, this the PID of the process that caused the event.
270.PP
1b24e2ee
MK
271A program listening to fanotify events can compare this PID
272to the PID returned by
597aaea2 273.BR getpid (2),
1b24e2ee 274to determine whether the event is caused by the listener itself,
4a57583f 275or is due to a file access by another process.
597aaea2
HS
276.PP
277The bit mask in
278.I mask
4a57583f 279indicates which events have occurred for a single filesystem object.
29325644 280Multiple bits may be set in this mask,
77bba7b5 281if more than one event occurred for the monitored filesystem object.
75c3e3bd
MK
282In particular,
283consecutive events for the same filesystem object and originating from the
284same process may be merged into a single event, with the exception that two
285permission events are never merged into one queue entry.
286.PP
29325644
MK
287The bits that may appear in
288.I mask
289are as follows:
597aaea2
HS
290.TP
291.B FAN_ACCESS
292A file or a directory (but see BUGS) was accessed (read).
293.TP
294.B FAN_OPEN
295A file or a directory was opened.
296.TP
fc37d2f1
MB
297.B FAN_OPEN_EXEC
298A file was opened with the intent to be executed.
fd1eb8a7 299See NOTES in
fc37d2f1
MB
300.BR fanotify_mark (2)
301for additional details.
302.TP
0a4db6dc
MB
303.B FAN_ATTRIB
304A file or directory metadata was changed.
305.TP
306.B FAN_CREATE
307A child file or directory was created in a watched parent.
308.TP
309.B FAN_DELETE
310A child file or directory was deleted in a watched parent.
311.TP
312.B FAN_DELETE_SELF
313A watched file or directory was deleted.
314.TP
315.B FAN_MOVED_FROM
316A file or directory has been moved from a watched parent directory.
317.TP
318.B FAN_MOVED_TO
319A file or directory has been moved to a watched parent directory.
320.TP
321.B FAN_MOVE_SELF
322A watched file or directory was moved.
323.TP
597aaea2
HS
324.B FAN_MODIFY
325A file was modified.
326.TP
a93e5c95
AG
327.B FAN_DIR_MODIFY
328A directory entry was created, deleted or moved.
329.TP
597aaea2
HS
330.B FAN_CLOSE_WRITE
331A file that was opened for writing
332.RB ( O_WRONLY
333or
334.BR O_RDWR )
335was closed.
336.TP
337.B FAN_CLOSE_NOWRITE
02a18e0f 338A file or directory that was opened read-only
597aaea2 339.RB ( O_RDONLY )
02a18e0f 340was closed.
597aaea2
HS
341.TP
342.B FAN_Q_OVERFLOW
343The event queue exceeded the limit of 16384 entries.
4a57583f
MK
344This limit can be overridden by specifying the
345.BR FAN_UNLIMITED_QUEUE
346flag when calling
347.BR fanotify_init (2).
597aaea2
HS
348.TP
349.B FAN_ACCESS_PERM
350An application wants to read a file or directory, for example using
351.BR read (2)
352or
353.BR readdir (2).
4a57583f
MK
354The reader must write a response (as described below)
355that determines whether the permission to
597aaea2
HS
356access the filesystem object shall be granted.
357.TP
358.B FAN_OPEN_PERM
359An application wants to open a file or directory.
360The reader must write a response that determines whether the permission to
361open the filesystem object shall be granted.
fc37d2f1
MB
362.TP
363.B FAN_OPEN_EXEC_PERM
364An application wants to open a file for execution.
365The reader must write a response that determines whether the permission to
366open the filesystem object for execution shall be granted.
fd1eb8a7 367See NOTES in
fc37d2f1
MB
368.BR fanotify_mark (2)
369for additional details.
597aaea2
HS
370.PP
371To check for any close event, the following bit mask may be used:
372.TP
373.B FAN_CLOSE
f897ec11 374A file was closed.
4a57583f 375This is a synonym for:
a721e8b2 376.IP
f897ec11 377 FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE
597aaea2 378.PP
0a4db6dc
MB
379To check for any move event, the following bit mask may be used:
380.TP
381.B FAN_MOVE
382A file or directory was moved.
383This is a synonym for:
384.IP
385 FAN_MOVED_FROM | FAN_MOVED_TO
386.PP
387The fields of the
388.I fanotify_event_info_fid
389structure are as follows:
390.TP
391.I hdr
392This is a structure of type
393.IR fanotify_event_info_header .
394It is a generic header that contains information used to describe
395additional information attached to the event.
396For example, when an fanotify file descriptor is created using
817c8240 397.BR FAN_REPORT_FID ,
0a4db6dc
MB
398the
399.I info_type
400field of this header is set to
a93e5c95
AG
401.BR FAN_EVENT_INFO_TYPE_FID
402or
403.BR FAN_EVENT_INFO_TYPE_DFID_NAME .
404Event listeners can use this field to check what additional information
405is received for an event.
0a4db6dc
MB
406Additionally, the
407.I fanotify_event_info_header
408also contains a
409.I len
410field.
411In the current implementation, the value of
412.I len
5ff63f51 413is always (event_len \- FAN_EVENT_METADATA_LEN).
0a4db6dc
MB
414.TP
415.I fsid
416This is a unique identifier of the filesystem containing the object
417associated with the event.
418It is a structure of type
419.I __kernel_fsid_t
420and contains the same value as
421.I f_fsid
422when calling
423.BR statfs (2).
424.TP
425.I file_handle
426This is a variable length structure of type
427.IR file_handle .
428It is an opaque handle that corresponds to a specified object on a
429filesystem as returned by
817c8240 430.BR name_to_handle_at (2).
0a4db6dc
MB
431It can be used to uniquely identify a file on a filesystem and can be
432passed as an argument to
817c8240 433.BR open_by_handle_at (2).
0a4db6dc
MB
434Note that for directory entry events, such as
435.BR FAN_CREATE ,
436.BR FAN_DELETE ,
817c8240
MK
437and
438.BR FAN_MOVE ,
0a4db6dc
MB
439the
440.IR file_handle
441describes the modified directory and not the created/deleted/moved child
442object.
443The events
444.BR FAN_ATTRIB ,
817c8240 445.BR FAN_DELETE_SELF ,
0a4db6dc
MB
446and
447.BR FAN_MOVE_SELF
448will carry the
449.IR file_handle
450information for the child object if the child object is being watched.
a93e5c95
AG
451For the event
452.BR FAN_DIR_MODIFY ,
453the
454.I info_type
455field of this header is set to
456.BR FAN_EVENT_INFO_TYPE_DFID_NAME .
457The file handle describes the modified directory and a null terminated
458name of the modified entry follows directly after the file handle buffer.
0a4db6dc 459.PP
1b24e2ee 460The following macros are provided to iterate over a buffer containing
4a57583f 461fanotify event metadata returned by a
597aaea2 462.BR read (2)
4a57583f 463from an fanotify file descriptor:
597aaea2
HS
464.TP
465.B FAN_EVENT_OK(meta, len)
466This macro checks the remaining length
467.I len
468of the buffer
469.I meta
470against the length of the metadata structure and the
471.I event_len
472field of the first metadata structure in the buffer.
473.TP
474.B FAN_EVENT_NEXT(meta, len)
98f7d53c 475This macro uses the length indicated in the
597aaea2 476.I event_len
98f7d53c
MK
477field of the metadata structure pointed to by
478.IR meta
479to calculate the address of the next metadata structure that follows
480.IR meta .
481.I len
482is the number of bytes of metadata that currently remain in the buffer.
483The macro returns a pointer to the next metadata structure that follows
484.IR meta ,
485and reduces
486.I len
d721b5aa 487by the number of bytes in the metadata structure that
98f7d53c
MK
488has been skipped over (i.e., it subtracts
489.IR meta\->event_len
490from
491.IR len ).
3c36e635
HS
492.PP
493In addition, there is:
494.TP
495.B FAN_EVENT_METADATA_LEN
7c0f0ce0
MK
496This macro returns the size (in bytes) of the structure
497.IR fanotify_event_metadata .
3c36e635 498This is the minimum size (and currently the only size) of any event metadata.
98f7d53c 499.\"
488cdd81
MK
500.SS Monitoring an fanotify file descriptor for events
501When an fanotify event occurs, the fanotify file descriptor indicates as
502readable when passed to
503.BR epoll (7),
504.BR poll (2),
505or
506.BR select (2).
88145b29 507.SS Dealing with permission events
597aaea2
HS
508For permission events, the application must
509.BR write (2)
510a structure of the following form to the
d3471a46 511fanotify file descriptor:
a721e8b2 512.PP
597aaea2 513.in +4n
b8302363 514.EX
597aaea2
HS
515struct fanotify_response {
516 __s32 fd;
517 __u32 response;
518};
b8302363 519.EE
597aaea2 520.in
d7d24d40
MK
521.PP
522The fields of this structure are as follows:
9d76d630 523.TP
597aaea2
HS
524.I fd
525This is the file descriptor from the structure
526.IR fanotify_event_metadata .
527.TP
528.I response
529This field indicates whether or not the permission is to be granted.
530Its value must be either
531.B FAN_ALLOW
532to allow the file operation or
533.B FAN_DENY
534to deny the file operation.
535.PP
49894a5a
MK
536If access is denied, the requesting application call will receive an
537.BR EPERM
538error.
88145b29 539.SS Closing the fanotify file descriptor
be8ba5d8
MK
540.PP
541When all file descriptors referring to the fanotify notification group are
542closed, the fanotify group is released and its resources
543are freed for reuse by the kernel.
544Upon
545.BR close (2),
546outstanding permission events will be set to allowed.
c00ff2dc 547.SS /proc/[pid]/fdinfo
597aaea2 548The file
3d4433fe 549.I /proc/[pid]/fdinfo/[fd]
597aaea2
HS
550contains information about fanotify marks for file descriptor
551.I fd
552of process
553.IR pid .
75f8598a
MK
554See
555.BR proc (5)
597aaea2
HS
556for details.
557.SH ERRORS
558In addition to the usual errors for
559.BR read (2),
1b24e2ee
MK
560the following errors can occur when reading from the
561fanotify file descriptor:
597aaea2
HS
562.TP
563.B EINVAL
4a57583f 564The buffer is too small to hold the event.
597aaea2
HS
565.TP
566.B EMFILE
567The per-process limit on the number of open files has been reached.
568See the description of
569.B RLIMIT_NOFILE
570in
571.BR getrlimit (2).
572.TP
573.B ENFILE
e258766b 574The system-wide limit on the total number of open files has been reached.
597aaea2 575See
fa6d3b26 576.I /proc/sys/fs/file\-max
597aaea2
HS
577in
578.BR proc (5).
579.TP
580.B ETXTBSY
597aaea2 581This error is returned by
68bcc008 582.BR read (2)
597aaea2
HS
583if
584.B O_RDWR
585or
586.B O_WRONLY
587was specified in the
588.I event_f_flags
589argument when calling
590.BR fanotify_init (2)
68bcc008 591and an event occurred for a monitored file that is currently being executed.
597aaea2
HS
592.PP
593In addition to the usual errors for
594.BR write (2),
595the following errors can occur when writing to the fanotify file descriptor:
596.TP
597.B EINVAL
1b24e2ee
MK
598Fanotify access permissions are not enabled in the kernel configuration
599or the value of
597aaea2
HS
600.I response
601in the response structure is not valid.
602.TP
603.B ENOENT
604The file descriptor
605.I fd
606in the response structure is not valid.
33022419
MK
607This may occur when a response for the permission event has already been
608written.
597aaea2
HS
609.SH VERSIONS
610The fanotify API was introduced in version 2.6.36 of the Linux kernel and
611enabled in version 2.6.37.
612Fdinfo support was added in version 3.8.
d282bb24 613.SH CONFORMING TO
597aaea2
HS
614The fanotify API is Linux-specific.
615.SH NOTES
616The fanotify API is available only if the kernel was built with the
617.B CONFIG_FANOTIFY
618configuration option enabled.
619In addition, fanotify permission handling is available only if the
620.B CONFIG_FANOTIFY_ACCESS_PERMISSIONS
621configuration option is enabled.
622.SS Limitations and caveats
623Fanotify reports only events that a user-space program triggers through the
624filesystem API.
1b24e2ee
MK
625As a result,
626it does not catch remote events that occur on network filesystems.
597aaea2
HS
627.PP
628The fanotify API does not report file accesses and modifications that
629may occur because of
630.BR mmap (2),
631.BR msync (2),
632and
633.BR munmap (2).
634.PP
635Events for directories are created only if the directory itself is opened,
636read, and closed.
637Adding, removing, or changing children of a marked directory does not create
638events for the monitored directory itself.
639.PP
1b24e2ee
MK
640Fanotify monitoring of directories is not recursive:
641to monitor subdirectories under a directory,
642additional marks must be created.
a93e5c95
AG
643The
644.B FAN_DIR_MODIFY
645event can be used for detecting when a subdirectory has been created under
646a marked directory.
647An additional mark must then be set on the newly created subdirectory.
597aaea2 648Monitoring mounts offers the capability to monitor a whole directory tree.
b2f8214d
AG
649Monitoring filesystems offers the capability to monitor changes made from
650any mount of a filesystem instance.
597aaea2
HS
651.PP
652The event queue can overflow.
653In this case, events are lost.
654.SH BUGS
707914e9
MK
655Before Linux 3.19,
656.BR fallocate (2)
657did not generate fanotify events.
658Since Linux 3.19,
659.\" commit 820c12d5d6c0890bc93dd63893924a13041fdc35
660calls to
661.BR fallocate (2)
662generate
663.B FAN_MODIFY
664events.
a721e8b2 665.PP
d5b26a69 666As of Linux 3.17,
1aa556ab 667the following bugs exist:
597aaea2 668.IP * 3
c5a00024 669On Linux, a filesystem object may be accessible through multiple paths,
8e38f6d3 670for example, a part of a filesystem may be remounted using the
c5a00024
MK
671.IR \-\-bind
672option of
673.BR mount (8).
674A listener that marked a mount will be notified only of events that were
675triggered for a filesystem object using the same mount.
a4b394f2
HS
676Any other event will pass unnoticed.
677.IP *
bea08fec 678.\" FIXME . A patch was proposed.
1b24e2ee
MK
679When an event is generated,
680no check is made to see whether the user ID of the
681receiving process has authorization to read or write the file
682before passing a file descriptor for that file.
597aaea2
HS
683This poses a security risk, when the
684.B CAP_SYS_ADMIN
685capability is set for programs executed by unprivileged users.
f96adfdc
HS
686.IP *
687If a call to
1c612526 688.BR read (2)
e1001916
MK
689processes multiple events from the fanotify queue and an error occurs,
690the return value will be the total length of the events successfully
691copied to the user-space buffer before the error occurred.
692The return value will not be \-1, and
f96adfdc
HS
693.I errno
694will not be set.
e1001916 695Thus, the reading application has no way to detect the error.
597aaea2 696.SH EXAMPLE
0a4db6dc 697The two example programs below demonstrate the usage of the fanotify API.
3051b98c
MK
698.SS Example program: fanotify_example.c
699The first program is an example of fanotify being
0a4db6dc
MB
700used with its event object information passed in the form of a file
701descriptor.
3051b98c
MK
702The program marks the mount point passed as a command-line argument and
703waits for events of type
6684e3e4 704.B FAN_OPEN_PERM
597aaea2
HS
705and
706.BR FAN_CLOSE_WRITE .
707When a permission event occurs, a
708.B FAN_ALLOW
709response is given.
710.PP
3051b98c
MK
711The following shell session shows an example of
712running this program.
0a4db6dc 713This session involved editing the file
597aaea2
HS
714.IR /home/user/temp/notes .
715Before the file was opened, a
716.B FAN_OPEN_PERM
717event occurred.
718After the file was closed, a
719.B FAN_CLOSE_WRITE
720event occurred.
721Execution of the program ends when the user presses the ENTER key.
0a4db6dc 722.PP
597aaea2 723.in +4n
b8302363 724.EX
26f6196a 725# \fB./fanotify_example /home\fP
597aaea2
HS
726Press enter key to terminate.
727Listening for events.
728FAN_OPEN_PERM: File /home/user/temp/notes
729FAN_CLOSE_WRITE: File /home/user/temp/notes
730
731Listening for events stopped.
b8302363 732.EE
3051b98c 733.in
0a4db6dc 734.SS Program source: fanotify_example.c
c7885256 735\&
e7d0bb47 736.EX
616fce49 737#define _GNU_SOURCE /* Needed to get O_LARGEFILE definition */
597aaea2
HS
738#include <errno.h>
739#include <fcntl.h>
740#include <limits.h>
741#include <poll.h>
742#include <stdio.h>
743#include <stdlib.h>
744#include <sys/fanotify.h>
745#include <unistd.h>
746
5ff63f51 747/* Read all available fanotify events from the file descriptor \(aqfd\(aq */
597aaea2 748
815df19b 749static void
597aaea2
HS
750handle_events(int fd)
751{
752 const struct fanotify_event_metadata *metadata;
864eccb9 753 struct fanotify_event_metadata buf[200];
597aaea2
HS
754 ssize_t len;
755 char path[PATH_MAX];
756 ssize_t path_len;
757 char procfd_path[PATH_MAX];
758 struct fanotify_response response;
759
f7767949 760 /* Loop while events can be read from fanotify file descriptor */
597aaea2 761
7877c846 762 for (;;) {
597aaea2 763
f7767949 764 /* Read some events */
597aaea2
HS
765
766 len = read(fd, (void *) &buf, sizeof(buf));
767 if (len == \-1 && errno != EAGAIN) {
768 perror("read");
769 exit(EXIT_FAILURE);
770 }
771
f7767949 772 /* Check if end of available data reached */
597aaea2
HS
773
774 if (len <= 0)
775 break;
776
f7767949 777 /* Point to the first event in the buffer */
597aaea2 778
864eccb9 779 metadata = buf;
597aaea2 780
f7767949 781 /* Loop over all events in the buffer */
597aaea2
HS
782
783 while (FAN_EVENT_OK(metadata, len)) {
784
f7767949 785 /* Check that run\-time and compile\-time structures match */
597aaea2
HS
786
787 if (metadata\->vers != FANOTIFY_METADATA_VERSION) {
788 fprintf(stderr,
d1a71985 789 "Mismatch of fanotify metadata version.\en");
597aaea2
HS
790 exit(EXIT_FAILURE);
791 }
792
bfff73cb
MK
793 /* metadata\->fd contains either FAN_NOFD, indicating a
794 queue overflow, or a file descriptor (a nonnegative
795 integer). Here, we simply ignore queue overflow. */
0554d3f7 796
597aaea2
HS
797 if (metadata\->fd >= 0) {
798
f7767949 799 /* Handle open permission event */
597aaea2
HS
800
801 if (metadata\->mask & FAN_OPEN_PERM) {
802 printf("FAN_OPEN_PERM: ");
803
f7767949 804 /* Allow file to be opened */
597aaea2
HS
805
806 response.fd = metadata\->fd;
807 response.response = FAN_ALLOW;
f7767949 808 write(fd, &response,
864eccb9 809 sizeof(struct fanotify_response));
597aaea2
HS
810 }
811
f7767949 812 /* Handle closing of writable file event */
597aaea2 813
f7767949 814 if (metadata\->mask & FAN_CLOSE_WRITE)
597aaea2 815 printf("FAN_CLOSE_WRITE: ");
597aaea2 816
b34cbc45 817 /* Retrieve and print pathname of the accessed file */
597aaea2
HS
818
819 snprintf(procfd_path, sizeof(procfd_path),
820 "/proc/self/fd/%d", metadata\->fd);
821 path_len = readlink(procfd_path, path,
822 sizeof(path) \- 1);
823 if (path_len == \-1) {
824 perror("readlink");
825 exit(EXIT_FAILURE);
826 }
827
5ff63f51 828 path[path_len] = \(aq\e0\(aq;
d1a71985 829 printf("File %s\en", path);
597aaea2 830
f7767949 831 /* Close the file descriptor of the event */
597aaea2
HS
832
833 close(metadata\->fd);
597aaea2
HS
834 }
835
48fd9fe0 836 /* Advance to next event */
597aaea2
HS
837
838 metadata = FAN_EVENT_NEXT(metadata, len);
839 }
840 }
841}
842
843int
844main(int argc, char *argv[])
845{
846 char buf;
847 int fd, poll_num;
848 nfds_t nfds;
849 struct pollfd fds[2];
850
f7767949 851 /* Check mount point is supplied */
597aaea2
HS
852
853 if (argc != 2) {
d1a71985 854 fprintf(stderr, "Usage: %s MOUNT\en", argv[0]);
597aaea2
HS
855 exit(EXIT_FAILURE);
856 }
857
d1a71985 858 printf("Press enter key to terminate.\en");
597aaea2 859
f7767949 860 /* Create the file descriptor for accessing the fanotify API */
597aaea2
HS
861
862 fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
863 O_RDONLY | O_LARGEFILE);
864 if (fd == \-1) {
865 perror("fanotify_init");
866 exit(EXIT_FAILURE);
867 }
868
f7767949 869 /* Mark the mount for:
597aaea2 870 \- permission events before opening files
f7767949
MK
871 \- notification events after closing a write\-enabled
872 file descriptor */
597aaea2
HS
873
874 if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
943c52b7 875 FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,
597aaea2
HS
876 argv[1]) == \-1) {
877 perror("fanotify_mark");
597aaea2
HS
878 exit(EXIT_FAILURE);
879 }
880
f7767949 881 /* Prepare for polling */
597aaea2
HS
882
883 nfds = 2;
884
f7767949 885 /* Console input */
597aaea2
HS
886
887 fds[0].fd = STDIN_FILENO;
888 fds[0].events = POLLIN;
889
f7767949 890 /* Fanotify input */
597aaea2
HS
891
892 fds[1].fd = fd;
893 fds[1].events = POLLIN;
894
f7767949 895 /* This is the loop to wait for incoming events */
597aaea2 896
d1a71985 897 printf("Listening for events.\en");
370359a7 898
597aaea2
HS
899 while (1) {
900 poll_num = poll(fds, nfds, \-1);
901 if (poll_num == \-1) {
e1ca5880
MK
902 if (errno == EINTR) /* Interrupted by a signal */
903 continue; /* Restart poll() */
904
905 perror("poll"); /* Unexpected error */
597aaea2
HS
906 exit(EXIT_FAILURE);
907 }
370359a7 908
597aaea2
HS
909 if (poll_num > 0) {
910 if (fds[0].revents & POLLIN) {
911
f7767949 912 /* Console input is available: empty stdin and quit */
597aaea2 913
5ff63f51 914 while (read(STDIN_FILENO, &buf, 1) > 0 && buf != \(aq\en\(aq)
597aaea2
HS
915 continue;
916 break;
917 }
370359a7 918
597aaea2
HS
919 if (fds[1].revents & POLLIN) {
920
f7767949 921 /* Fanotify events are available */
597aaea2
HS
922
923 handle_events(fd);
924 }
925 }
926 }
927
d1a71985 928 printf("Listening for events stopped.\en");
f7767949 929 exit(EXIT_SUCCESS);
597aaea2 930}
e7d0bb47 931.EE
3051b98c
MK
932.\"
933.SS Example program: fanotify_fid.c
934The second program is an example of fanotify being used with
935.B FAN_REPORT_FID
936enabled.
794b5143 937The program marks the filesystem object that is passed as
3051b98c
MK
938a command-line argument
939and waits until an event of type
940.B FAN_CREATE
a93e5c95
AG
941or
942.B FAN_DIR_MODIFY
3051b98c 943has occurred.
794b5143 944The event mask indicates which type of filesystem object\(emeither
8f397fb4 945a file or a directory\(emwas created.
3051b98c
MK
946Once all events have been read from the buffer and processed accordingly,
947the program simply terminates.
948.PP
949The following shell sessions show two different invocations of
950this program, with different actions performed on a watched object.
951.PP
952The first session shows a mark being placed on
953.IR /home/user .
954This is followed by the creation of a regular file,
955.IR /home/user/testfile.txt .
956This results in a
957.B FAN_CREATE
4e535185 958event being generated and reported against the file's parent watched
a93e5c95
AG
959directory object and a
960.B FAN_DIR_MODIFY
961event being generated and reported with the created file name.
3051b98c
MK
962Program execution ends once all events captured within the buffer have
963been processed.
3051b98c
MK
964.PP
965.in +4n
966.EX
967# \fB./fanotify_fid /home/user\fP
968Listening for events.
4e535185
AG
969FAN_CREATE (file created):
970 Directory /home/user has been modified.
a93e5c95
AG
971FAN_DIR_MODIFY (entry changed):
972 Directory /home/user has been modified.
973 Entry 'testfile.txt' is not a subdirectory.
3051b98c
MK
974All events processed successfully. Program exiting.
975
4e535185 976$ \fBtouch /home/user/testfile.txt\fP # In another terminal
3051b98c
MK
977.EE
978.in
979.PP
980The second session shows a mark being placed on
981.IR /home/user .
982This is followed by the creation of a directory,
983.IR /home/user/testdir .
4e535185 984This specific action results in a
3051b98c 985.B FAN_CREATE
4e535185 986event being generated and is reported with the
3051b98c 987.B FAN_ONDIR
a93e5c95
AG
988flag set and a
989.B FAN_DIR_MODIFY
990event being generated and reported with the created directory name.
3051b98c
MK
991.PP
992.in +4n
993.EX
994# \fB./fanotify_fid /home/user\fP
995Listening for events.
996FAN_CREATE | FAN_ONDIR (subdirectory created):
997 Directory /home/user has been modified.
a93e5c95
AG
998FAN_DIR_MODIFY (entry changed):
999 Directory /home/user has been modified.
1000 Entry 'testdir' is a subdirectory.
3051b98c
MK
1001All events processed successfully. Program exiting.
1002
4e535185 1003$ \fBmkdir \-p /home/user/testdir\fP # In another terminal
3051b98c 1004.EE
0a4db6dc
MB
1005.in
1006.SS Program source: fanotify_fid.c
1007\&
1008.EX
1009#define _GNU_SOURCE
1010#include <errno.h>
1011#include <fcntl.h>
1012#include <limits.h>
1013#include <stdio.h>
1014#include <stdlib.h>
1015#include <sys/types.h>
1016#include <sys/stat.h>
1017#include <sys/fanotify.h>
1018#include <unistd.h>
1019
1020#define BUF_SIZE 256
1021
6f10bd32
MK
1022int
1023main(int argc, char **argv)
0a4db6dc 1024{
4e535185 1025 int fd, ret, event_fd, mount_fd;
0a4db6dc
MB
1026 ssize_t len, path_len;
1027 char path[PATH_MAX];
1028 char procfd_path[PATH_MAX];
1029 char events_buf[BUF_SIZE];
0a4db6dc
MB
1030 struct file_handle *file_handle;
1031 struct fanotify_event_metadata *metadata;
1032 struct fanotify_event_info_fid *fid;
a93e5c95
AG
1033 const char *file_name;
1034 struct stat sb;
0a4db6dc
MB
1035
1036 if (argc != 2) {
8f397fb4 1037 fprintf(stderr, "Invalid number of command line arguments.\en");
0a4db6dc
MB
1038 exit(EXIT_FAILURE);
1039 }
1040
4e535185
AG
1041 mount_fd = open(argv[1], O_DIRECTORY | O_RDONLY);
1042 if (mount_fd == \-1) {
1043 perror(argv[1]);
1044 exit(EXIT_FAILURE);
1045 }
1046
1047
0a4db6dc 1048 /* Create an fanotify file descriptor with FAN_REPORT_FID as a flag
87d12b1b
MK
1049 so that program can receive fid events. */
1050
0a4db6dc 1051 fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, 0);
5ff63f51 1052 if (fd == \-1) {
0a4db6dc
MB
1053 perror("fanotify_init");
1054 exit(EXIT_FAILURE);
1055 }
1056
1057 /* Place a mark on the filesystem object supplied in argv[1]. */
87d12b1b 1058
0a4db6dc 1059 ret = fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_ONLYDIR,
a93e5c95 1060 FAN_DIR_MODIFY | FAN_CREATE | FAN_ONDIR,
0a4db6dc 1061 AT_FDCWD, argv[1]);
5ff63f51 1062 if (ret == \-1) {
0a4db6dc
MB
1063 perror("fanotify_mark");
1064 exit(EXIT_FAILURE);
1065 }
1066
8f397fb4 1067 printf("Listening for events.\en");
0a4db6dc
MB
1068
1069 /* Read events from the event queue into a buffer */
87d12b1b 1070
0a4db6dc 1071 len = read(fd, (void *) &events_buf, sizeof(events_buf));
5ff63f51 1072 if (len == \-1 && errno != EAGAIN) {
0a4db6dc
MB
1073 perror("read");
1074 exit(EXIT_FAILURE);
1075 }
1076
1077 /* Process all events within the buffer */
87d12b1b 1078
0a4db6dc
MB
1079 for (metadata = (struct fanotify_event_metadata *) events_buf;
1080 FAN_EVENT_OK(metadata, len);
1081 metadata = FAN_EVENT_NEXT(metadata, len)) {
1082 fid = (struct fanotify_event_info_fid *) (metadata + 1);
8f397fb4 1083 file_handle = (struct file_handle *) fid\->handle;
0a4db6dc
MB
1084
1085 /* Ensure that the event info is of the correct type */
87d12b1b 1086
a93e5c95
AG
1087 if (fid\->hdr.info_type == FAN_EVENT_INFO_TYPE_FID) {
1088 file_name = NULL;
1089 } else if (fid\->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID_NAME) {
4c258dbc
MK
1090 file_name = file_handle->f_handle +
1091 file_handle->handle_bytes;
a93e5c95 1092 } else {
8f397fb4 1093 fprintf(stderr, "Received unexpected event info type.\en");
0a4db6dc
MB
1094 exit(EXIT_FAILURE);
1095 }
1096
a93e5c95
AG
1097 if (metadata\->mask == FAN_DIR_MODIFY)
1098 printf("FAN_DIR_MODIFY (entry changed):\en");
1099
8f397fb4 1100 if (metadata\->mask == FAN_CREATE)
4e535185 1101 printf("FAN_CREATE (file created):\en");
0a4db6dc 1102
4e535185
AG
1103 if (metadata\->mask == (FAN_CREATE | FAN_ONDIR))
1104 printf("FAN_CREATE | FAN_ONDIR (subdirectory created):\en");
0a4db6dc 1105
4c258dbc
MK
1106 /* metadata\->fd is set to FAN_NOFD when FAN_REPORT_FID is
1107 enabled. To obtain a file descriptor for the file object
1108 corresponding to an event you can use the struct file_handle
1109 that\(aqs provided within the fanotify_event_info_fid in
1110 conjunction with the open_by_handle_at(2) system call.
1111 A check for ESTALE is done to accommodate for the situation
1112 where the file handle for the object was deleted prior to
1113 this system call. */
87d12b1b 1114
4e535185
AG
1115 event_fd = open_by_handle_at(mount_fd, file_handle, O_RDONLY);
1116 if (event_fd == \-1) {
2d26ddfa
MK
1117 if (errno == ESTALE) {
1118 printf("File handle is no longer valid. "
8f397fb4 1119 "File has been deleted\en");
2d26ddfa
MK
1120 continue;
1121 } else {
1122 perror("open_by_handle_at");
1123 exit(EXIT_FAILURE);
4e535185 1124 }
0a4db6dc
MB
1125 }
1126
6f10bd32
MK
1127 snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d",
1128 event_fd);
0a4db6dc 1129
817c8240 1130 /* Retrieve and print the path of the modified dentry */
87d12b1b 1131
5ff63f51
MK
1132 path_len = readlink(procfd_path, path, sizeof(path) \- 1);
1133 if (path_len == \-1) {
0a4db6dc
MB
1134 perror("readlink");
1135 exit(EXIT_FAILURE);
1136 }
1137
8f397fb4
JW
1138 path[path_len] = \(aq\e0\(aq;
1139 printf("\etDirectory \(aq%s\(aq has been modified.\en", path);
0a4db6dc 1140
a93e5c95
AG
1141 if (file_name) {
1142 ret = fstatat(event_fd, file_name, &sb, 0);
1143 if (ret == \-1) {
1144 if (errno != ENOENT) {
1145 perror("fstatat");
1146 exit(EXIT_FAILURE);
1147 }
1148 printf("\etEntry %\(aqs\(aq does not exist.\en", file_name);
1149 } else if ((sb.st_mode & S_IFMT) == S_IFDIR) {
1150 printf("\etEntry \(aq%s\(aq is a subdirectory.\en", file_name);
1151 } else {
4c258dbc
MK
1152 printf("\etEntry \(aq%s\(aq is not a subdirectory.\en",
1153 file_name);
a93e5c95
AG
1154 }
1155 }
1156
0a4db6dc 1157 /* Close associated file descriptor for this event */
5ff63f51 1158
0a4db6dc
MB
1159 close(event_fd);
1160 }
1161
8f397fb4 1162 printf("All events processed successfully. Program exiting.\en");
0a4db6dc
MB
1163 exit(EXIT_SUCCESS);
1164}
1165.EE
d282bb24 1166.SH SEE ALSO
597aaea2
HS
1167.ad l
1168.BR fanotify_init (2),
1169.BR fanotify_mark (2),
1170.BR inotify (7)