]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man7/fanotify.7
fanotify.7: wfix
[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
9ba01802 25.TH FANOTIFY 7 2019-03-06 "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
327.B FAN_CLOSE_WRITE
328A file that was opened for writing
329.RB ( O_WRONLY
330or
331.BR O_RDWR )
332was closed.
333.TP
334.B FAN_CLOSE_NOWRITE
02a18e0f 335A file or directory that was opened read-only
597aaea2 336.RB ( O_RDONLY )
02a18e0f 337was closed.
597aaea2
HS
338.TP
339.B FAN_Q_OVERFLOW
340The event queue exceeded the limit of 16384 entries.
4a57583f
MK
341This limit can be overridden by specifying the
342.BR FAN_UNLIMITED_QUEUE
343flag when calling
344.BR fanotify_init (2).
597aaea2
HS
345.TP
346.B FAN_ACCESS_PERM
347An application wants to read a file or directory, for example using
348.BR read (2)
349or
350.BR readdir (2).
4a57583f
MK
351The reader must write a response (as described below)
352that determines whether the permission to
597aaea2
HS
353access the filesystem object shall be granted.
354.TP
355.B FAN_OPEN_PERM
356An application wants to open a file or directory.
357The reader must write a response that determines whether the permission to
358open the filesystem object shall be granted.
fc37d2f1
MB
359.TP
360.B FAN_OPEN_EXEC_PERM
361An application wants to open a file for execution.
362The reader must write a response that determines whether the permission to
363open the filesystem object for execution shall be granted.
fd1eb8a7 364See NOTES in
fc37d2f1
MB
365.BR fanotify_mark (2)
366for additional details.
597aaea2
HS
367.PP
368To check for any close event, the following bit mask may be used:
369.TP
370.B FAN_CLOSE
f897ec11 371A file was closed.
4a57583f 372This is a synonym for:
a721e8b2 373.IP
f897ec11 374 FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE
597aaea2 375.PP
0a4db6dc
MB
376To check for any move event, the following bit mask may be used:
377.TP
378.B FAN_MOVE
379A file or directory was moved.
380This is a synonym for:
381.IP
382 FAN_MOVED_FROM | FAN_MOVED_TO
383.PP
384The fields of the
385.I fanotify_event_info_fid
386structure are as follows:
387.TP
388.I hdr
389This is a structure of type
390.IR fanotify_event_info_header .
391It is a generic header that contains information used to describe
392additional information attached to the event.
393For example, when an fanotify file descriptor is created using
817c8240 394.BR FAN_REPORT_FID ,
0a4db6dc
MB
395the
396.I info_type
397field of this header is set to
398.BR FAN_EVENT_INFO_TYPE_FID .
399Event listeners can use this field to check that the additional
400information received for an event is of the correct type.
401Additionally, the
402.I fanotify_event_info_header
403also contains a
404.I len
405field.
406In the current implementation, the value of
407.I len
5ff63f51 408is always (event_len \- FAN_EVENT_METADATA_LEN).
0a4db6dc
MB
409.TP
410.I fsid
411This is a unique identifier of the filesystem containing the object
412associated with the event.
413It is a structure of type
414.I __kernel_fsid_t
415and contains the same value as
416.I f_fsid
417when calling
418.BR statfs (2).
419.TP
420.I file_handle
421This is a variable length structure of type
422.IR file_handle .
423It is an opaque handle that corresponds to a specified object on a
424filesystem as returned by
817c8240 425.BR name_to_handle_at (2).
0a4db6dc
MB
426It can be used to uniquely identify a file on a filesystem and can be
427passed as an argument to
817c8240 428.BR open_by_handle_at (2).
0a4db6dc
MB
429Note that for directory entry events, such as
430.BR FAN_CREATE ,
431.BR FAN_DELETE ,
817c8240
MK
432and
433.BR FAN_MOVE ,
0a4db6dc
MB
434the
435.IR file_handle
436describes the modified directory and not the created/deleted/moved child
437object.
438The events
439.BR FAN_ATTRIB ,
817c8240 440.BR FAN_DELETE_SELF ,
0a4db6dc
MB
441and
442.BR FAN_MOVE_SELF
443will carry the
444.IR file_handle
445information for the child object if the child object is being watched.
446.PP
1b24e2ee 447The following macros are provided to iterate over a buffer containing
4a57583f 448fanotify event metadata returned by a
597aaea2 449.BR read (2)
4a57583f 450from an fanotify file descriptor:
597aaea2
HS
451.TP
452.B FAN_EVENT_OK(meta, len)
453This macro checks the remaining length
454.I len
455of the buffer
456.I meta
457against the length of the metadata structure and the
458.I event_len
459field of the first metadata structure in the buffer.
460.TP
461.B FAN_EVENT_NEXT(meta, len)
98f7d53c 462This macro uses the length indicated in the
597aaea2 463.I event_len
98f7d53c
MK
464field of the metadata structure pointed to by
465.IR meta
466to calculate the address of the next metadata structure that follows
467.IR meta .
468.I len
469is the number of bytes of metadata that currently remain in the buffer.
470The macro returns a pointer to the next metadata structure that follows
471.IR meta ,
472and reduces
473.I len
d721b5aa 474by the number of bytes in the metadata structure that
98f7d53c
MK
475has been skipped over (i.e., it subtracts
476.IR meta\->event_len
477from
478.IR len ).
3c36e635
HS
479.PP
480In addition, there is:
481.TP
482.B FAN_EVENT_METADATA_LEN
7c0f0ce0
MK
483This macro returns the size (in bytes) of the structure
484.IR fanotify_event_metadata .
3c36e635 485This is the minimum size (and currently the only size) of any event metadata.
98f7d53c 486.\"
488cdd81
MK
487.SS Monitoring an fanotify file descriptor for events
488When an fanotify event occurs, the fanotify file descriptor indicates as
489readable when passed to
490.BR epoll (7),
491.BR poll (2),
492or
493.BR select (2).
88145b29 494.SS Dealing with permission events
597aaea2
HS
495For permission events, the application must
496.BR write (2)
497a structure of the following form to the
d3471a46 498fanotify file descriptor:
a721e8b2 499.PP
597aaea2 500.in +4n
b8302363 501.EX
597aaea2
HS
502struct fanotify_response {
503 __s32 fd;
504 __u32 response;
505};
b8302363 506.EE
597aaea2 507.in
d7d24d40
MK
508.PP
509The fields of this structure are as follows:
9d76d630 510.TP
597aaea2
HS
511.I fd
512This is the file descriptor from the structure
513.IR fanotify_event_metadata .
514.TP
515.I response
516This field indicates whether or not the permission is to be granted.
517Its value must be either
518.B FAN_ALLOW
519to allow the file operation or
520.B FAN_DENY
521to deny the file operation.
522.PP
49894a5a
MK
523If access is denied, the requesting application call will receive an
524.BR EPERM
525error.
88145b29 526.SS Closing the fanotify file descriptor
be8ba5d8
MK
527.PP
528When all file descriptors referring to the fanotify notification group are
529closed, the fanotify group is released and its resources
530are freed for reuse by the kernel.
531Upon
532.BR close (2),
533outstanding permission events will be set to allowed.
c00ff2dc 534.SS /proc/[pid]/fdinfo
597aaea2 535The file
3d4433fe 536.I /proc/[pid]/fdinfo/[fd]
597aaea2
HS
537contains information about fanotify marks for file descriptor
538.I fd
539of process
540.IR pid .
75f8598a
MK
541See
542.BR proc (5)
597aaea2
HS
543for details.
544.SH ERRORS
545In addition to the usual errors for
546.BR read (2),
1b24e2ee
MK
547the following errors can occur when reading from the
548fanotify file descriptor:
597aaea2
HS
549.TP
550.B EINVAL
4a57583f 551The buffer is too small to hold the event.
597aaea2
HS
552.TP
553.B EMFILE
554The per-process limit on the number of open files has been reached.
555See the description of
556.B RLIMIT_NOFILE
557in
558.BR getrlimit (2).
559.TP
560.B ENFILE
e258766b 561The system-wide limit on the total number of open files has been reached.
597aaea2 562See
fa6d3b26 563.I /proc/sys/fs/file\-max
597aaea2
HS
564in
565.BR proc (5).
566.TP
567.B ETXTBSY
597aaea2 568This error is returned by
68bcc008 569.BR read (2)
597aaea2
HS
570if
571.B O_RDWR
572or
573.B O_WRONLY
574was specified in the
575.I event_f_flags
576argument when calling
577.BR fanotify_init (2)
68bcc008 578and an event occurred for a monitored file that is currently being executed.
597aaea2
HS
579.PP
580In addition to the usual errors for
581.BR write (2),
582the following errors can occur when writing to the fanotify file descriptor:
583.TP
584.B EINVAL
1b24e2ee
MK
585Fanotify access permissions are not enabled in the kernel configuration
586or the value of
597aaea2
HS
587.I response
588in the response structure is not valid.
589.TP
590.B ENOENT
591The file descriptor
592.I fd
593in the response structure is not valid.
33022419
MK
594This may occur when a response for the permission event has already been
595written.
597aaea2
HS
596.SH VERSIONS
597The fanotify API was introduced in version 2.6.36 of the Linux kernel and
598enabled in version 2.6.37.
599Fdinfo support was added in version 3.8.
d282bb24 600.SH CONFORMING TO
597aaea2
HS
601The fanotify API is Linux-specific.
602.SH NOTES
603The fanotify API is available only if the kernel was built with the
604.B CONFIG_FANOTIFY
605configuration option enabled.
606In addition, fanotify permission handling is available only if the
607.B CONFIG_FANOTIFY_ACCESS_PERMISSIONS
608configuration option is enabled.
609.SS Limitations and caveats
610Fanotify reports only events that a user-space program triggers through the
611filesystem API.
1b24e2ee
MK
612As a result,
613it does not catch remote events that occur on network filesystems.
597aaea2
HS
614.PP
615The fanotify API does not report file accesses and modifications that
616may occur because of
617.BR mmap (2),
618.BR msync (2),
619and
620.BR munmap (2).
621.PP
622Events for directories are created only if the directory itself is opened,
623read, and closed.
624Adding, removing, or changing children of a marked directory does not create
625events for the monitored directory itself.
626.PP
1b24e2ee
MK
627Fanotify monitoring of directories is not recursive:
628to monitor subdirectories under a directory,
629additional marks must be created.
3d1ee497 630(But note that the fanotify API provides no way of detecting when a
1b24e2ee
MK
631subdirectory has been created under a marked directory,
632which makes recursive monitoring difficult.)
597aaea2 633Monitoring mounts offers the capability to monitor a whole directory tree.
b2f8214d
AG
634Monitoring filesystems offers the capability to monitor changes made from
635any mount of a filesystem instance.
597aaea2
HS
636.PP
637The event queue can overflow.
638In this case, events are lost.
639.SH BUGS
707914e9
MK
640Before Linux 3.19,
641.BR fallocate (2)
642did not generate fanotify events.
643Since Linux 3.19,
644.\" commit 820c12d5d6c0890bc93dd63893924a13041fdc35
645calls to
646.BR fallocate (2)
647generate
648.B FAN_MODIFY
649events.
a721e8b2 650.PP
d5b26a69 651As of Linux 3.17,
1aa556ab 652the following bugs exist:
597aaea2 653.IP * 3
c5a00024 654On Linux, a filesystem object may be accessible through multiple paths,
8e38f6d3 655for example, a part of a filesystem may be remounted using the
c5a00024
MK
656.IR \-\-bind
657option of
658.BR mount (8).
659A listener that marked a mount will be notified only of events that were
660triggered for a filesystem object using the same mount.
a4b394f2
HS
661Any other event will pass unnoticed.
662.IP *
bea08fec 663.\" FIXME . A patch was proposed.
1b24e2ee
MK
664When an event is generated,
665no check is made to see whether the user ID of the
666receiving process has authorization to read or write the file
667before passing a file descriptor for that file.
597aaea2
HS
668This poses a security risk, when the
669.B CAP_SYS_ADMIN
670capability is set for programs executed by unprivileged users.
f96adfdc
HS
671.IP *
672If a call to
1c612526 673.BR read (2)
e1001916
MK
674processes multiple events from the fanotify queue and an error occurs,
675the return value will be the total length of the events successfully
676copied to the user-space buffer before the error occurred.
677The return value will not be \-1, and
f96adfdc
HS
678.I errno
679will not be set.
e1001916 680Thus, the reading application has no way to detect the error.
597aaea2 681.SH EXAMPLE
0a4db6dc 682The two example programs below demonstrate the usage of the fanotify API.
3051b98c
MK
683.SS Example program: fanotify_example.c
684The first program is an example of fanotify being
0a4db6dc
MB
685used with its event object information passed in the form of a file
686descriptor.
3051b98c
MK
687The program marks the mount point passed as a command-line argument and
688waits for events of type
6684e3e4 689.B FAN_OPEN_PERM
597aaea2
HS
690and
691.BR FAN_CLOSE_WRITE .
692When a permission event occurs, a
693.B FAN_ALLOW
694response is given.
695.PP
3051b98c
MK
696The following shell session shows an example of
697running this program.
0a4db6dc 698This session involved editing the file
597aaea2
HS
699.IR /home/user/temp/notes .
700Before the file was opened, a
701.B FAN_OPEN_PERM
702event occurred.
703After the file was closed, a
704.B FAN_CLOSE_WRITE
705event occurred.
706Execution of the program ends when the user presses the ENTER key.
0a4db6dc 707.PP
597aaea2 708.in +4n
b8302363 709.EX
26f6196a 710# \fB./fanotify_example /home\fP
597aaea2
HS
711Press enter key to terminate.
712Listening for events.
713FAN_OPEN_PERM: File /home/user/temp/notes
714FAN_CLOSE_WRITE: File /home/user/temp/notes
715
716Listening for events stopped.
b8302363 717.EE
3051b98c 718.in
0a4db6dc 719.EE
597aaea2 720.in
0a4db6dc 721.SS Program source: fanotify_example.c
c7885256 722\&
e7d0bb47 723.EX
616fce49 724#define _GNU_SOURCE /* Needed to get O_LARGEFILE definition */
597aaea2
HS
725#include <errno.h>
726#include <fcntl.h>
727#include <limits.h>
728#include <poll.h>
729#include <stdio.h>
730#include <stdlib.h>
731#include <sys/fanotify.h>
732#include <unistd.h>
733
5ff63f51 734/* Read all available fanotify events from the file descriptor \(aqfd\(aq */
597aaea2 735
815df19b 736static void
597aaea2
HS
737handle_events(int fd)
738{
739 const struct fanotify_event_metadata *metadata;
864eccb9 740 struct fanotify_event_metadata buf[200];
597aaea2
HS
741 ssize_t len;
742 char path[PATH_MAX];
743 ssize_t path_len;
744 char procfd_path[PATH_MAX];
745 struct fanotify_response response;
746
f7767949 747 /* Loop while events can be read from fanotify file descriptor */
597aaea2 748
7877c846 749 for (;;) {
597aaea2 750
f7767949 751 /* Read some events */
597aaea2
HS
752
753 len = read(fd, (void *) &buf, sizeof(buf));
754 if (len == \-1 && errno != EAGAIN) {
755 perror("read");
756 exit(EXIT_FAILURE);
757 }
758
f7767949 759 /* Check if end of available data reached */
597aaea2
HS
760
761 if (len <= 0)
762 break;
763
f7767949 764 /* Point to the first event in the buffer */
597aaea2 765
864eccb9 766 metadata = buf;
597aaea2 767
f7767949 768 /* Loop over all events in the buffer */
597aaea2
HS
769
770 while (FAN_EVENT_OK(metadata, len)) {
771
f7767949 772 /* Check that run\-time and compile\-time structures match */
597aaea2
HS
773
774 if (metadata\->vers != FANOTIFY_METADATA_VERSION) {
775 fprintf(stderr,
d1a71985 776 "Mismatch of fanotify metadata version.\en");
597aaea2
HS
777 exit(EXIT_FAILURE);
778 }
779
bfff73cb
MK
780 /* metadata\->fd contains either FAN_NOFD, indicating a
781 queue overflow, or a file descriptor (a nonnegative
782 integer). Here, we simply ignore queue overflow. */
0554d3f7 783
597aaea2
HS
784 if (metadata\->fd >= 0) {
785
f7767949 786 /* Handle open permission event */
597aaea2
HS
787
788 if (metadata\->mask & FAN_OPEN_PERM) {
789 printf("FAN_OPEN_PERM: ");
790
f7767949 791 /* Allow file to be opened */
597aaea2
HS
792
793 response.fd = metadata\->fd;
794 response.response = FAN_ALLOW;
f7767949 795 write(fd, &response,
864eccb9 796 sizeof(struct fanotify_response));
597aaea2
HS
797 }
798
f7767949 799 /* Handle closing of writable file event */
597aaea2 800
f7767949 801 if (metadata\->mask & FAN_CLOSE_WRITE)
597aaea2 802 printf("FAN_CLOSE_WRITE: ");
597aaea2 803
b34cbc45 804 /* Retrieve and print pathname of the accessed file */
597aaea2
HS
805
806 snprintf(procfd_path, sizeof(procfd_path),
807 "/proc/self/fd/%d", metadata\->fd);
808 path_len = readlink(procfd_path, path,
809 sizeof(path) \- 1);
810 if (path_len == \-1) {
811 perror("readlink");
812 exit(EXIT_FAILURE);
813 }
814
5ff63f51 815 path[path_len] = \(aq\e0\(aq;
d1a71985 816 printf("File %s\en", path);
597aaea2 817
f7767949 818 /* Close the file descriptor of the event */
597aaea2
HS
819
820 close(metadata\->fd);
597aaea2
HS
821 }
822
48fd9fe0 823 /* Advance to next event */
597aaea2
HS
824
825 metadata = FAN_EVENT_NEXT(metadata, len);
826 }
827 }
828}
829
830int
831main(int argc, char *argv[])
832{
833 char buf;
834 int fd, poll_num;
835 nfds_t nfds;
836 struct pollfd fds[2];
837
f7767949 838 /* Check mount point is supplied */
597aaea2
HS
839
840 if (argc != 2) {
d1a71985 841 fprintf(stderr, "Usage: %s MOUNT\en", argv[0]);
597aaea2
HS
842 exit(EXIT_FAILURE);
843 }
844
d1a71985 845 printf("Press enter key to terminate.\en");
597aaea2 846
f7767949 847 /* Create the file descriptor for accessing the fanotify API */
597aaea2
HS
848
849 fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
850 O_RDONLY | O_LARGEFILE);
851 if (fd == \-1) {
852 perror("fanotify_init");
853 exit(EXIT_FAILURE);
854 }
855
f7767949 856 /* Mark the mount for:
597aaea2 857 \- permission events before opening files
f7767949
MK
858 \- notification events after closing a write\-enabled
859 file descriptor */
597aaea2
HS
860
861 if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
943c52b7 862 FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,
597aaea2
HS
863 argv[1]) == \-1) {
864 perror("fanotify_mark");
597aaea2
HS
865 exit(EXIT_FAILURE);
866 }
867
f7767949 868 /* Prepare for polling */
597aaea2
HS
869
870 nfds = 2;
871
f7767949 872 /* Console input */
597aaea2
HS
873
874 fds[0].fd = STDIN_FILENO;
875 fds[0].events = POLLIN;
876
f7767949 877 /* Fanotify input */
597aaea2
HS
878
879 fds[1].fd = fd;
880 fds[1].events = POLLIN;
881
f7767949 882 /* This is the loop to wait for incoming events */
597aaea2 883
d1a71985 884 printf("Listening for events.\en");
370359a7 885
597aaea2
HS
886 while (1) {
887 poll_num = poll(fds, nfds, \-1);
888 if (poll_num == \-1) {
e1ca5880
MK
889 if (errno == EINTR) /* Interrupted by a signal */
890 continue; /* Restart poll() */
891
892 perror("poll"); /* Unexpected error */
597aaea2
HS
893 exit(EXIT_FAILURE);
894 }
370359a7 895
597aaea2
HS
896 if (poll_num > 0) {
897 if (fds[0].revents & POLLIN) {
898
f7767949 899 /* Console input is available: empty stdin and quit */
597aaea2 900
5ff63f51 901 while (read(STDIN_FILENO, &buf, 1) > 0 && buf != \(aq\en\(aq)
597aaea2
HS
902 continue;
903 break;
904 }
370359a7 905
597aaea2
HS
906 if (fds[1].revents & POLLIN) {
907
f7767949 908 /* Fanotify events are available */
597aaea2
HS
909
910 handle_events(fd);
911 }
912 }
913 }
914
d1a71985 915 printf("Listening for events stopped.\en");
f7767949 916 exit(EXIT_SUCCESS);
597aaea2 917}
e7d0bb47 918.EE
3051b98c
MK
919.\"
920.SS Example program: fanotify_fid.c
921The second program is an example of fanotify being used with
922.B FAN_REPORT_FID
923enabled.
794b5143 924The program marks the filesystem object that is passed as
3051b98c
MK
925a command-line argument
926and waits until an event of type
927.B FAN_CREATE
928has occurred.
794b5143
MK
929The event mask indicates which type of filesystem object\(emeither
930a file or a directory\(emwas created".
3051b98c
MK
931Once all events have been read from the buffer and processed accordingly,
932the program simply terminates.
933.PP
934The following shell sessions show two different invocations of
935this program, with different actions performed on a watched object.
936.PP
937The first session shows a mark being placed on
938.IR /home/user .
939This is followed by the creation of a regular file,
940.IR /home/user/testfile.txt .
941This results in a
942.B FAN_CREATE
943event being created and reported against the file's parent watched
944directory object.
945Program execution ends once all events captured within the buffer have
946been processed.
947Program execution ends once all events captured within the buffer are
948processed.
949.PP
950.in +4n
951.EX
952# \fB./fanotify_fid /home/user\fP
953Listening for events.
954FAN_CREATE (file created): Directory /home/user has been modified.
955All events processed successfully. Program exiting.
956
957$ \fBtouch /home/user/testing\fP # In another terminal
958.EE
959.in
960.PP
961The second session shows a mark being placed on
962.IR /home/user .
963This is followed by the creation of a directory,
964.IR /home/user/testdir .
965This specific action results in the program producing a
966.B FAN_CREATE
967and
968.B FAN_ONDIR
969event.
970.PP
971.in +4n
972.EX
973# \fB./fanotify_fid /home/user\fP
974Listening for events.
975FAN_CREATE | FAN_ONDIR (subdirectory created):
976 Directory /home/user has been modified.
977All events processed successfully. Program exiting.
978
979$ \fBmkdir \-p /home/user/testing\fP # In another terminal
980.EE
0a4db6dc
MB
981.in
982.SS Program source: fanotify_fid.c
983\&
984.EX
985#define _GNU_SOURCE
986#include <errno.h>
987#include <fcntl.h>
988#include <limits.h>
989#include <stdio.h>
990#include <stdlib.h>
991#include <sys/types.h>
992#include <sys/stat.h>
993#include <sys/fanotify.h>
994#include <unistd.h>
995
996#define BUF_SIZE 256
997
6f10bd32
MK
998int
999main(int argc, char **argv)
0a4db6dc
MB
1000{
1001 int fd, ret, event_fd;
1002 ssize_t len, path_len;
1003 char path[PATH_MAX];
1004 char procfd_path[PATH_MAX];
1005 char events_buf[BUF_SIZE];
0a4db6dc
MB
1006 struct file_handle *file_handle;
1007 struct fanotify_event_metadata *metadata;
1008 struct fanotify_event_info_fid *fid;
1009
1010 if (argc != 2) {
5ff63f51 1011 fprintf(stderr, "Invalid number of command line arguments.\e\n");
0a4db6dc
MB
1012 exit(EXIT_FAILURE);
1013 }
1014
1015 /* Create an fanotify file descriptor with FAN_REPORT_FID as a flag
87d12b1b
MK
1016 so that program can receive fid events. */
1017
0a4db6dc 1018 fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, 0);
5ff63f51 1019 if (fd == \-1) {
0a4db6dc
MB
1020 perror("fanotify_init");
1021 exit(EXIT_FAILURE);
1022 }
1023
1024 /* Place a mark on the filesystem object supplied in argv[1]. */
87d12b1b 1025
0a4db6dc
MB
1026 ret = fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_ONLYDIR,
1027 FAN_CREATE | FAN_ONDIR,
1028 AT_FDCWD, argv[1]);
5ff63f51 1029 if (ret == \-1) {
0a4db6dc
MB
1030 perror("fanotify_mark");
1031 exit(EXIT_FAILURE);
1032 }
1033
5ff63f51 1034 printf("Listening for events.\e\n");
0a4db6dc
MB
1035
1036 /* Read events from the event queue into a buffer */
87d12b1b 1037
0a4db6dc 1038 len = read(fd, (void *) &events_buf, sizeof(events_buf));
5ff63f51 1039 if (len == \-1 && errno != EAGAIN) {
0a4db6dc
MB
1040 perror("read");
1041 exit(EXIT_FAILURE);
1042 }
1043
1044 /* Process all events within the buffer */
87d12b1b 1045
0a4db6dc
MB
1046 for (metadata = (struct fanotify_event_metadata *) events_buf;
1047 FAN_EVENT_OK(metadata, len);
1048 metadata = FAN_EVENT_NEXT(metadata, len)) {
1049 fid = (struct fanotify_event_info_fid *) (metadata + 1);
1050 file_handle = (struct file_handle *) fid->handle;
1051
1052 /* Ensure that the event info is of the correct type */
87d12b1b 1053
0a4db6dc 1054 if (fid->hdr.info_type != FAN_EVENT_INFO_TYPE_FID) {
5ff63f51 1055 fprintf(stderr, "Received unexpected event info type.\e\n");
0a4db6dc
MB
1056 exit(EXIT_FAILURE);
1057 }
1058
1059 if (metadata->mask == FAN_CREATE)
525b88e1 1060 printf("FAN_CREATE (file created):");
0a4db6dc
MB
1061
1062 if (metadata->mask == FAN_CREATE | FAN_ONDIR)
525b88e1 1063 printf("FAN_CREATE | FAN_ONDIR (subdirectory created):");
0a4db6dc
MB
1064
1065 /* metadata->fd is set to FAN_NOFD when FAN_REPORT_FID is enabled.
87d12b1b 1066 To obtain a file descriptor for the file object corresponding to
5ff63f51 1067 an event you can use the struct file_handle that\(aqs provided
87d12b1b 1068 within the fanotify_event_info_fid in conjunction with the
c6624006 1069 open_by_handle_at(2) system call. A check for ESTALE is done
794b5143
MK
1070 to accommodate for the situation where the file handle for the
1071 object was deleted prior to this system call. */
87d12b1b 1072
0a4db6dc 1073 event_fd = open_by_handle_at(AT_FDCWD, file_handle, O_RDONLY);
2d26ddfa
MK
1074 if (ret == \-1) {
1075 if (errno == ESTALE) {
1076 printf("File handle is no longer valid. "
1077 "File has been deleted\e\n");
1078 continue;
1079 } else {
1080 perror("open_by_handle_at");
1081 exit(EXIT_FAILURE);
1082 }
0a4db6dc
MB
1083 }
1084
6f10bd32
MK
1085 snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d",
1086 event_fd);
0a4db6dc 1087
817c8240 1088 /* Retrieve and print the path of the modified dentry */
87d12b1b 1089
5ff63f51
MK
1090 path_len = readlink(procfd_path, path, sizeof(path) \- 1);
1091 if (path_len == \-1) {
0a4db6dc
MB
1092 perror("readlink");
1093 exit(EXIT_FAILURE);
1094 }
1095
5ff63f51 1096 path[path_len] = \(aq\e\0\(aq;
525b88e1 1097 printf("\etDirectory \(aq%s\(aq has been modified.\e\n", path);
0a4db6dc
MB
1098
1099 /* Close associated file descriptor for this event */
5ff63f51 1100
0a4db6dc
MB
1101 close(event_fd);
1102 }
1103
5ff63f51 1104 printf("All events processed successfully. Program exiting.\e\n");
0a4db6dc
MB
1105 exit(EXIT_SUCCESS);
1106}
1107.EE
d282bb24 1108.SH SEE ALSO
597aaea2
HS
1109.ad l
1110.BR fanotify_init (2),
1111.BR fanotify_mark (2),
1112.BR inotify (7)