* [PATCH 1/1 v2] fanotify: create manpages
@ 2014-04-24 20:18 Heinrich Schuchardt
[not found] ` <1398370691-13971-1-git-send-email-xypron.glpk-Mmb7MZpHnFY@public.gmane.org>
0 siblings, 1 reply; 4+ messages in thread
From: Heinrich Schuchardt @ 2014-04-24 20:18 UTC (permalink / raw)
To: Michael Kerrisk
Cc: linux-man-u79uwXL29TY76Z2rM5mHXA, Jan Kara, Eric Paris,
Heinrich Schuchardt
Hello Michael,
I applied all you request for changes, including the example code.
For fanotify_mark(2) you did not review the latest version:
It is flags and not mask that is not yet properly checked.
' I think that last sentence could go. FAN_ALL_INIT_FLAGS is non it sys/fanotify.h
' (only in the linux/ header file).
The definition of FAN_ALL_INIT_FLAGS is in
/include/uapi/linux/fanotify.h
like FAN_CLOEXEC.
Hence, it is also available in sys/fanotify.h
In a prior mail you wrote:
' ' +This length might be longer than the size of structure
' ' +.I fanotify_event_metadata.
'
' .IR fanotify_event_metadata .
'
' Also, here, I think you need to add a few words about *why* it might be longer.
' Otherwise the reader is left puzzled. (The *why* could eb a forward reference
' to some explanatory text lower in the page.)
I reworked the paragraph.
Best regards
Heinrich
Signed-off-by: Heinrich Schuchardt <xypron.glpk-Mmb7MZpHnFY@public.gmane.org>
---
man2/fanotify_init.2 | 207 ++++++++++++++++
man2/fanotify_mark.2 | 327 +++++++++++++++++++++++++
man7/fanotify.7 | 670 +++++++++++++++++++++++++++++++++++++++++++++++++++
man7/inotify.7 | 3 +-
4 files changed, 1206 insertions(+), 1 deletion(-)
create mode 100644 man2/fanotify_init.2
create mode 100644 man2/fanotify_mark.2
create mode 100644 man7/fanotify.7
diff --git a/man2/fanotify_init.2 b/man2/fanotify_init.2
new file mode 100644
index 0000000..3214d9e
--- /dev/null
+++ b/man2/fanotify_init.2
@@ -0,0 +1,207 @@
+.\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk-Mmb7MZpHnFY@public.gmane.org>
+.\"
+.\" %%%LICENSE_START(VERBATIM)
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of
+.\" this manual under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of
+.\" a permission notice identical to this one.
+.\"
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date. The author(s) assume.
+.\" no responsibility for errors or omissions, or for damages resulting.
+.\" from the use of the information contained herein. The author(s) may.
+.\" not have taken the same level of care in the production of this.
+.\" manual, which is licensed free of charge, as they might when working.
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" %%%LICENSE_END
+.TH FANOTIFY_INIT 2 2014-04-24 "Linux" "Linux Programmer's Manual"
+.SH NAME
+fanotify_init \- create and initialize fanotify group
+.SH SYNOPSIS
+.B #include <fcntl.h>
+.br
+.B #include <sys/fanotify.h>
+.sp
+.BI "int fanotify_init(unsigned int " flags ", unsigned int " event_f_flags );
+.SH DESCRIPTION
+For an overview of the fanotify API, see
+.BR fanotify (7).
+.PP
+.BR fanotify_init ()
+initializes a new fanotify group and returns a file descriptor for the event
+queue associated with the group.
+.PP
+The file descriptor is used in calls to
+.BR fanotify_mark (2)
+to specify the files, directories, and mounts for which fanotify events shall
+be created.
+These events are received by reading from the file descriptor.
+Some events are only informative, indicating that a file has been accessed.
+Other events can be used to control if another application may access a file
+or directory.
+Permission to access filesystem objects is granted by writing to the file
+descriptor.
+.PP
+Multiple programs may be using the fanotify interface at the same time to
+monitor the same files.
+.PP
+In the current implementation, the number of fanotify groups per user is
+limited to 128.
+This limit cannot be overridden.
+.PP
+Calling
+.BR fanotify_init ()
+requires the
+.B CAP_SYS_ADMIN
+capability.
+This constraint might be relaxed in future versions of the API.
+Therefore certain additional capability checks have been implemented as
+indicated below.
+.PP
+The
+.I flags
+argument contains a multi-bit field defining the notification class of the
+listening application and further single bit fields specifying the behavior of
+the file descriptor.
+.PP
+If multiple listeners for permission events exist, the notification class is
+used to establish the sequence in which the listeners receive the events.
+.PP
+Only one of the following values may be specified in
+.IR flags .
+.TP
+.B FAN_CLASS_PRE_CONTENT
+This value allows the receipt of events notifying that a file has been
+accessed and events for permission decisions if a file may be accessed.
+It is intended for event listeners that need to access files before they
+contain their final data.
+This notification class might be used by hierarchical storage managers, for
+example.
+.TP
+.B FAN_CLASS_CONTENT
+This value allows the receipt of events notifying that a file has been
+accessed and events for permission decisions if a file may be accessed.
+It is intended for event listeners that need to access files when they already
+contain their final content.
+This notification class might be used by malware detection programs, for
+example.
+.TP
+.B FAN_CLASS_NOTIF
+This is the default value.
+It does not need to be specified.
+This value only allows the receipt of events notifying that a file has been
+accessed.
+Permission decisions before the file is accessed are not possible.
+.PP
+Listeners with different notification classes will receive events in the
+sequence
+.BR FAN_CLASS_PRE_CONTENT ,
+.BR FAN_CLASS_CONTENT ,
+.BR FAN_CLASS_NOTIF .
+The order of notification for listeners of the same value is undefined.
+.PP
+The following bit mask values can be set additionally in
+.IR flags :
+.TP
+.B FAN_CLOEXEC
+This flag sets the close-on-exec flag
+.RB ( FD_CLOEXEC )
+on the new file descriptor.
+See the description of the
+.B O_CLOEXEC
+flag in
+.BR open (2).
+.TP
+.B FAN_NONBLOCK
+This flag enables the nonblocking flag
+.RB ( O_NONBLOCK )
+for the file descriptor.
+Reading from the file descriptor will not block.
+Instead, if no data is available in a call to
+.BR read (2)
+the error
+.B EAGAIN
+will occur.
+.TP
+.B FAN_UNLIMITED_QUEUE
+This flag removes the limit of 16384 events on the size of the event queue.
+It requires the
+.B CAP_SYS_ADMIN
+capability.
+.TP
+.B FAN_UNLIMITED_MARKS
+This flag removes the limit of 8192 marks.
+It requires the
+.B CAP_SYS_ADMIN
+capability.
+.PP
+The argument
+.I event_f_flags
+defines the file flags with which file descriptors for fanotify events shall
+be created.
+For explanations of possible values, see the argument
+.I flags
+of the
+.BR open (2)
+system call.
+Useful values are:
+.TP
+.B O_RDONLY
+This value allows only read access.
+.TP
+.B O_WRONLY
+This value allows only write access.
+.TP
+.B O_RDWR
+This value allows read and write access.
+.TP
+.B O_CLOEXEC
+This flag enables the close-on-exec flag for the file descriptor.
+.TP
+.B O_LARGEFILE
+This flag enables support for files exceeding 2 GB.
+Failing to set this flag will result in an
+.B EOVERFLOW
+error when trying to open a large file which is monitored by an fanotify group
+on a 32-bit system.
+.SH RETURN VALUE
+On success,
+.BR fanotify_init ()
+returns a new file descriptor.
+In case of an error, \-1 is returned, and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.TP
+.B EINVAL
+An invalid value was passed in
+.IR flags .
+.B FAN_ALL_INIT_FLAGS
+defines all allowable bits.
+.TP
+.B EMFILE
+The number of fanotify groups of the user exceeds 128.
+.TP
+.B ENOMEM
+The allocation of memory for the notification group failed.
+.TP
+.B EPERM
+The operation is not permitted because the caller lacks the
+.B CAP_SYS_ADMIN
+capability.
+.SH VERSIONS
+.BR fanotify_init ()
+was introduced in version 2.6.36 of the Linux kernel and enabled in version
+2.6.37.
+.SH "CONFORMING TO"
+This system call is Linux-specific.
+.SH "SEE ALSO"
+.BR fanotify_mark (2),
+.BR fanotify (7)
diff --git a/man2/fanotify_mark.2 b/man2/fanotify_mark.2
new file mode 100644
index 0000000..2975f4b
--- /dev/null
+++ b/man2/fanotify_mark.2
@@ -0,0 +1,327 @@
+.\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk-Mmb7MZpHnFY@public.gmane.org>
+.\"
+.\" %%%LICENSE_START(VERBATIM)
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of
+.\" this manual under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of
+.\" a permission notice identical to this one.
+.\"
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date. The author(s) assume.
+.\" no responsibility for errors or omissions, or for damages resulting.
+.\" from the use of the information contained herein. The author(s) may.
+.\" not have taken the same level of care in the production of this.
+.\" manual, which is licensed free of charge, as they might when working.
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" %%%LICENSE_END
+.TH FANOTIFY_MARK 2 2014-04-24 "Linux" "Linux Programmer's Manual"
+.SH NAME
+fanotify_mark \- add, remove, or modify an fanotify mark on a filesystem
+object
+.SH SYNOPSIS
+.nf
+.B #include <sys/fanotify.h>
+.sp
+.BI "int fanotify_mark(int " fanotify_fd ", unsigned int " flags ,
+.BI " uint64_t " mask ", int " dirfd ,
+.BI " const char *" pathname );
+.fi
+.SH DESCRIPTION
+For an overview of the fanotify API, see
+.BR fanotify (7).
+.PP
+.BR fanotify_mark (2)
+adds, removes, or modifies an fanotify mark on a filesystem.
+.PP
+The caller must have read permission on the filesystem object that is to be
+marked.
+.PP
+The
+.I fanotify_fd
+argument is the file descriptor returned by
+.BR fanotify_init (2).
+.PP
+.I flags
+is a bit mask describing the modification to perform.
+It must include exactly one of the following values:
+.TP
+.B FAN_MARK_ADD
+The events in
+.I mask
+will be added to the mark mask (or to the ignore mask).
+.I mask
+must be nonempty or the error
+.B EINVAL
+will occur.
+.TP
+.B FAN_MARK_REMOVE
+The events in argument
+.I mask
+will be removed from the mark mask (or from the ignore mask).
+.I mask
+must be nonempty or the error
+.B EINVAL
+will occur.
+.TP
+.B FAN_MARK_FLUSH
+Remove either all mount or non-mount marks from the fanotify group.
+If
+.I flag
+contains
+.BR FAN_MARK_MOUNT ,
+all marks for mounts are removed from the group.
+Otherwise, all marks for directories and files are removed.
+No other flag but
+.B FAN_MARK_MOUNT
+can be used in conjunction with
+.BR FAN_MARK_FLUSH .
+.I mask
+is ignored.
+.PP
+If none of the values above is specified, or more than one is specified, the
+call fails with the error
+.BR EINVAL .
+.PP
+In addition,
+.I flags
+may contain zero or more of the following:
+.TP
+.B FAN_MARK_DONT_FOLLOW
+If
+.I pathname
+is a symbolic link, mark the link itself, rather than the file to which it
+refers.
+(By default,
+.BR fanotify_mark ()
+dereferences
+.I pathname
+if it is a symbolic link.)
+.TP
+.B FAN_MARK_ONLYDIR
+If the filesystem object to be marked is not a directory, the error
+.B ENOTDIR
+shall be raised.
+.TP
+.B FAN_MARK_MOUNT
+The
+.I pathname
+indicates a mount point to be marked.
+If the path is not itself a mount point, the mount point containing the path
+will be marked.
+All directories, subdirectories, and the contained files of the mount point
+will be monitored.
+.TP
+.B FAN_MARK_IGNORED_MASK
+The events in
+.I mask
+shall be added to or removed from the ignore mask.
+.TP
+.B FAN_MARK_IGNORED_SURV_MODIFY
+The ignore mask shall survive modify events.
+If this flag is not set, the ignore mask is cleared when a modify event occurs
+for the ignored file or directory.
+.PP
+.I mask
+defines which events shall be listened to (or which shall be ignored).
+It is a bit mask composed of the following values:
+.TP
+.B FAN_ACCESS
+Create an event when a file or directory (but see BUGS) is accessed (read).
+.TP
+.B FAN_MODIFY
+Create an event when a file is modified (write).
+.TP
+.B FAN_CLOSE_WRITE
+Create an event when a writable file is closed.
+.TP
+.B FAN_CLOSE_NOWRITE
+Create an event when a read-only file or directory is closed.
+.TP
+.B FAN_OPEN
+Create an event when a file or directory is opened.
+.TP
+.B FAN_OPEN_PERM
+Create an event when a permission to open a file or directory is requested.
+An fanotify file descriptor created with
+.B FAN_CLASS_PRE_CONTENT
+or
+.B FAN_CLASS_CONTENT
+is required.
+.TP
+.B FAN_ACCESS_PERM
+Create an event when a permission to read a file or directory is requested.
+An fanotify file descriptor created with
+.B FAN_CLASS_PRE_CONTENT
+or
+.B FAN_CLASS_CONTENT
+is required.
+.TP
+.B FAN_ONDIR
+Events for directories shall be created, for example when
+.BR opendir (2),
+.BR readdir (2)
+(but see BUGS), and
+.BR closedir (2)
+are called.
+Without this flag only events for files are created.
+.TP
+.B FAN_EVENT_ON_CHILD
+Events for the immediate children of marked directories shall be created.
+The flag has no effect when marking mounts.
+Note that events are not generated for children of the subdirectories
+of marked directories.
+To monitor complete directory trees it is necessary to mark the relevant
+mount.
+.PP
+The following composed value is defined:
+.TP
+.B FAN_CLOSE
+A file is closed
+.RB ( FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE ).
+.PP
+The filesystem object to be marked is determined by the file descriptor
+.I dirfd
+and the pathname specified in
+.IR pathname :
+.IP * 3
+If
+.I pathname
+is NULL,
+.I dirfd
+defines the filesystem object to be marked.
+.IP *
+If
+.I pathname
+is NULL, and
+.I dirfd
+takes the special value
+.BR AT_FDCWD ,
+the current working directory is to be marked.
+.IP *
+If
+.I pathname
+is absolute, it defines the filesystem object to be marked, and
+.I dirfd
+is ignored.
+.IP *
+If
+.I pathname
+is relative, and
+.I dirfd
+does not have the value
+.BR AT_FDCWD ,
+then the filesystem object to be marked is determined by interpreting
+.I pathname
+relative the directory referred to by
+.IR dirfd .
+.IP *
+If
+.I pathname
+is relative, and
+.I dirfd
+has the value
+.BR AT_FDCWD,
+then the filesystem object to be marked is determined by interpreting
+.I pathname
+relative the current working directory.
+.SH RETURN VALUE
+On success,
+.BR fanotify_mark ()
+returns 0.
+In case of an error, \-1 is returned, and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.TP
+.B EBADF
+An invalid file descriptor was passed in
+.IR fanotify_fd .
+.TP
+.B EINVAL
+An invalid value was passed in
+.IR flags
+or
+.IR mask ,
+or
+.I fanotify_fd
+was not an fanotify file descriptor.
+.TP
+.B EINVAL
+The fanotify file descriptor was opened with
+.B FAN_CLASS_NOTIF
+and mask contains a flag for permission events
+.RB ( FAN_OPEN_PERM
+or
+.BR FAN_ACCESS_PERM ).
+.TP
+.B ENOENT
+The filesystem object indicated by
+.IR dirfd
+and
+.IR pathname
+does not exist.
+This error also occurs when trying to remove a mark from an object which is not
+marked.
+.TP
+.B ENOMEM
+The necessary memory could not be allocated.
+.TP
+.B ENOSPC
+The number of marks exceeds the limit of 8192 and
+.B FAN_UNLIMITED_MARKS
+was not specified in the call to
+.BR fanotify_init (2).
+.TP
+.B ENOTDIR
+.I flags
+contains
+.BR FAN_MARK_ONLYDIR ,
+and
+.I dirfd
+and
+.I pathname
+do not specify a directory.
+.SH VERSIONS
+.BR fanotify_mark ()
+was introduced in version 2.6.36 of the Linux kernel and enabled in version
+2.6.37.
+.SH CONFORMING TO
+This system call is Linux-specific.
+.SH BUGS
+As of Linux 3.15,
+the following bugs exist:
+.IP * 3
+.\" FIXME: Patch is in next-20140424.
+If
+.I flags
+contains
+.BR FAN_MARK_FLUSH ,
+.I dfd
+and
+.I pathname
+must indicate a valid path.
+This path is not used.
+.IP *
+.\" FIXME: Patch is in next-20140424.
+.BR readdir (2)
+does not result in a
+.B FAN_ACCESS
+event.
+.IP *
+.\" FIXME: Patch proposed.
+If
+.BR fanotify_mark (2)
+is called with
+.B FAN_MARK_FLUSH,
+.I flags
+is not checked for invalid values.
+.SH SEE ALSO
+.BR fanotify_init (2),
+.BR fanotify (7)
diff --git a/man7/fanotify.7 b/man7/fanotify.7
new file mode 100644
index 0000000..efb20bb
--- /dev/null
+++ b/man7/fanotify.7
@@ -0,0 +1,670 @@
+.\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk-Mmb7MZpHnFY@public.gmane.org>
+.\"
+.\" %%%LICENSE_START(VERBATIM)
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of
+.\" this manual under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of
+.\" a permission notice identical to this one.
+.\"
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date. The author(s) assume.
+.\" no responsibility for errors or omissions, or for damages resulting.
+.\" from the use of the information contained herein. The author(s) may.
+.\" not have taken the same level of care in the production of this.
+.\" manual, which is licensed free of charge, as they might when working.
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" %%%LICENSE_END
+.TH FANOTIFY 7 2014-04-24 "Linux" "Linux Programmer's Manual"
+.SH NAME
+fanotify \- monitoring filesystem events
+.SH DESCRIPTION
+The
+.B fanotify
+API provides notification and interception of filesystem events.
+Use cases include virus scanning and hierarchical storage management.
+Currently, only a limited set of events is supported.
+In particular there is no support for create, delete, and move events.
+
+Additional capabilities compared to the
+.BR inotify (7)
+API are monitoring of complete mounts, access permission decisions, and the
+possibility to read or modify files before access by other applications.
+
+The following system calls are used with this API:
+.BR fanotify_init (2),
+.BR fanotify_mark (2),
+.BR poll (2),
+.BR ppoll (2),
+.BR read (2),
+.BR write (2),
+and
+.BR close (2).
+.PP
+.BR fanotify_init (2)
+creates and initializes an fanotify notification group and returns a file
+descriptor referring to it.
+.PP
+An fanotify notification group is an internal object of the kernel which holds
+a list of files, directories, and mount points for which events shall be
+created.
+.PP
+For each entry in an fanotify notification group, two bit masks exist.
+One mask (the mark mask) defines file activities for which an event shall be
+created.
+Another mask (the ignore mask) defines activities for which no event shall be
+generated.
+Having these two types of masks permits a mount point or directory to be
+marked for receiving events, while at the same time ignoring events for
+specific objects under that mount point or directory.
+.PP
+A possible usage of the ignore mask is for a file cache.
+Events of interest for a file cache are modification of a file and closing
+of the same.
+Hence, the cached directory or mount point is to be marked to receive these
+events.
+After receiving the first event informing that a file has been modified, the
+corresponding cache entry will be invalidated.
+No further modification events for this file are of interest until the file is
+closed.
+Hence, the modify event can be added to the ignore mask.
+Upon receiving the closed event, the modify event can be removed from the
+ignore mask and the file cache entry can be updated.
+.PP
+The entries in the fanotify notification groups refer to files and directories
+via their inode number and to mounts via their mount ID.
+If files or directories are renamed or moved, the respective entries survive.
+If files or directories are deleted or mounts are unmounted, the corresponding
+entries are deleted.
+.PP
+Two types of events exist: notification events and permission events.
+Notification events are only informative and require no action to be taken by
+the receiving application except for closing the file descriptor passed in the
+event.
+Permission events are requests to the receiving application to decide whether
+permission for a file access shall be granted.
+For these events, the recipient must write a response which decides whether
+access is granted or not.
+.PP
+When all file descriptors referring to the fanotify notification group are
+closed, the fanotify group is released and its resources are freed for reuse by
+the kernel.
+.PP
+.BR fanotify_mark (2)
+adds a file, directory, or mount to the group and specifies which events
+shall be reported (or ignored), or removes or modifies such an entry.
+.PP
+When an fanotify event occurs, the fanotify file descriptor indicates as
+readable when passed to
+.BR epoll (7),
+.BR poll (2),
+or
+.BR select (2).
+.PP
+All events for an fanotify group are collected in a queue.
+Consecutive events for the same filesystem object and originating from the
+same process may be merged into a single event, with the exception that two
+permission events are never merged into one queue entry.
+Queue entries for notification events are removed when the event has been
+read.
+Queue entries for permission events are removed when the permission
+decision has been taken by writing to the fanotify file descriptor.
+.PP
+Calling
+.BR read (2)
+for the file descriptor returned by
+.BR fanotify_init (2)
+blocks (if the flag
+.B FAN_NONBLOCK
+is not specified in the call to
+.BR fanotify_init (2))
+until either a file event occurs or the call is interrupted by a signal
+(see
+.BR signal (7)).
+
+The return value of
+.BR read (2)
+is the length of the filled buffer, or \-1 in case of an error.
+After a successful
+.BR read(2),
+the read buffer contains one or more of the following structures:
+
+.in +4n
+.nf
+struct fanotify_event_metadata {
+ __u32 event_len;
+ __u8 vers;
+ __u8 reserved;
+ __u16 metadata_len;
+ __aligned_u64 mask;
+ __s32 fd;
+ __s32 pid;
+};
+.fi
+.in
+
+.TP 15
+.I event_len
+This is the length of the data for the current event and the offset to the next
+event in the buffer.
+In the current implementation the value of
+.I event_len
+is always
+.BR FAN_EVENT_METADATA_LEN .
+In principal the API design would allow to return variable length structures.
+Therefore, and for performance reasons, it is recommended to use a larger
+buffer size when reading, for example 4096 bytes.
+.TP
+.I vers
+This field holds a version number for the structures.
+It must be compared to
+.B FANOTIFY_METADATA_VERSION
+to verify that the structures at runtime match the structures at compile
+time.
+In case of a mismatch, the application should abandon trying to use the
+fanotify file descriptor.
+.TP
+.I reserved
+This field is not used.
+.TP
+.I metadata_len
+This is the length of the structure.
+The field was introduced to facilitate the implementation of optional headers
+per event type.
+No such optional headers exist in the current implementation.
+.TP
+.I mask
+This is a bit mask describing the event.
+.TP
+.I fd
+This is an open file descriptor for the object being accessed, or
+.B FAN_NOFD
+if a queue overflow occurred.
+The file descriptor can be used to access the contents of the monitored file or
+directory.
+It has internal the flag
+.B FMODE_NONOTIFY
+set.
+This flag suppresses fanotify event generation.
+Hence, when the receiver of the fanotify event accesses the notified file or
+directory using this file descriptor, no additional events will be created.
+The reading application is responsible for closing the file descriptor.
+.TP
+.I pid
+This is the ID of the process that caused the event.
+A program listening to fanotify events can compare this PID to the PID returned
+by
+.BR getpid (2),
+to determine whether the event is caused by the listener itself, or is due to a
+file access by another program.
+.PP
+The bit mask in
+.I mask
+signals which events have occurred for a single filesystem object.
+More than one of the following flags can be set at once in the bit mask.
+.TP
+.B FAN_ACCESS
+A file or a directory (but see BUGS) was accessed (read).
+.TP
+.B FAN_OPEN
+A file or a directory was opened.
+.TP
+.B FAN_MODIFY
+A file was modified.
+.TP
+.B FAN_CLOSE_WRITE
+A file that was opened for writing
+.RB ( O_WRONLY
+or
+.BR O_RDWR )
+was closed.
+.TP
+.B FAN_CLOSE_NOWRITE
+A file that was only opened for reading
+.RB ( O_RDONLY )
+or a directory was closed.
+.TP
+.B FAN_Q_OVERFLOW
+The event queue exceeded the limit of 16384 entries.
+This limit can be overridden in the call to
+.BR fanotify_init (2)
+by setting the flag
+.BR FAN_UNLIMITED_QUEUE .
+.TP
+.B FAN_ACCESS_PERM
+An application wants to read a file or directory, for example using
+.BR read (2)
+or
+.BR readdir (2).
+The reader must write a response that determines whether the permission to
+access the filesystem object shall be granted.
+.TP
+.B FAN_OPEN_PERM
+An application wants to open a file or directory.
+The reader must write a response that determines whether the permission to
+open the filesystem object shall be granted.
+.PP
+To check for any close event, the following bit mask may be used:
+.TP
+.B FAN_CLOSE
+A file was closed
+(FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE).
+.PP
+The following macros are provided to iterate over a buffer containing fanotify
+event metadata returned by
+.BR read (2)
+from an fanotify file descriptor.
+.TP
+.B FAN_EVENT_OK(meta, len)
+This macro checks the remaining length
+.I len
+of the buffer
+.I meta
+against the length of the metadata structure and the
+.I event_len
+field of the first metadata structure in the buffer.
+.TP
+.B FAN_EVENT_NEXT(meta, len)
+This macro sets the pointer
+.I meta
+to the next metadata structure using the length indicated in the
+.I event_len
+field of the metadata structure and reduces the remaining length of the
+buffer
+.IT len .
+.PP
+For permission events, the application must
+.BR write (2)
+a structure of the following form to the
+.B fanotify
+file descriptor:
+
+.in +4n
+.nf
+struct fanotify_response {
+ __s32 fd;
+ __u32 response;
+};
+.fi
+.in
+
+.TP 15
+.I fd
+This is the file descriptor from the structure
+.IR fanotify_event_metadata .
+.TP
+.I response
+This field indicates whether or not the permission is to be granted.
+Its value must be either
+.B FAN_ALLOW
+to allow the file operation or
+.B FAN_DENY
+to deny the file operation.
+.PP
+If access has been denied, the requesting application call will receive an
+error
+.BR EPERM .
+.PP
+To end listening, it is sufficient to
+.BR close (2)
+the fanotify file descriptor.
+The outstanding permission events will be set to allowed, and all resources
+will be returned to the kernel.
+.PP
+The file
+.I /proc/<pid>/fdinfo/<fd>
+contains information about fanotify marks for file descriptor
+.I fd
+of process
+.IR pid .
+See
+.I Documentation/filesystems/proc.txt
+for details.
+.SH ERRORS
+In addition to the usual errors for
+.BR read (2),
+the following errors can occur when reading from the fanotify file descriptor:
+.TP
+.B EINVAL
+The buffer is too short to hold the event.
+.TP
+.B EMFILE
+The per-process limit on the number of open files has been reached.
+See the description of
+.B RLIMIT_NOFILE
+in
+.BR getrlimit (2).
+.TP
+.B ENFILE
+The system-wide limit on the number of open files has been reached.
+See
+.I /proc/sys/fs/file-max
+in
+.BR proc (5).
+.TP
+.B ETXTBSY
+A write enabled file descriptor shall be created for a file that is executing.
+This error is returned by
+.BR read (2),
+if
+.B O_RDWR
+or
+.B O_WRONLY
+was specified in the
+.I event_f_flags
+argument when calling
+.BR fanotify_init (2)
+and the event occured for a monitored file that is currently being execuded.
+.PP
+In addition to the usual errors for
+.BR write (2),
+the following errors can occur when writing to the fanotify file descriptor:
+.TP
+.B EINVAL
+Fanotify access permissions are not enabled in the kernel configuration or the
+value of
+.I response
+in the response structure is not valid.
+.TP
+.B ENOENT
+The file descriptor
+.I fd
+in the response structure is not valid.
+This might occur because the file was already deleted by another thread or
+process.
+.SH VERSIONS
+The fanotify API was introduced in version 2.6.36 of the Linux kernel and
+enabled in version 2.6.37.
+Fdinfo support was added in version 3.8.
+.SH "CONFORMING TO"
+The fanotify API is Linux-specific.
+.SH NOTES
+The fanotify API is available only if the kernel was built with the
+.B CONFIG_FANOTIFY
+configuration option enabled.
+In addition, fanotify permission handling is available only if the
+.B CONFIG_FANOTIFY_ACCESS_PERMISSIONS
+configuration option is enabled.
+.SS Limitations and caveats
+Fanotify reports only events that a user-space program triggers through the
+filesystem API.
+As a result, it does not catch remote events that occur on network filesystems.
+.PP
+The fanotify API does not report file accesses and modifications that
+may occur because of
+.BR mmap (2),
+.BR msync (2),
+and
+.BR munmap (2).
+.PP
+Events for directories are created only if the directory itself is opened,
+read, and closed.
+Adding, removing, or changing children of a marked directory does not create
+events for the monitored directory itself.
+.PP
+Fanotify monitoring of directories is not recursive: to monitor subdirectories
+under a directory, additional marks must be created.
+(But note that the fanotify API provides no way of detecting when a
+subdirectory has been created under a marked directory, which makes recursive
+monitoring difficult.)
+Monitoring mounts offers the capability to monitor a whole directory tree.
+.PP
+The event queue can overflow.
+In this case, events are lost.
+.SH BUGS
+As of Linux 3.15,
+the following bugs existed:
+.IP * 3
+.\" FIXME: Patch is in linux-next-20140424.
+.BR readdir (2)
+does not create a
+.B FAN_ACCESS
+event.
+.IP *
+.\" FIXME: A patch was proposed.
+When an event is generated, no check is made to see whether the user ID of the
+receiving process has authorization to read or write the file before passing a
+file descriptor for that file in
+This poses a security risk, when the
+.B CAP_SYS_ADMIN
+capability is set for programs executed by unprivileged users.
+.SH EXAMPLE
+The following program demonstrates the usage of the fanotify API.
+It marks the mount passed as argument and waits for events of type
+.B FAN_PERM_OPEN
+and
+.BR FAN_CLOSE_WRITE .
+When a permission event occurs, a
+.B FAN_ALLOW
+response is given.
+.PP
+The following output was recorded while editing file
+.IR /home/user/temp/notes .
+Before the file was opened, a
+.B FAN_OPEN_PERM
+event occurred.
+After the file was closed, a
+.B FAN_CLOSE_WRITE
+event occurred.
+Execution of the program ends when the user presses the ENTER key.
+.SS Example output
+.in +4n
+.nf
+# ./fanotify_example /home
+Press enter key to terminate.
+Listening for events.
+FAN_OPEN_PERM: File /home/user/temp/notes
+FAN_CLOSE_WRITE: File /home/user/temp/notes
+
+Listening for events stopped.
+.fi
+.in
+.SS Program source
+.nf
+#define _GNU_SOURCE // needed for O_LARGEFILE
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/fanotify.h>
+#include <unistd.h>
+
+/* Read all available fanotify events from the file descriptor 'fd' */
+
+void
+handle_events(int fd)
+{
+ const struct fanotify_event_metadata *metadata;
+ char buf[4096];
+ ssize_t len;
+ char path[PATH_MAX];
+ ssize_t path_len;
+ char procfd_path[PATH_MAX];
+ struct fanotify_response response;
+
+ /* Loop while events can be read from fanotify file descriptor. */
+
+ for(;;) {
+
+ /* Read some events. */
+
+ len = read(fd, (void *) &buf, sizeof(buf));
+ if (len == \-1 && errno != EAGAIN) {
+ perror("read");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Check if end of available data reached. */
+
+ if (len <= 0)
+ break;
+
+ /* Point to the first event in the buffer. */
+
+ metadata = (struct fanotify_event_metadata *) buf;
+
+ /* Loop over all events in the buffer. */
+
+ while (FAN_EVENT_OK(metadata, len)) {
+
+ /* Check that run time and compile time structures
+ match. */
+
+ if (metadata\->vers != FANOTIFY_METADATA_VERSION) {
+ fprintf(stderr,
+ "Mismatch of fanotify metadata version.\\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Check that the event contains a file descriptor. */
+
+ if (metadata\->fd >= 0) {
+
+ /* Handle open permission event. */
+
+ if (metadata\->mask & FAN_OPEN_PERM) {
+ printf("FAN_OPEN_PERM: ");
+
+ /* Allow file to be opened. */
+
+ response.fd = metadata\->fd;
+ response.response = FAN_ALLOW;
+ write(fd, &response, sizeof(
+ struct fanotify_response));
+ }
+
+ /* Handle closing of writable file event. */
+
+ if (metadata\->mask & FAN_CLOSE_WRITE) {
+ printf("FAN_CLOSE_WRITE: ");
+ }
+
+ /* Determine path of the file accessed. */
+
+ snprintf(procfd_path, sizeof(procfd_path),
+ "/proc/self/fd/%d", metadata\->fd);
+ path_len = readlink(procfd_path, path,
+ sizeof(path) \- 1);
+ if (path_len == \-1) {
+ perror("readlink");
+ exit(EXIT_FAILURE);
+ }
+
+ path[path_len] = '\\0';
+ printf("File %s", path);
+
+ /* Close the file descriptor of the event. */
+
+ close(metadata\->fd);
+ printf("\\n");
+ }
+
+ /* Forward pointer to next event. */
+
+ metadata = FAN_EVENT_NEXT(metadata, len);
+ }
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ char buf;
+ int fd, poll_num;
+ nfds_t nfds;
+ struct pollfd fds[2];
+
+ /* Check mount point is supplied. */
+
+ if (argc != 2) {
+ printf("Usage: %s MOUNT\\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ printf("Press enter key to terminate.\\n");
+
+ /* Create the file descriptor for accessing the fanotify API. */
+
+ fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
+ O_RDONLY | O_LARGEFILE);
+ if (fd == \-1) {
+ perror("fanotify_init");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Mark the mount for
+ \- permission events before opening files
+ \- notification events after closing a write enabled
+ file descriptor. */
+
+ if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
+ FAN_OPEN_PERM | FAN_CLOSE_WRITE, \-1,
+ argv[1]) == \-1) {
+ perror("fanotify_mark");
+ close(fd);
+ exit(EXIT_FAILURE);
+ }
+
+ /* Prepare for polling. */
+
+ nfds = 2;
+
+ /* Console input. */
+
+ fds[0].fd = STDIN_FILENO;
+ fds[0].events = POLLIN;
+
+ /* Fanotify input. */
+
+ fds[1].fd = fd;
+ fds[1].events = POLLIN;
+
+ /* This is the loop to wait for incoming events. */
+
+ printf("Listening for events.\\n");
+ while (1) {
+ poll_num = poll(fds, nfds, \-1);
+ if (poll_num == \-1) {
+ if (errno == EINTR)
+ continue;
+ perror("poll");
+ exit(EXIT_FAILURE);
+ }
+ if (poll_num > 0) {
+ if (fds[0].revents & POLLIN) {
+
+ /* Console input is available. Empty stdin and quit. */
+
+ while (read(STDIN_FILENO, &buf, 1) > 0 && buf != '\\n')
+ continue;
+ break;
+ }
+ if (fds[1].revents & POLLIN) {
+
+ /* Fanotify events are available. */
+
+ handle_events(fd);
+ }
+ }
+ }
+
+ /* Close fanotify file descriptor. */
+
+ close(fd);
+ printf("Listening for events stopped.\\n");
+ return EXIT_SUCCESS;
+}
+.fi
+.SH "SEE ALSO"
+.ad l
+.BR fanotify_init (2),
+.BR fanotify_mark (2),
+.BR inotify (7)
diff --git a/man7/inotify.7 b/man7/inotify.7
index 17462c6..da76b2a 100644
--- a/man7/inotify.7
+++ b/man7/inotify.7
@@ -760,7 +760,8 @@ unread event.
.BR inotify_init1 (2),
.BR inotify_rm_watch (2),
.BR read (2),
-.BR stat (2)
+.BR stat (2),
+.BR fanotify (7)
.IR Documentation/filesystems/inotify.txt
in the Linux kernel source tree
--
1.9.2
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 4+ messages in thread[parent not found: <1398370691-13971-1-git-send-email-xypron.glpk-Mmb7MZpHnFY@public.gmane.org>]
* Re: [PATCH 1/1 v2] fanotify: create manpages [not found] ` <1398370691-13971-1-git-send-email-xypron.glpk-Mmb7MZpHnFY@public.gmane.org> @ 2014-04-25 10:43 ` Michael Kerrisk (man-pages) [not found] ` <535A3C3E.8050400-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 0 siblings, 1 reply; 4+ messages in thread From: Michael Kerrisk (man-pages) @ 2014-04-25 10:43 UTC (permalink / raw) To: Heinrich Schuchardt Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w, linux-man-u79uwXL29TY76Z2rM5mHXA, Jan Kara, Eric Paris Hello Heinrich, I have merged the pages. You can find them in git. From here on in please send any changes as patches (but make logically separate changes into separate patches). I made many minor edits and added a few words and headings in various places. In general, though, there was no substantial change to the text. You can review my individual changes using: git log -p --reverse f75d27e6b..master Some things I'd like you to check or fix: * Please review 679a078389 (ETXTBUSY) * Please review 3b32c70be9 (FAN_MARK_FLUSH bug) * See the FIXME in the example code in fanotify(7). * The readdir(2) / FAN_ACCESS bug is described in fanotify(7) and fanotify_mark(7). It only needs to be in one of the pages. Could you patch to remove whichever you think should be removed. An earlier question that I believe is still not resolved: [[ > ' Now I know that I earlier said that FAN_ONDIR and FAN_EVENT_ON_CHILD > ' belong in the input events for fanotify_mark(), not here in the > ' returned events. Or at least, as far as I can tell, they can't be > ' in the returned events--but can you confirm this please. > Where did you find FAN_ONDIR and FAN_EVENT_ON_CHILD in fanotify.7? They were in an earlier version in fanotify.7, if I recall correctly. Anyway, my point is: have you confirmed that FAN_ONDIR and FAN_EVENT_ON_CHILD are only input flags, and can't be returned as output event flags? ]] Once we've finished those tweaks, we can pester Eric for a review. Thank you these excellent pages, Heinrich. And on top of that, you've found and patched a number bugs in the API. All in all, a magnificent piece of work. Cheers, Michael On 04/24/2014 10:18 PM, Heinrich Schuchardt wrote: > Hello Michael, > > I applied all you request for changes, including the example code. > > For fanotify_mark(2) you did not review the latest version: > It is flags and not mask that is not yet properly checked. > > ' I think that last sentence could go. FAN_ALL_INIT_FLAGS is non it sys/fanotify.h > ' (only in the linux/ header file). > > The definition of FAN_ALL_INIT_FLAGS is in > /include/uapi/linux/fanotify.h > like FAN_CLOEXEC. > > Hence, it is also available in sys/fanotify.h > > In a prior mail you wrote: > > ' ' +This length might be longer than the size of structure > ' ' +.I fanotify_event_metadata. > ' > ' .IR fanotify_event_metadata . > ' > ' Also, here, I think you need to add a few words about *why* it might be longer. > ' Otherwise the reader is left puzzled. (The *why* could eb a forward reference > ' to some explanatory text lower in the page.) > > I reworked the paragraph. > > Best regards > > Heinrich > > Signed-off-by: Heinrich Schuchardt <xypron.glpk-Mmb7MZpHnFY@public.gmane.org> > --- > man2/fanotify_init.2 | 207 ++++++++++++++++ > man2/fanotify_mark.2 | 327 +++++++++++++++++++++++++ > man7/fanotify.7 | 670 +++++++++++++++++++++++++++++++++++++++++++++++++++ > man7/inotify.7 | 3 +- > 4 files changed, 1206 insertions(+), 1 deletion(-) > create mode 100644 man2/fanotify_init.2 > create mode 100644 man2/fanotify_mark.2 > create mode 100644 man7/fanotify.7 > > diff --git a/man2/fanotify_init.2 b/man2/fanotify_init.2 > new file mode 100644 > index 0000000..3214d9e > --- /dev/null > +++ b/man2/fanotify_init.2 > @@ -0,0 +1,207 @@ > +.\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk-Mmb7MZpHnFY@public.gmane.org> > +.\" > +.\" %%%LICENSE_START(VERBATIM) > +.\" Permission is granted to make and distribute verbatim copies of this > +.\" manual provided the copyright notice and this permission notice are > +.\" preserved on all copies. > +.\" > +.\" Permission is granted to copy and distribute modified versions of > +.\" this manual under the conditions for verbatim copying, provided that > +.\" the entire resulting derived work is distributed under the terms of > +.\" a permission notice identical to this one. > +.\" > +.\" Since the Linux kernel and libraries are constantly changing, this > +.\" manual page may be incorrect or out-of-date. The author(s) assume. > +.\" no responsibility for errors or omissions, or for damages resulting. > +.\" from the use of the information contained herein. The author(s) may. > +.\" not have taken the same level of care in the production of this. > +.\" manual, which is licensed free of charge, as they might when working. > +.\" professionally. > +.\" > +.\" Formatted or processed versions of this manual, if unaccompanied by > +.\" the source, must acknowledge the copyright and authors of this work. > +.\" %%%LICENSE_END > +.TH FANOTIFY_INIT 2 2014-04-24 "Linux" "Linux Programmer's Manual" > +.SH NAME > +fanotify_init \- create and initialize fanotify group > +.SH SYNOPSIS > +.B #include <fcntl.h> > +.br > +.B #include <sys/fanotify.h> > +.sp > +.BI "int fanotify_init(unsigned int " flags ", unsigned int " event_f_flags ); > +.SH DESCRIPTION > +For an overview of the fanotify API, see > +.BR fanotify (7). > +.PP > +.BR fanotify_init () > +initializes a new fanotify group and returns a file descriptor for the event > +queue associated with the group. > +.PP > +The file descriptor is used in calls to > +.BR fanotify_mark (2) > +to specify the files, directories, and mounts for which fanotify events shall > +be created. > +These events are received by reading from the file descriptor. > +Some events are only informative, indicating that a file has been accessed. > +Other events can be used to control if another application may access a file > +or directory. > +Permission to access filesystem objects is granted by writing to the file > +descriptor. > +.PP > +Multiple programs may be using the fanotify interface at the same time to > +monitor the same files. > +.PP > +In the current implementation, the number of fanotify groups per user is > +limited to 128. > +This limit cannot be overridden. > +.PP > +Calling > +.BR fanotify_init () > +requires the > +.B CAP_SYS_ADMIN > +capability. > +This constraint might be relaxed in future versions of the API. > +Therefore certain additional capability checks have been implemented as > +indicated below. > +.PP > +The > +.I flags > +argument contains a multi-bit field defining the notification class of the > +listening application and further single bit fields specifying the behavior of > +the file descriptor. > +.PP > +If multiple listeners for permission events exist, the notification class is > +used to establish the sequence in which the listeners receive the events. > +.PP > +Only one of the following values may be specified in > +.IR flags . > +.TP > +.B FAN_CLASS_PRE_CONTENT > +This value allows the receipt of events notifying that a file has been > +accessed and events for permission decisions if a file may be accessed. > +It is intended for event listeners that need to access files before they > +contain their final data. > +This notification class might be used by hierarchical storage managers, for > +example. > +.TP > +.B FAN_CLASS_CONTENT > +This value allows the receipt of events notifying that a file has been > +accessed and events for permission decisions if a file may be accessed. > +It is intended for event listeners that need to access files when they already > +contain their final content. > +This notification class might be used by malware detection programs, for > +example. > +.TP > +.B FAN_CLASS_NOTIF > +This is the default value. > +It does not need to be specified. > +This value only allows the receipt of events notifying that a file has been > +accessed. > +Permission decisions before the file is accessed are not possible. > +.PP > +Listeners with different notification classes will receive events in the > +sequence > +.BR FAN_CLASS_PRE_CONTENT , > +.BR FAN_CLASS_CONTENT , > +.BR FAN_CLASS_NOTIF . > +The order of notification for listeners of the same value is undefined. > +.PP > +The following bit mask values can be set additionally in > +.IR flags : > +.TP > +.B FAN_CLOEXEC > +This flag sets the close-on-exec flag > +.RB ( FD_CLOEXEC ) > +on the new file descriptor. > +See the description of the > +.B O_CLOEXEC > +flag in > +.BR open (2). > +.TP > +.B FAN_NONBLOCK > +This flag enables the nonblocking flag > +.RB ( O_NONBLOCK ) > +for the file descriptor. > +Reading from the file descriptor will not block. > +Instead, if no data is available in a call to > +.BR read (2) > +the error > +.B EAGAIN > +will occur. > +.TP > +.B FAN_UNLIMITED_QUEUE > +This flag removes the limit of 16384 events on the size of the event queue. > +It requires the > +.B CAP_SYS_ADMIN > +capability. > +.TP > +.B FAN_UNLIMITED_MARKS > +This flag removes the limit of 8192 marks. > +It requires the > +.B CAP_SYS_ADMIN > +capability. > +.PP > +The argument > +.I event_f_flags > +defines the file flags with which file descriptors for fanotify events shall > +be created. > +For explanations of possible values, see the argument > +.I flags > +of the > +.BR open (2) > +system call. > +Useful values are: > +.TP > +.B O_RDONLY > +This value allows only read access. > +.TP > +.B O_WRONLY > +This value allows only write access. > +.TP > +.B O_RDWR > +This value allows read and write access. > +.TP > +.B O_CLOEXEC > +This flag enables the close-on-exec flag for the file descriptor. > +.TP > +.B O_LARGEFILE > +This flag enables support for files exceeding 2 GB. > +Failing to set this flag will result in an > +.B EOVERFLOW > +error when trying to open a large file which is monitored by an fanotify group > +on a 32-bit system. > +.SH RETURN VALUE > +On success, > +.BR fanotify_init () > +returns a new file descriptor. > +In case of an error, \-1 is returned, and > +.I errno > +is set to indicate the error. > +.SH ERRORS > +.TP > +.B EINVAL > +An invalid value was passed in > +.IR flags . > +.B FAN_ALL_INIT_FLAGS > +defines all allowable bits. > +.TP > +.B EMFILE > +The number of fanotify groups of the user exceeds 128. > +.TP > +.B ENOMEM > +The allocation of memory for the notification group failed. > +.TP > +.B EPERM > +The operation is not permitted because the caller lacks the > +.B CAP_SYS_ADMIN > +capability. > +.SH VERSIONS > +.BR fanotify_init () > +was introduced in version 2.6.36 of the Linux kernel and enabled in version > +2.6.37. > +.SH "CONFORMING TO" > +This system call is Linux-specific. > +.SH "SEE ALSO" > +.BR fanotify_mark (2), > +.BR fanotify (7) > diff --git a/man2/fanotify_mark.2 b/man2/fanotify_mark.2 > new file mode 100644 > index 0000000..2975f4b > --- /dev/null > +++ b/man2/fanotify_mark.2 > @@ -0,0 +1,327 @@ > +.\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk-Mmb7MZpHnFY@public.gmane.org> > +.\" > +.\" %%%LICENSE_START(VERBATIM) > +.\" Permission is granted to make and distribute verbatim copies of this > +.\" manual provided the copyright notice and this permission notice are > +.\" preserved on all copies. > +.\" > +.\" Permission is granted to copy and distribute modified versions of > +.\" this manual under the conditions for verbatim copying, provided that > +.\" the entire resulting derived work is distributed under the terms of > +.\" a permission notice identical to this one. > +.\" > +.\" Since the Linux kernel and libraries are constantly changing, this > +.\" manual page may be incorrect or out-of-date. The author(s) assume. > +.\" no responsibility for errors or omissions, or for damages resulting. > +.\" from the use of the information contained herein. The author(s) may. > +.\" not have taken the same level of care in the production of this. > +.\" manual, which is licensed free of charge, as they might when working. > +.\" professionally. > +.\" > +.\" Formatted or processed versions of this manual, if unaccompanied by > +.\" the source, must acknowledge the copyright and authors of this work. > +.\" %%%LICENSE_END > +.TH FANOTIFY_MARK 2 2014-04-24 "Linux" "Linux Programmer's Manual" > +.SH NAME > +fanotify_mark \- add, remove, or modify an fanotify mark on a filesystem > +object > +.SH SYNOPSIS > +.nf > +.B #include <sys/fanotify.h> > +.sp > +.BI "int fanotify_mark(int " fanotify_fd ", unsigned int " flags , > +.BI " uint64_t " mask ", int " dirfd , > +.BI " const char *" pathname ); > +.fi > +.SH DESCRIPTION > +For an overview of the fanotify API, see > +.BR fanotify (7). > +.PP > +.BR fanotify_mark (2) > +adds, removes, or modifies an fanotify mark on a filesystem. > +.PP > +The caller must have read permission on the filesystem object that is to be > +marked. > +.PP > +The > +.I fanotify_fd > +argument is the file descriptor returned by > +.BR fanotify_init (2). > +.PP > +.I flags > +is a bit mask describing the modification to perform. > +It must include exactly one of the following values: > +.TP > +.B FAN_MARK_ADD > +The events in > +.I mask > +will be added to the mark mask (or to the ignore mask). > +.I mask > +must be nonempty or the error > +.B EINVAL > +will occur. > +.TP > +.B FAN_MARK_REMOVE > +The events in argument > +.I mask > +will be removed from the mark mask (or from the ignore mask). > +.I mask > +must be nonempty or the error > +.B EINVAL > +will occur. > +.TP > +.B FAN_MARK_FLUSH > +Remove either all mount or non-mount marks from the fanotify group. > +If > +.I flag > +contains > +.BR FAN_MARK_MOUNT , > +all marks for mounts are removed from the group. > +Otherwise, all marks for directories and files are removed. > +No other flag but > +.B FAN_MARK_MOUNT > +can be used in conjunction with > +.BR FAN_MARK_FLUSH . > +.I mask > +is ignored. > +.PP > +If none of the values above is specified, or more than one is specified, the > +call fails with the error > +.BR EINVAL . > +.PP > +In addition, > +.I flags > +may contain zero or more of the following: > +.TP > +.B FAN_MARK_DONT_FOLLOW > +If > +.I pathname > +is a symbolic link, mark the link itself, rather than the file to which it > +refers. > +(By default, > +.BR fanotify_mark () > +dereferences > +.I pathname > +if it is a symbolic link.) > +.TP > +.B FAN_MARK_ONLYDIR > +If the filesystem object to be marked is not a directory, the error > +.B ENOTDIR > +shall be raised. > +.TP > +.B FAN_MARK_MOUNT > +The > +.I pathname > +indicates a mount point to be marked. > +If the path is not itself a mount point, the mount point containing the path > +will be marked. > +All directories, subdirectories, and the contained files of the mount point > +will be monitored. > +.TP > +.B FAN_MARK_IGNORED_MASK > +The events in > +.I mask > +shall be added to or removed from the ignore mask. > +.TP > +.B FAN_MARK_IGNORED_SURV_MODIFY > +The ignore mask shall survive modify events. > +If this flag is not set, the ignore mask is cleared when a modify event occurs > +for the ignored file or directory. > +.PP > +.I mask > +defines which events shall be listened to (or which shall be ignored). > +It is a bit mask composed of the following values: > +.TP > +.B FAN_ACCESS > +Create an event when a file or directory (but see BUGS) is accessed (read). > +.TP > +.B FAN_MODIFY > +Create an event when a file is modified (write). > +.TP > +.B FAN_CLOSE_WRITE > +Create an event when a writable file is closed. > +.TP > +.B FAN_CLOSE_NOWRITE > +Create an event when a read-only file or directory is closed. > +.TP > +.B FAN_OPEN > +Create an event when a file or directory is opened. > +.TP > +.B FAN_OPEN_PERM > +Create an event when a permission to open a file or directory is requested. > +An fanotify file descriptor created with > +.B FAN_CLASS_PRE_CONTENT > +or > +.B FAN_CLASS_CONTENT > +is required. > +.TP > +.B FAN_ACCESS_PERM > +Create an event when a permission to read a file or directory is requested. > +An fanotify file descriptor created with > +.B FAN_CLASS_PRE_CONTENT > +or > +.B FAN_CLASS_CONTENT > +is required. > +.TP > +.B FAN_ONDIR > +Events for directories shall be created, for example when > +.BR opendir (2), > +.BR readdir (2) > +(but see BUGS), and > +.BR closedir (2) > +are called. > +Without this flag only events for files are created. > +.TP > +.B FAN_EVENT_ON_CHILD > +Events for the immediate children of marked directories shall be created. > +The flag has no effect when marking mounts. > +Note that events are not generated for children of the subdirectories > +of marked directories. > +To monitor complete directory trees it is necessary to mark the relevant > +mount. > +.PP > +The following composed value is defined: > +.TP > +.B FAN_CLOSE > +A file is closed > +.RB ( FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE ). > +.PP > +The filesystem object to be marked is determined by the file descriptor > +.I dirfd > +and the pathname specified in > +.IR pathname : > +.IP * 3 > +If > +.I pathname > +is NULL, > +.I dirfd > +defines the filesystem object to be marked. > +.IP * > +If > +.I pathname > +is NULL, and > +.I dirfd > +takes the special value > +.BR AT_FDCWD , > +the current working directory is to be marked. > +.IP * > +If > +.I pathname > +is absolute, it defines the filesystem object to be marked, and > +.I dirfd > +is ignored. > +.IP * > +If > +.I pathname > +is relative, and > +.I dirfd > +does not have the value > +.BR AT_FDCWD , > +then the filesystem object to be marked is determined by interpreting > +.I pathname > +relative the directory referred to by > +.IR dirfd . > +.IP * > +If > +.I pathname > +is relative, and > +.I dirfd > +has the value > +.BR AT_FDCWD, > +then the filesystem object to be marked is determined by interpreting > +.I pathname > +relative the current working directory. > +.SH RETURN VALUE > +On success, > +.BR fanotify_mark () > +returns 0. > +In case of an error, \-1 is returned, and > +.I errno > +is set to indicate the error. > +.SH ERRORS > +.TP > +.B EBADF > +An invalid file descriptor was passed in > +.IR fanotify_fd . > +.TP > +.B EINVAL > +An invalid value was passed in > +.IR flags > +or > +.IR mask , > +or > +.I fanotify_fd > +was not an fanotify file descriptor. > +.TP > +.B EINVAL > +The fanotify file descriptor was opened with > +.B FAN_CLASS_NOTIF > +and mask contains a flag for permission events > +.RB ( FAN_OPEN_PERM > +or > +.BR FAN_ACCESS_PERM ). > +.TP > +.B ENOENT > +The filesystem object indicated by > +.IR dirfd > +and > +.IR pathname > +does not exist. > +This error also occurs when trying to remove a mark from an object which is not > +marked. > +.TP > +.B ENOMEM > +The necessary memory could not be allocated. > +.TP > +.B ENOSPC > +The number of marks exceeds the limit of 8192 and > +.B FAN_UNLIMITED_MARKS > +was not specified in the call to > +.BR fanotify_init (2). > +.TP > +.B ENOTDIR > +.I flags > +contains > +.BR FAN_MARK_ONLYDIR , > +and > +.I dirfd > +and > +.I pathname > +do not specify a directory. > +.SH VERSIONS > +.BR fanotify_mark () > +was introduced in version 2.6.36 of the Linux kernel and enabled in version > +2.6.37. > +.SH CONFORMING TO > +This system call is Linux-specific. > +.SH BUGS > +As of Linux 3.15, > +the following bugs exist: > +.IP * 3 > +.\" FIXME: Patch is in next-20140424. > +If > +.I flags > +contains > +.BR FAN_MARK_FLUSH , > +.I dfd > +and > +.I pathname > +must indicate a valid path. > +This path is not used. > +.IP * > +.\" FIXME: Patch is in next-20140424. > +.BR readdir (2) > +does not result in a > +.B FAN_ACCESS > +event. > +.IP * > +.\" FIXME: Patch proposed. > +If > +.BR fanotify_mark (2) > +is called with > +.B FAN_MARK_FLUSH, > +.I flags > +is not checked for invalid values. > +.SH SEE ALSO > +.BR fanotify_init (2), > +.BR fanotify (7) > diff --git a/man7/fanotify.7 b/man7/fanotify.7 > new file mode 100644 > index 0000000..efb20bb > --- /dev/null > +++ b/man7/fanotify.7 > @@ -0,0 +1,670 @@ > +.\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk-Mmb7MZpHnFY@public.gmane.org> > +.\" > +.\" %%%LICENSE_START(VERBATIM) > +.\" Permission is granted to make and distribute verbatim copies of this > +.\" manual provided the copyright notice and this permission notice are > +.\" preserved on all copies. > +.\" > +.\" Permission is granted to copy and distribute modified versions of > +.\" this manual under the conditions for verbatim copying, provided that > +.\" the entire resulting derived work is distributed under the terms of > +.\" a permission notice identical to this one. > +.\" > +.\" Since the Linux kernel and libraries are constantly changing, this > +.\" manual page may be incorrect or out-of-date. The author(s) assume. > +.\" no responsibility for errors or omissions, or for damages resulting. > +.\" from the use of the information contained herein. The author(s) may. > +.\" not have taken the same level of care in the production of this. > +.\" manual, which is licensed free of charge, as they might when working. > +.\" professionally. > +.\" > +.\" Formatted or processed versions of this manual, if unaccompanied by > +.\" the source, must acknowledge the copyright and authors of this work. > +.\" %%%LICENSE_END > +.TH FANOTIFY 7 2014-04-24 "Linux" "Linux Programmer's Manual" > +.SH NAME > +fanotify \- monitoring filesystem events > +.SH DESCRIPTION > +The > +.B fanotify > +API provides notification and interception of filesystem events. > +Use cases include virus scanning and hierarchical storage management. > +Currently, only a limited set of events is supported. > +In particular there is no support for create, delete, and move events. > + > +Additional capabilities compared to the > +.BR inotify (7) > +API are monitoring of complete mounts, access permission decisions, and the > +possibility to read or modify files before access by other applications. > + > +The following system calls are used with this API: > +.BR fanotify_init (2), > +.BR fanotify_mark (2), > +.BR poll (2), > +.BR ppoll (2), > +.BR read (2), > +.BR write (2), > +and > +.BR close (2). > +.PP > +.BR fanotify_init (2) > +creates and initializes an fanotify notification group and returns a file > +descriptor referring to it. > +.PP > +An fanotify notification group is an internal object of the kernel which holds > +a list of files, directories, and mount points for which events shall be > +created. > +.PP > +For each entry in an fanotify notification group, two bit masks exist. > +One mask (the mark mask) defines file activities for which an event shall be > +created. > +Another mask (the ignore mask) defines activities for which no event shall be > +generated. > +Having these two types of masks permits a mount point or directory to be > +marked for receiving events, while at the same time ignoring events for > +specific objects under that mount point or directory. > +.PP > +A possible usage of the ignore mask is for a file cache. > +Events of interest for a file cache are modification of a file and closing > +of the same. > +Hence, the cached directory or mount point is to be marked to receive these > +events. > +After receiving the first event informing that a file has been modified, the > +corresponding cache entry will be invalidated. > +No further modification events for this file are of interest until the file is > +closed. > +Hence, the modify event can be added to the ignore mask. > +Upon receiving the closed event, the modify event can be removed from the > +ignore mask and the file cache entry can be updated. > +.PP > +The entries in the fanotify notification groups refer to files and directories > +via their inode number and to mounts via their mount ID. > +If files or directories are renamed or moved, the respective entries survive. > +If files or directories are deleted or mounts are unmounted, the corresponding > +entries are deleted. > +.PP > +Two types of events exist: notification events and permission events. > +Notification events are only informative and require no action to be taken by > +the receiving application except for closing the file descriptor passed in the > +event. > +Permission events are requests to the receiving application to decide whether > +permission for a file access shall be granted. > +For these events, the recipient must write a response which decides whether > +access is granted or not. > +.PP > +When all file descriptors referring to the fanotify notification group are > +closed, the fanotify group is released and its resources are freed for reuse by > +the kernel. > +.PP > +.BR fanotify_mark (2) > +adds a file, directory, or mount to the group and specifies which events > +shall be reported (or ignored), or removes or modifies such an entry. > +.PP > +When an fanotify event occurs, the fanotify file descriptor indicates as > +readable when passed to > +.BR epoll (7), > +.BR poll (2), > +or > +.BR select (2). > +.PP > +All events for an fanotify group are collected in a queue. > +Consecutive events for the same filesystem object and originating from the > +same process may be merged into a single event, with the exception that two > +permission events are never merged into one queue entry. > +Queue entries for notification events are removed when the event has been > +read. > +Queue entries for permission events are removed when the permission > +decision has been taken by writing to the fanotify file descriptor. > +.PP > +Calling > +.BR read (2) > +for the file descriptor returned by > +.BR fanotify_init (2) > +blocks (if the flag > +.B FAN_NONBLOCK > +is not specified in the call to > +.BR fanotify_init (2)) > +until either a file event occurs or the call is interrupted by a signal > +(see > +.BR signal (7)). > + > +The return value of > +.BR read (2) > +is the length of the filled buffer, or \-1 in case of an error. > +After a successful > +.BR read(2), > +the read buffer contains one or more of the following structures: > + > +.in +4n > +.nf > +struct fanotify_event_metadata { > + __u32 event_len; > + __u8 vers; > + __u8 reserved; > + __u16 metadata_len; > + __aligned_u64 mask; > + __s32 fd; > + __s32 pid; > +}; > +.fi > +.in > + > +.TP 15 > +.I event_len > +This is the length of the data for the current event and the offset to the next > +event in the buffer. > +In the current implementation the value of > +.I event_len > +is always > +.BR FAN_EVENT_METADATA_LEN . > +In principal the API design would allow to return variable length structures. > +Therefore, and for performance reasons, it is recommended to use a larger > +buffer size when reading, for example 4096 bytes. > +.TP > +.I vers > +This field holds a version number for the structures. > +It must be compared to > +.B FANOTIFY_METADATA_VERSION > +to verify that the structures at runtime match the structures at compile > +time. > +In case of a mismatch, the application should abandon trying to use the > +fanotify file descriptor. > +.TP > +.I reserved > +This field is not used. > +.TP > +.I metadata_len > +This is the length of the structure. > +The field was introduced to facilitate the implementation of optional headers > +per event type. > +No such optional headers exist in the current implementation. > +.TP > +.I mask > +This is a bit mask describing the event. > +.TP > +.I fd > +This is an open file descriptor for the object being accessed, or > +.B FAN_NOFD > +if a queue overflow occurred. > +The file descriptor can be used to access the contents of the monitored file or > +directory. > +It has internal the flag > +.B FMODE_NONOTIFY > +set. > +This flag suppresses fanotify event generation. > +Hence, when the receiver of the fanotify event accesses the notified file or > +directory using this file descriptor, no additional events will be created. > +The reading application is responsible for closing the file descriptor. > +.TP > +.I pid > +This is the ID of the process that caused the event. > +A program listening to fanotify events can compare this PID to the PID returned > +by > +.BR getpid (2), > +to determine whether the event is caused by the listener itself, or is due to a > +file access by another program. > +.PP > +The bit mask in > +.I mask > +signals which events have occurred for a single filesystem object. > +More than one of the following flags can be set at once in the bit mask. > +.TP > +.B FAN_ACCESS > +A file or a directory (but see BUGS) was accessed (read). > +.TP > +.B FAN_OPEN > +A file or a directory was opened. > +.TP > +.B FAN_MODIFY > +A file was modified. > +.TP > +.B FAN_CLOSE_WRITE > +A file that was opened for writing > +.RB ( O_WRONLY > +or > +.BR O_RDWR ) > +was closed. > +.TP > +.B FAN_CLOSE_NOWRITE > +A file that was only opened for reading > +.RB ( O_RDONLY ) > +or a directory was closed. > +.TP > +.B FAN_Q_OVERFLOW > +The event queue exceeded the limit of 16384 entries. > +This limit can be overridden in the call to > +.BR fanotify_init (2) > +by setting the flag > +.BR FAN_UNLIMITED_QUEUE . > +.TP > +.B FAN_ACCESS_PERM > +An application wants to read a file or directory, for example using > +.BR read (2) > +or > +.BR readdir (2). > +The reader must write a response that determines whether the permission to > +access the filesystem object shall be granted. > +.TP > +.B FAN_OPEN_PERM > +An application wants to open a file or directory. > +The reader must write a response that determines whether the permission to > +open the filesystem object shall be granted. > +.PP > +To check for any close event, the following bit mask may be used: > +.TP > +.B FAN_CLOSE > +A file was closed > +(FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE). > +.PP > +The following macros are provided to iterate over a buffer containing fanotify > +event metadata returned by > +.BR read (2) > +from an fanotify file descriptor. > +.TP > +.B FAN_EVENT_OK(meta, len) > +This macro checks the remaining length > +.I len > +of the buffer > +.I meta > +against the length of the metadata structure and the > +.I event_len > +field of the first metadata structure in the buffer. > +.TP > +.B FAN_EVENT_NEXT(meta, len) > +This macro sets the pointer > +.I meta > +to the next metadata structure using the length indicated in the > +.I event_len > +field of the metadata structure and reduces the remaining length of the > +buffer > +.IT len . > +.PP > +For permission events, the application must > +.BR write (2) > +a structure of the following form to the > +.B fanotify > +file descriptor: > + > +.in +4n > +.nf > +struct fanotify_response { > + __s32 fd; > + __u32 response; > +}; > +.fi > +.in > + > +.TP 15 > +.I fd > +This is the file descriptor from the structure > +.IR fanotify_event_metadata . > +.TP > +.I response > +This field indicates whether or not the permission is to be granted. > +Its value must be either > +.B FAN_ALLOW > +to allow the file operation or > +.B FAN_DENY > +to deny the file operation. > +.PP > +If access has been denied, the requesting application call will receive an > +error > +.BR EPERM . > +.PP > +To end listening, it is sufficient to > +.BR close (2) > +the fanotify file descriptor. > +The outstanding permission events will be set to allowed, and all resources > +will be returned to the kernel. > +.PP > +The file > +.I /proc/<pid>/fdinfo/<fd> > +contains information about fanotify marks for file descriptor > +.I fd > +of process > +.IR pid . > +See > +.I Documentation/filesystems/proc.txt > +for details. > +.SH ERRORS > +In addition to the usual errors for > +.BR read (2), > +the following errors can occur when reading from the fanotify file descriptor: > +.TP > +.B EINVAL > +The buffer is too short to hold the event. > +.TP > +.B EMFILE > +The per-process limit on the number of open files has been reached. > +See the description of > +.B RLIMIT_NOFILE > +in > +.BR getrlimit (2). > +.TP > +.B ENFILE > +The system-wide limit on the number of open files has been reached. > +See > +.I /proc/sys/fs/file-max > +in > +.BR proc (5). > +.TP > +.B ETXTBSY > +A write enabled file descriptor shall be created for a file that is executing. > +This error is returned by > +.BR read (2), > +if > +.B O_RDWR > +or > +.B O_WRONLY > +was specified in the > +.I event_f_flags > +argument when calling > +.BR fanotify_init (2) > +and the event occured for a monitored file that is currently being execuded. > +.PP > +In addition to the usual errors for > +.BR write (2), > +the following errors can occur when writing to the fanotify file descriptor: > +.TP > +.B EINVAL > +Fanotify access permissions are not enabled in the kernel configuration or the > +value of > +.I response > +in the response structure is not valid. > +.TP > +.B ENOENT > +The file descriptor > +.I fd > +in the response structure is not valid. > +This might occur because the file was already deleted by another thread or > +process. > +.SH VERSIONS > +The fanotify API was introduced in version 2.6.36 of the Linux kernel and > +enabled in version 2.6.37. > +Fdinfo support was added in version 3.8. > +.SH "CONFORMING TO" > +The fanotify API is Linux-specific. > +.SH NOTES > +The fanotify API is available only if the kernel was built with the > +.B CONFIG_FANOTIFY > +configuration option enabled. > +In addition, fanotify permission handling is available only if the > +.B CONFIG_FANOTIFY_ACCESS_PERMISSIONS > +configuration option is enabled. > +.SS Limitations and caveats > +Fanotify reports only events that a user-space program triggers through the > +filesystem API. > +As a result, it does not catch remote events that occur on network filesystems. > +.PP > +The fanotify API does not report file accesses and modifications that > +may occur because of > +.BR mmap (2), > +.BR msync (2), > +and > +.BR munmap (2). > +.PP > +Events for directories are created only if the directory itself is opened, > +read, and closed. > +Adding, removing, or changing children of a marked directory does not create > +events for the monitored directory itself. > +.PP > +Fanotify monitoring of directories is not recursive: to monitor subdirectories > +under a directory, additional marks must be created. > +(But note that the fanotify API provides no way of detecting when a > +subdirectory has been created under a marked directory, which makes recursive > +monitoring difficult.) > +Monitoring mounts offers the capability to monitor a whole directory tree. > +.PP > +The event queue can overflow. > +In this case, events are lost. > +.SH BUGS > +As of Linux 3.15, > +the following bugs existed: > +.IP * 3 > +.\" FIXME: Patch is in linux-next-20140424. > +.BR readdir (2) > +does not create a > +.B FAN_ACCESS > +event. > +.IP * > +.\" FIXME: A patch was proposed. > +When an event is generated, no check is made to see whether the user ID of the > +receiving process has authorization to read or write the file before passing a > +file descriptor for that file in > +This poses a security risk, when the > +.B CAP_SYS_ADMIN > +capability is set for programs executed by unprivileged users. > +.SH EXAMPLE > +The following program demonstrates the usage of the fanotify API. > +It marks the mount passed as argument and waits for events of type > +.B FAN_PERM_OPEN > +and > +.BR FAN_CLOSE_WRITE . > +When a permission event occurs, a > +.B FAN_ALLOW > +response is given. > +.PP > +The following output was recorded while editing file > +.IR /home/user/temp/notes . > +Before the file was opened, a > +.B FAN_OPEN_PERM > +event occurred. > +After the file was closed, a > +.B FAN_CLOSE_WRITE > +event occurred. > +Execution of the program ends when the user presses the ENTER key. > +.SS Example output > +.in +4n > +.nf > +# ./fanotify_example /home > +Press enter key to terminate. > +Listening for events. > +FAN_OPEN_PERM: File /home/user/temp/notes > +FAN_CLOSE_WRITE: File /home/user/temp/notes > + > +Listening for events stopped. > +.fi > +.in > +.SS Program source > +.nf > +#define _GNU_SOURCE // needed for O_LARGEFILE > +#include <errno.h> > +#include <fcntl.h> > +#include <limits.h> > +#include <poll.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <sys/fanotify.h> > +#include <unistd.h> > + > +/* Read all available fanotify events from the file descriptor 'fd' */ > + > +void > +handle_events(int fd) > +{ > + const struct fanotify_event_metadata *metadata; > + char buf[4096]; > + ssize_t len; > + char path[PATH_MAX]; > + ssize_t path_len; > + char procfd_path[PATH_MAX]; > + struct fanotify_response response; > + > + /* Loop while events can be read from fanotify file descriptor. */ > + > + for(;;) { > + > + /* Read some events. */ > + > + len = read(fd, (void *) &buf, sizeof(buf)); > + if (len == \-1 && errno != EAGAIN) { > + perror("read"); > + exit(EXIT_FAILURE); > + } > + > + /* Check if end of available data reached. */ > + > + if (len <= 0) > + break; > + > + /* Point to the first event in the buffer. */ > + > + metadata = (struct fanotify_event_metadata *) buf; > + > + /* Loop over all events in the buffer. */ > + > + while (FAN_EVENT_OK(metadata, len)) { > + > + /* Check that run time and compile time structures > + match. */ > + > + if (metadata\->vers != FANOTIFY_METADATA_VERSION) { > + fprintf(stderr, > + "Mismatch of fanotify metadata version.\\n"); > + exit(EXIT_FAILURE); > + } > + > + /* Check that the event contains a file descriptor. */ > + > + if (metadata\->fd >= 0) { > + > + /* Handle open permission event. */ > + > + if (metadata\->mask & FAN_OPEN_PERM) { > + printf("FAN_OPEN_PERM: "); > + > + /* Allow file to be opened. */ > + > + response.fd = metadata\->fd; > + response.response = FAN_ALLOW; > + write(fd, &response, sizeof( > + struct fanotify_response)); > + } > + > + /* Handle closing of writable file event. */ > + > + if (metadata\->mask & FAN_CLOSE_WRITE) { > + printf("FAN_CLOSE_WRITE: "); > + } > + > + /* Determine path of the file accessed. */ > + > + snprintf(procfd_path, sizeof(procfd_path), > + "/proc/self/fd/%d", metadata\->fd); > + path_len = readlink(procfd_path, path, > + sizeof(path) \- 1); > + if (path_len == \-1) { > + perror("readlink"); > + exit(EXIT_FAILURE); > + } > + > + path[path_len] = '\\0'; > + printf("File %s", path); > + > + /* Close the file descriptor of the event. */ > + > + close(metadata\->fd); > + printf("\\n"); > + } > + > + /* Forward pointer to next event. */ > + > + metadata = FAN_EVENT_NEXT(metadata, len); > + } > + } > +} > + > +int > +main(int argc, char *argv[]) > +{ > + char buf; > + int fd, poll_num; > + nfds_t nfds; > + struct pollfd fds[2]; > + > + /* Check mount point is supplied. */ > + > + if (argc != 2) { > + printf("Usage: %s MOUNT\\n", argv[0]); > + exit(EXIT_FAILURE); > + } > + > + printf("Press enter key to terminate.\\n"); > + > + /* Create the file descriptor for accessing the fanotify API. */ > + > + fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK, > + O_RDONLY | O_LARGEFILE); > + if (fd == \-1) { > + perror("fanotify_init"); > + exit(EXIT_FAILURE); > + } > + > + /* Mark the mount for > + \- permission events before opening files > + \- notification events after closing a write enabled > + file descriptor. */ > + > + if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT, > + FAN_OPEN_PERM | FAN_CLOSE_WRITE, \-1, > + argv[1]) == \-1) { > + perror("fanotify_mark"); > + close(fd); > + exit(EXIT_FAILURE); > + } > + > + /* Prepare for polling. */ > + > + nfds = 2; > + > + /* Console input. */ > + > + fds[0].fd = STDIN_FILENO; > + fds[0].events = POLLIN; > + > + /* Fanotify input. */ > + > + fds[1].fd = fd; > + fds[1].events = POLLIN; > + > + /* This is the loop to wait for incoming events. */ > + > + printf("Listening for events.\\n"); > + while (1) { > + poll_num = poll(fds, nfds, \-1); > + if (poll_num == \-1) { > + if (errno == EINTR) > + continue; > + perror("poll"); > + exit(EXIT_FAILURE); > + } > + if (poll_num > 0) { > + if (fds[0].revents & POLLIN) { > + > + /* Console input is available. Empty stdin and quit. */ > + > + while (read(STDIN_FILENO, &buf, 1) > 0 && buf != '\\n') > + continue; > + break; > + } > + if (fds[1].revents & POLLIN) { > + > + /* Fanotify events are available. */ > + > + handle_events(fd); > + } > + } > + } > + > + /* Close fanotify file descriptor. */ > + > + close(fd); > + printf("Listening for events stopped.\\n"); > + return EXIT_SUCCESS; > +} > +.fi > +.SH "SEE ALSO" > +.ad l > +.BR fanotify_init (2), > +.BR fanotify_mark (2), > +.BR inotify (7) > diff --git a/man7/inotify.7 b/man7/inotify.7 > index 17462c6..da76b2a 100644 > --- a/man7/inotify.7 > +++ b/man7/inotify.7 > @@ -760,7 +760,8 @@ unread event. > .BR inotify_init1 (2), > .BR inotify_rm_watch (2), > .BR read (2), > -.BR stat (2) > +.BR stat (2), > +.BR fanotify (7) > > .IR Documentation/filesystems/inotify.txt > in the Linux kernel source tree > -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <535A3C3E.8050400-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>]
* Re: [PATCH 1/1 v2] fanotify: create manpages [not found] ` <535A3C3E.8050400-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> @ 2014-04-25 15:10 ` Heinrich Schuchardt [not found] ` <535A7AF2.3030501-Mmb7MZpHnFY@public.gmane.org> 0 siblings, 1 reply; 4+ messages in thread From: Heinrich Schuchardt @ 2014-04-25 15:10 UTC (permalink / raw) To: Michael Kerrisk (man-pages); +Cc: linux-man-u79uwXL29TY76Z2rM5mHXA On 25.04.2014 12:43, Michael Kerrisk (man-pages) wrote: > Some things I'd like you to check or fix: > * Please review 679a078389 (ETXTBUSY) ok > * Please review 3b32c70be9 (FAN_MARK_FLUSH bug) a period ('.') is missing at the end of the sentence. You received a patch. > * See the FIXME in the example code in fanotify(7). My understanding is, that file descriptors are always positive. Please, correct me if I am wrong. Comparing to FAN_NOFD would be a valid alternative. You are right that queue overflow is not notified to the user. But it is not necessary for the listener to take any action in case of a queue overflow. > * The readdir(2) / FAN_ACCESS bug is described in fanotify(7) > and fanotify_mark(7). It only needs to be in one of the pages. > Could you patch to remove whichever you think should be removed. Patch provided > > An earlier question that I believe is still not resolved: > > [[ >> ' Now I know that I earlier said that FAN_ONDIR and FAN_EVENT_ON_CHILD >> ' belong in the input events for fanotify_mark(), not here in the >> ' returned events. Or at least, as far as I can tell, they can't be >> ' in the returned events--but can you confirm this please. >> Where did you find FAN_ONDIR and FAN_EVENT_ON_CHILD in fanotify.7? > > They were in an earlier version in fanotify.7, if I recall correctly. > Anyway, my point is: have you confirmed that FAN_ONDIR and > FAN_EVENT_ON_CHILD are only input flags, and can't be returned as output > event flags? > ]] Verified with test program: FAN_ONDIR and FAN_EVENT_ON_CHILD are not returned as output event flags, when specified fanotify_mark. > > Once we've finished those tweaks, we can pester Eric for a review. Let's say invite. Hopefully he is not too busy. > Cheers Heinrich -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <535A7AF2.3030501-Mmb7MZpHnFY@public.gmane.org>]
* Re: [PATCH 1/1 v2] fanotify: create manpages [not found] ` <535A7AF2.3030501-Mmb7MZpHnFY@public.gmane.org> @ 2014-04-25 18:10 ` Michael Kerrisk (man-pages) 0 siblings, 0 replies; 4+ messages in thread From: Michael Kerrisk (man-pages) @ 2014-04-25 18:10 UTC (permalink / raw) To: Heinrich Schuchardt Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w, linux-man-u79uwXL29TY76Z2rM5mHXA On 04/25/2014 05:10 PM, Heinrich Schuchardt wrote: > On 25.04.2014 12:43, Michael Kerrisk (man-pages) wrote: >> Some things I'd like you to check or fix: >> * Please review 679a078389 (ETXTBUSY) > ok > >> * Please review 3b32c70be9 (FAN_MARK_FLUSH bug) > a period ('.') is missing at the end of the sentence. > You received a patch. Thanks. >> * See the FIXME in the example code in fanotify(7). > My understanding is, that file descriptors are always positive. > Please, correct me if I am wrong. Comparing to FAN_NOFD would > be a valid alternative. You're right. It's just that comparing to FAN_NOFD seemed to me to be a little more transparent. I.e., "[if not queue overflow]" > You are right that queue overflow is not notified to the user. > But it is not necessary for the listener to take any action in case > of a queue overflow. Fair enough. But I think a comment explaining what goes on might be helpful. I added one. >> * The readdir(2) / FAN_ACCESS bug is described in fanotify(7) >> and fanotify_mark(7). It only needs to be in one of the pages. >> Could you patch to remove whichever you think should be removed. > Patch provided Thanks. >> An earlier question that I believe is still not resolved: >> >> [[ >>> ' Now I know that I earlier said that FAN_ONDIR and FAN_EVENT_ON_CHILD >>> ' belong in the input events for fanotify_mark(), not here in the >>> ' returned events. Or at least, as far as I can tell, they can't be >>> ' in the returned events--but can you confirm this please. >>> Where did you find FAN_ONDIR and FAN_EVENT_ON_CHILD in fanotify.7? >> >> They were in an earlier version in fanotify.7, if I recall correctly. >> Anyway, my point is: have you confirmed that FAN_ONDIR and >> FAN_EVENT_ON_CHILD are only input flags, and can't be returned as output >> event flags? >> ]] > Verified with test program: FAN_ONDIR and FAN_EVENT_ON_CHILD are not > returned as output event flags, when specified fanotify_mark. Okay -- thanks. My testing also got the same result, but I wanted to some independent checking. >> Once we've finished those tweaks, we can pester Eric for a review. > Let's say invite. Hopefully he is not too busy. Sure ;-). Cheers, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-04-25 18:10 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-24 20:18 [PATCH 1/1 v2] fanotify: create manpages Heinrich Schuchardt
[not found] ` <1398370691-13971-1-git-send-email-xypron.glpk-Mmb7MZpHnFY@public.gmane.org>
2014-04-25 10:43 ` Michael Kerrisk (man-pages)
[not found] ` <535A3C3E.8050400-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-04-25 15:10 ` Heinrich Schuchardt
[not found] ` <535A7AF2.3030501-Mmb7MZpHnFY@public.gmane.org>
2014-04-25 18:10 ` Michael Kerrisk (man-pages)
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).