Provided by: manpages-fr_4.21.0-2_all bug

NOM

       fanotify – Surveiller les événements des systèmes de fichiers

DESCRIPTION

       L’interface  de programmation fanotify permet la notification et l’interception des événements du système
       de fichiers. La  recherche  de  virus  et  la  gestion  de  stockage  hiérarchisé  font  partie  des  cas
       d’utilisation.  Dans l’interface originelle seul un ensemble limité d’événements était pris en charge. En
       particulier, les événements de création, de suppression ou de déplacement n’étaient pas pris  en  charge.
       La  prise  en  charge  de  ces évènements a été ajoutée dans Linux 5.1. Consultez inotify(7) pour plus de
       précisions sur l’interface qui ne notifiait pas ces évènements avant Linux 5.1.

       La capacité de surveiller tous les objets d’un système de fichiers monté,  la  capacité  de  décider  des
       droits  d’accès  et  la  possibilité  de lire ou modifier les fichiers avant qu’ils ne soient accédés par
       d’autres applications font partie des capacités supplémentaires à celles de l’interface de  programmation
       inotify(7).

       Les  appels  système  suivants  sont  utilisés  avec cette interface de programmation : fanotify_init(2),
       fanotify_mark(2), read(2), write(2) et close(2).

   fanotify_init(), fanotify_mark() et groupes de notification
       L’appel système fanotify_init(2) crée et initialise un groupe de notifications  fanotify  et  renvoie  un
       descripteur de fichier le référençant.

       Un  groupe  de  notifications  fanotify est un objet interne au noyau qui contient une liste de fichiers,
       répertoires et points de montage pour lesquels des événements seront créés.

       Pour chaque entrée dans un groupe de notifications fanotify, deux masques  binaires  sont  présents :  le
       masque  mark  et  le  masque  ignore.  Le masque mark définit les activités de fichier pour lesquelles un
       événement doit être créé. Le masque ignore définit les activités pour lesquelles aucun événement ne  doit
       être  créé.  Avoir ces deux types de masque permet à un point de montage ou à un répertoire d’être marqué
       pour recevoir des événements, tout en ignorant en même temps les événements pour des  objets  spécifiques
       dans ce point de montage ou répertoire.

       L’appel  système  fanotify_mark(2)  ajoute  un  fichier,  répertoire  ou  point de montage à un groupe de
       notifications et indique les événements qui doivent être signalés (ou ignorés), ou  supprime  ou  modifie
       une telle entrée.

       Le  masque  ignore  peut  servir  pour  un cache de fichier. Les événements intéressants pour un cache de
       fichier sont la modification et la fermeture d’un fichier. Ainsi, le répertoire ou point  de  montage  en
       cache  va  être  marqué  pour  recevoir ces événements. Après la réception du premier événement informant
       qu’un fichier a été modifié, l’entrée correspondante du cache sera désactivée. Aucun autre  événement  de
       modification  pour ce fichier ne sera utile jusqu’à sa fermeture. Ainsi, l’événement de modification peut
       être ajouté au masque  ignore.  Lors  de  la  réception  d’un  événement  de  fermeture,  l’événement  de
       modification peut être supprimé du masque ignore et l’entrée de cache de fichier peut être mise à jour.

       Les  entrées  des groupes de notification fanotify font référence aux fichiers et répertoires à l’aide de
       leur numéro d’inœud et aux montages à  l’aide  de  leur  identifiant  de  montage.  Si  les  fichiers  ou
       répertoires sont renommés ou déplacés dans le même montage, les entrées correspondantes survivent. Si les
       fichiers  ou  répertoires  sont  supprimés  ou  déplacés  dans  un  autre montage ou si les montages sont
       démontés, les entrées correspondantes sont supprimées.

   La file d’événements
       Comme les événements surviennent sur les objets de système  de  fichiers  surveillés  par  un  groupe  de
       notifications, le système fanotify génère les événements qui sont collectés dans une file. Ces événements
       peuvent  être lus (en utilisant read(2) ou similaire) à partir du descripteur de fichier fanotify renvoyé
       par fanotify_init(2).

       Deux types d’événements sont créés : les événements de notification et les événements de permission.  Les
       événements  de  notification  sont  surtout  informatifs  et  ne  nécessitent  pas d’action à prendre par
       l’application qui les reçoit à part pour la fermeture  du  descripteur  de  fichier  valable  passé  dans
       l’événement  (voir  ci-dessous).  Les  événements de permission sont des demandes à l’application qui les
       reçoit pour décider si les droits d’accès à un fichier doivent être attribués. Pour  ces  événements,  le
       destinataire doit écrire une réponse qui décide d’attribuer l’accès ou non.

       Un événement est supprimé de la file d’événements du groupe fanotify quand il a été lu. Les événements de
       permission  qui  ont  été  lus  sont  gardés  dans une liste interne du groupe fanotify jusqu’à ce qu’une
       décision d’attribution de droits ait été prise en écrivant dans le descripteur de fichier fanotify ou que
       le descripteur de fichier fanotify soit fermé.

   Lecture d’événements fanotify
       Appeler read(2) pour le descripteur  de  fichier  renvoyé  par  fanotify_init(2)  bloque  (si  l’attribut
       FAN_NONBLOCK  n’est  pas  indiqué dans l’appel de fanotify_init(2)) jusqu’à ce qu’un événement de fichier
       survienne ou que l’appel soit interrompu par un signal (consultez signal(7)).

       Après un read(2) réussi, le tampon de lecture contient une ou plus des structures suivantes :

           struct fanotify_event_metadata {
               __u32 event_len;
               __u8 vers;
               __u8 reserved;
               __u16 metadata_len;
               __aligned_u64 mask;
               __s32 fd;
               __s32 pid;
           };

       Information records are supplemental pieces of information that may be  provided  alongside  the  generic
       fanotify_event_metadata  structure. The flags passed to fanotify_init(2)  have influence over the type of
       information records that may be  returned  for  an  event.  For  example,  if  a  notification  group  is
       initialized with FAN_REPORT_FID or FAN_REPORT_DIR_FID, then event listeners should also expect to receive
       a fanotify_event_info_fid structure alongside the fanotify_event_metadata structure, whereby file handles
       are  used  to  identify  filesystem objects rather than file descriptors. Information records may also be
       stacked, meaning that using the various FAN_REPORT_* flags in conjunction with one another is  supported.
       In  such  cases,  multiple  information  records  can  be  returned  for  an  event alongside the generic
       fanotify_event_metadata  structure.  For  example,  if  a  notification   group   is   initialized   with
       FAN_REPORT_TARGET_FID  and  FAN_REPORT_PIDFD,  then  an event listener should expect to receive up to two
       fanotify_event_info_fid  information  records  and  one  fanotify_event_info_pidfd   information   record
       alongside  the  generic  fanotify_event_metadata  structure.  Importantly, fanotify provides no guarantee
       around the ordering of information records when a notification group is initialized with a stacked  based
       configuration.  Each  information record has a nested structure of type fanotify_event_info_header. It is
       imperative for event listeners to inspect the info_type field of this structure in order to determine the
       type of information record that had been received for a given event.

       In cases where an fanotify group identifies filesystem objects by file handles,  event  listeners  should
       also  expect  to  receive  one  or  more  of  the  below information record objects alongside the generic
       fanotify_event_metadata structure within the read buffer:

           struct fanotify_event_info_fid {
               struct fanotify_event_info_header hdr;
               __kernel_fsid_t fsid;
               unsigned char file_handle[0];
           };

       In cases where an fanotify group is initialized with FAN_REPORT_PIDFD, event listeners should  expect  to
       receive  the  below  information  record  object  alongside the generic fanotify_event_metadata structure
       within the read buffer:

           struct fanotify_event_info_pidfd {
                   struct fanotify_event_info_header hdr;
                   __s32 pidfd;
           };

       In case of a FAN_FS_ERROR event, an additional information record describing the error that  occurred  is
       returned  alongside  the generic fanotify_event_metadata structure within the read buffer. This structure
       is defined as follows:

           struct fanotify_event_info_error {
               struct fanotify_event_info_header hdr;
               __s32 error;
               __u32 error_count;
           };

       All information records contain a nested structure of  type  fanotify_event_info_header.  This  structure
       holds  meta-information  about  the  information record that may have been returned alongside the generic
       fanotify_event_metadata structure. This structure is defined as follows:

           struct fanotify_event_info_header {
                __u8 info_type;
                __u8 pad;
                __u16 len;
           };

       Pour des raisons de performances, une grande taille de tampon (par exemple  4096 octets)  est  conseillée
       pour que plusieurs événements puissent être récupérés en une seule lecture.

       La  valeur de retour de read(2) est le nombre d’octets placés dans le tampon, ou -1 en cas d’erreur (mais
       consultez BOGUES).

       Les champs de la structure fanotify_event_metadata sont les suivants.

       event_len
              C’est la taille des données pour l’événement actuel et la position du prochain événement  dans  le
              tampon. À moins que le groupe identifie des objets du système de fichiers par des gestionnaires de
              fichiers,  la valeur d’event_len est toujours FAN_EVENT_METADATA_LEN. Pour un groupe qui identifie
              les objets du système de fichiers par des gestionnaires de fichiers, event_len  inclut  aussi  des
              enregistrements d’identificateur de fichier de taille variable.

       vers   Ce   champ   contient   un   numéro  de  version  pour  la  structure.  Il  doit  être  comparé  à
              FANOTIFY_METADATA_VERSION  pour  vérifier  que  les  structures  renvoyées   pendant   l’exécution
              correspondent  aux  structures  définies  à  la  compilation.  En  cas d’erreur de correspondance,
              l’application devrait arrêter d’essayer d’utiliser le descripteur de fichier fanotify.

       reserved
              Ce champ n’est pas utilisé.

       metadata_len
              C’est la taille de la  structure.  Le  champ  a  été  introduit  pour  faciliter  l’implémentation
              d’en-têtes   facultatifs   par   type   d’événement.   Aucun   en-tête  facultatif  n’existe  dans
              l’implémentation actuelle.

       mask   C’est un masque binaire décrivant l’événement (voir ci-dessous).

       fd     C’est un descripteur de fichier  ouvert  pour  l’objet  actuellement  accédé  ou  FAN_NOFD  si  un
              dépassement  de  file  est  survenu.  Avec  un groupe fanotify qui identifie les objets de système
              d’exploitation par des gestionnaires de fichiers, les applications  doivent  escompter  que  cette
              valeur soit FAN_NOFD pour chaque évènement qu’elles reçoivent. Le descripteur de fichier peut être
              utilisé  pour  accéder  au  contenu  du fichier ou répertoire surveillé. L’application qui lit est
              responsable de la fermeture de ce descripteur de fichier.

              Lors d’un appel  de  fanotify_init(2),  l’appelant  pourrait  indiquer  (à  l’aide  de  l’argument
              event_f_flags)  plusieurs  attributs  d’état  de  fichier à définir dans la description de fichier
              ouverte qui correspond à ce  descripteur  de  fichier.  De  plus,  l’attribut  d’état  de  fichier
              FMODE_NONOTIFY  (interne  au  noyau) est défini dans la description de fichier ouverte. L’attribut
              supprime la création d’événement fanotify. Ainsi, quand le destinataire  de  l’événement  fanotify
              accède  au  fichier  ou répertoire notifié en utilisant ce descripteur de fichier, aucun événement
              supplémentaire n’est créé.

       pid    Si l’attribut FAN_REPORT_TID était réglé  dans  fanotify_init(2),  c’est  l’identifiant  (TID)  du
              thread  qui  a  provoqué  cet  évènement.  Sinon,  c’est  le  PID  du processus qui a provoqué cet
              évènement.

       Un programme écoutant les événements fanotify peut comparer ce PID au  PID  renvoyé  par  getpid(2)  pour
       déterminer  si  l’événement  est  provoqué  par l’écoutant lui-même ou par un autre processus accédant au
       fichier.

       Le masque binaire mask indique les événements survenus  pour  un  seul  objet  de  système  de  fichiers.
       Plusieurs  bits pourraient être définis dans ce masque si plus d’un événement est survenu pour l’objet de
       système de fichiers surveillé. En particulier, les événements consécutifs pour le même objet  de  système
       de  fichiers et originaires du même processus pourraient être fusionnés dans un seul événement, mais deux
       événements de permission ne sont jamais fusionnés dans une entrée de file.

       Les bits pouvant apparaître dans mask sont les suivants.

       FAN_ACCESS
              Un fichier ou un répertoire (mais consultez BOGUES) a été accédé (en lecture).

       FAN_OPEN
              Un fichier ou un répertoire a été ouvert.

       FAN_OPEN_EXEC
              Un fichier a été ouvert dans le but d’être exécuté. Consultez  NOTES  dans  fanotify_mark(2)  pour
              plus de détails.

       FAN_ATTRIB
              Une métadonnée de fichier ou d’un répertoire a été modifiée.

       FAN_CREATE
              Un fichier enfant ou un répertoire a été créé dans le répertoire surveillé.

       FAN_DELETE
              Un fichier enfant ou un répertoire a été supprimé dans le répertoire surveillé.

       FAN_DELETE_SELF
              Un fichier ou un répertoire a été supprimé.

       FAN_FS_ERROR
              A filesystem error was detected.

       FAN_RENAME
              A file or directory has been moved to or from a watched parent directory.

       FAN_MOVED_FROM
              Un fichier ou un répertoire a été déplacé du répertoire surveillé.

       FAN_MOVED_TO
              Un fichier ou un répertoire a été déplacé du répertoire parent surveillé.

       IN_MOVE_SELF
              Un fichier ou un répertoire surveillé a été déplacé.

       FAN_MODIFY
              Un fichier a été modifié.

       FAN_CLOSE_WRITE
              Un fichier qui était ouvert en écriture (O_WRONLY ou O_RDWR) a été fermé.

       FAN_CLOSE_NOWRITE
              Un fichier ou un répertoire, qui était ouvert en lecture seule (O_RDONLY), a été fermé.

       FAN_Q_OVERFLOW
              The event queue exceeded the limit on number of events. This limit can be overridden by specifying
              the FAN_UNLIMITED_QUEUE flag when calling fanotify_init(2).

       FAN_ACCESS_PERM
              Une  application  veut  lire  un  fichier  ou  répertoire,  par  exemple  en  utilisant read(2) ou
              readdir(2). Le lecteur doit écrire une réponse (telle que décrite ci-dessous) qui détermine si  le
              droit d’accès à l’objet de système de fichiers sera attribué.

       FAN_OPEN_PERM
              Une  application  veut  ouvrir un fichier ou un répertoire. Le lecteur doit écrire une réponse qui
              détermine si le droit d’ouvrir l’objet de système de fichiers sera attribué.

       FAN_OPEN_PERM
              Une application veut ouvrir un fichier pour une exécution. Le lecteur doit écrire une réponse  qui
              détermine  si le droit d’ouvrir l’objet de système de fichiers sera attribué. Consultez NOTES dans
              fanotify_mark(2) pour plus de détails.

       Pour vérifier tous les événements fermés, le masque binaire suivant pourrait être utilisé :

       FAN_CLOSE
              Un fichier a été fermé. C’est un synonyme de :

                  FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE

       Pour vérifier tous les événements de déplacement, le masque binaire suivant pourrait être utilisé :

       FAN_MOVE
              Un fichier ou un répertoire a été déplacé. C’est un synonyme de :

                  FAN_MOVED_FROM | FAN_MOVED_TO

       Les bits suivants peuvent apparaître dans  mask  seulement  conjointement  avec  d’autres  bits  de  type
       d’évènement :

       FAN_ONDIR
              Les  évènements  décrits  dans  le  mask  se sont déroulés dans un objet de répertoire. Le rapport
              d’évènements dans des répertoires requiert le  réglage  de  cet  attribut  dans  le  masque  mark.
              Consultez  fanotify_mark(2) pour plus de détails. L’attribut FAN_ONDIR est rapporté dans un masque
              d’évènement seulement si le groupe fanotify identifie les objets de  système  d’exploitation  avec
              des gestionnaires de fichiers.

       Information records that are supplied alongside the generic fanotify_event_metadata structure will always
       contain    a    nested    structure    of    type   fanotify_event_info_header.   The   fields   of   the
       fanotify_event_info_header are as follows:

       info_type
              A unique integer value representing the type of information record object received for  an  event.
              The   value  of  this  field  can  be  set  to  one  of  the  following:  FAN_EVENT_INFO_TYPE_FID,
              FAN_EVENT_INFO_TYPE_DFID, FAN_EVENT_INFO_TYPE_DFID_NAME, or FAN_EVENT_INFO_TYPE_PIDFD.  The  value
              set for this field is dependent on the flags that have been supplied to fanotify_init(2). Refer to
              the  field  details of each information record object type below to understand the different cases
              in which the info_type values can be set.

       pad    This field is currently not used by any information record object type and  therefore  is  set  to
              zero.

       len    The  value  of  len  is  set  to  the  size  of  the  information  record  object,  including  the
              fanotify_event_info_header. The total size of all additional information records is  not  expected
              to be larger than (event_len - metadata_len).

       Les champs de la structure fanotify_event_info_fid sont les suivants.

       hdr    This  is  a  structure  of  type  fanotify_event_info_header.  For  example, when an fanotify file
              descriptor is created using FAN_REPORT_FID, a single information record is expected to be attached
              to the event with  info_type  field  value  of  FAN_EVENT_INFO_TYPE_FID.  When  an  fanotify  file
              descriptor is created using the combination of FAN_REPORT_FID and FAN_REPORT_DIR_FID, there may be
              two   information   records   attached   to   the   event:  one  with  info_type  field  value  of
              FAN_EVENT_INFO_TYPE_DFID, identifying a parent directory object,  and  one  with  info_type  field
              value  of  FAN_EVENT_INFO_TYPE_FID,  identifying a child object. Note that for the directory entry
              modification events FAN_CREATE,  FAN_DELETE,  FAN_MOVE,  and  FAN_RENAME,  an  information  record
              identifying  the  created/deleted/moved  child  object  is  reported only if an fanotify group was
              initialized with the flag FAN_REPORT_TARGET_FID.

       fsid   C’est un identifiant unique du système de fichiers contenant  l’objet  associé  avec  l’évènement.
              C’est  une  structure  de  type __kernel_fsid_t et elle contient la même valeur que f_fsid lors de
              l’appel statfs(2).

       file_handle
              This is a variable length structure of type struct  file_handle.  It  is  an  opaque  handle  that
              corresponds  to  a specified object on a filesystem as returned by name_to_handle_at(2). It can be
              used to uniquely  identify  a  file  on  a  filesystem  and  can  be  passed  as  an  argument  to
              open_by_handle_at(2).  If  the value of info_type field is FAN_EVENT_INFO_TYPE_DFID_NAME, the file
              handle is followed by a null terminated string that identifies the created/deleted/moved directory
              entry name. For other events such as FAN_OPEN, FAN_ATTRIB, FAN_DELETE_SELF, and FAN_MOVE_SELF,  if
              the  value  of  info_type  field is FAN_EVENT_INFO_TYPE_FID, the file_handle identifies the object
              correlated to the event.  If  the  value  of  info_type  field  is  FAN_EVENT_INFO_TYPE_DFID,  the
              file_handle  identifies  the directory object correlated to the event or the parent directory of a
              non-directory  object  correlated  to  the  event.  If   the   value   of   info_type   field   is
              FAN_EVENT_INFO_TYPE_DFID_NAME,  the file_handle identifies the same directory object that would be
              reported with FAN_EVENT_INFO_TYPE_DFID and the file handle is followed by a null terminated string
              that identifies the name of a directory entry in that directory, or '.' to identify the  directory
              object itself.

       The fields of the fanotify_event_info_pidfd structure are as follows:

       hdr    This  is  a  structure  of  type fanotify_event_info_header. When an fanotify group is initialized
              using FAN_REPORT_PIDFD, the info_type field value of  the  fanotify_event_info_header  is  set  to
              FAN_EVENT_INFO_TYPE_PIDFD.

       pidfd  This is a process file descriptor that refers to the process responsible for generating the event.
              The  returned process file descriptor is no different from one which could be obtained manually if
              pidfd_open(2)  were to be called on fanotify_event_metadata.pid. In the instance that an error  is
              encountered  during  pidfd  creation,  one  of  two possible error types represented by a negative
              integer value may be returned in this pidfd field. In cases  where  the  process  responsible  for
              generating the event has terminated prior to the event listener being able to read events from the
              notification  queue, FAN_NOPIDFD is returned. The pidfd creation for an event is only performed at
              the time the events are read from the  notification  queue.  All  other  possible  pidfd  creation
              failures  are  represented  by FAN_EPIDFD. Once the event listener has dealt with an event and the
              pidfd is no longer required, the pidfd should be closed via close(2).

       The fields of the fanotify_event_info_error structure are as follows:

       hdr    This  is  a  structure  of  type  fanotify_event_info_header.  The  info_type  field  is  set   to
              FAN_EVENT_INFO_TYPE_ERROR.

       error  Identifies the type of error that occurred.

       error_count
              This is a counter of the number of errors suppressed since the last error was read.

       Les  macros  suivantes  sont  fournies  pour  itérer  sur un tampon contenant les métadonnées d’événement
       fanotify renvoyées par read(2) à partir d’un descripteur de fichier fanotify.

       FAN_EVENT_OK(meta, len)
              Cette macro compare la taille restante len  du  tampon  meta  à  la  taille  de  la  structure  de
              métadonnées et au champ event_len de la première structure de métadonnées du tampon.

       FAN_EVENT_NEXT(meta, len)
              Cette  macro  utilise  la  taille  indiquée dans le champ event_len de la structure de métadonnées
              pointée par meta pour calculer l’adresse de la prochaine structure de métadonnées qui  suit  meta.
              len  est  le  nombre  d’octets  de  métadonnées  qui restent actuellement dans le tampon. La macro
              renvoie un pointeur vers la prochaine structure de métadonnées qui suit  meta  et  réduit  len  du
              nombre  d’octets dans la structure de métadonnées qui a été sautée (c’est-à-dire qu’elle soustrait
              meta->event_len de len).

       De plus, il existe :

       FAN_EVENT_METADATA_LEN
              Cette macro renvoie la taille (en octet) de la structure fanotify_event_metadata. C’est la  taille
              minimale (et actuellement la seule taille) de métadonnées d’événements.

   Surveiller un descripteur de fichier fanotify pour les événements
       Quand  un  événement  fanotify  survient,  le  descripteur  de fichier fanotify est indiqué comme lisible
       lorsque passé à epoll(7), poll(2) ou select(2).

   Traitement des événements de permission
       Pour les événements de permission, l’application doit écrire (avec write(2)) une structure  de  la  forme
       suivante sur le descripteur de fichier fanotify :

           struct fanotify_response {
               __s32 fd;
               __u32 response;
           };

       Les membres de cette structure sont les suivants :

       fd     C’est le descripteur de fichier de la structure fanotify_event_metadata.

       response
              Ce  champ  indique  si  les  droits  doivent  être  attribués  ou non. Cette valeur doit être soit
              FAN_ALLOW pour permettre l’opération  de  fichier,  soit  FAN_DENY  pour  refuser  l’opération  de
              fichier.

       Si  l’accès  est  refusé,  l’appel  de  l’application requérante recevra une erreur EPERM. De plus, si le
       groupe de notifications a été créé avec l’attribut FAN_ENABLE_AUDIT, alors l’attribut FAN_AUDIT peut être
       défini dans le champ response. Dans ce cas, le sous-système d’audit journalisera l’information  à  propos
       de la décision d’accès aux journaux d’audit.

   Monitoring filesystems for errors
       A  single  FAN_FS_ERROR  event  is stored per filesystem at once. Extra error messages are suppressed and
       accounted for in the error_count field of the existing FAN_FS_ERROR event record, but details  about  the
       errors are lost.

       Errors  reported  by FAN_FS_ERROR are generic errno values, but not all kinds of error types are reported
       by all filesystems.

       Errors not directly related to a file (i.e.  super  block  corruption)   are  reported  with  an  invalid
       file_handle. For these errors, the file_handle will have the field handle_type set to FILEID_INVALID, and
       the handle buffer size set to 0.

   Fermeture du descripteur de fichier fanotify
       Quand  tous  les  descripteurs de fichier se référant au groupe de notifications fanotify sont fermés, le
       groupe fanotify est libéré et ses ressources sont libérées pour être réutilisées par le  noyau.  Lors  de
       l’appel de close(2), les événements de permission restants seront définis à permis.

   Interfaces /proc
       Le  fichier  /proc/[pid]/fdinfo/[fd]  contient  des  renseignements  sur  les  marques  fanotify  pour le
       descripteur de fichier fd du processus pid. Consultez proc(5) pour plus de précisions.

       Since Linux 5.13, the following interfaces can be used to control the amount of kernel resources consumed
       by fanotify:

       /proc/sys/fs/fanotify/max_queued_events
              The value in this file is used when an application calls fanotify_init(2) to set an upper limit on
              the number of events that can be queued to the corresponding fanotify group. Events in  excess  of
              this  limit  are  dropped,  but an FAN_Q_OVERFLOW event is always generated. Prior to Linux kernel
              5.13, the hardcoded limit was 16384 events.

       /proc/sys/fs/fanotify/max_user_group
              This specifies an upper limit on the number of fanotify groups that can be created per  real  user
              ID. Prior to Linux kernel 5.13, the hardcoded limit was 128 groups per user.

       /proc/sys/fs/fanotify/max_user_marks
              This  specifies  an  upper limit on the number of fanotify marks that can be created per real user
              ID. Prior to Linux kernel 5.13, the hardcoded limit was 8192 marks per group (not per user).

ERREURS

       En plus des erreurs habituelles de read(2), les erreurs suivantes peuvent survenir  lors  de  la  lecture
       d’un descripteur de fichier fanotify.

       EINVAL Le tampon est trop petit pour contenir l’événement.

       EMFILE La  limite par processus du nombre de fichiers ouverts a été atteinte. Consultez la description de
              RLIMIT_NOFILE dans getrlimit(2).

       ENFILE La  limite  du  nombre  de  fichiers  ouverts  sur  le   système   a   été   atteinte.   Consultez
              /proc/sys/fs/file-max dans proc(5).

       ETXTBSY
              Cette  erreur  est  renvoyée  par  read(2)  si O_RDWR ou O_WRONLY ont été indiqués dans l’argument
              event_f_flags lors de l’appel fanotify_init(2) et qu’un événement  est  survenu  pour  un  fichier
              surveillé actuellement en cours d’exécution.

       En  plus  des  erreurs habituelles de write(2), les erreurs suivantes peuvent survenir lors de l’écriture
       sur un descripteur de fichier fanotify.

       EINVAL Les droits d’accès fanotify ne sont pas activés dans la configuration du noyau  ou  la  valeur  de
              response dans la structure de réponse n’est pas valable.

       ENOENT Le  descripteur  de  fichier  fd  dans  la  structure  de réponse n’est pas valable. Cela pourrait
              survenir quand une réponse pour l’événement de permission a déjà été écrite.

VERSIONS

       The fanotify API was introduced in Linux 2.6.36 and enabled in Linux 2.6.37. Fdinfo support was added  in
       Linux 3.8.

STANDARDS

       L’interface de programmation fanotify est spécifique à Linux.

NOTES

       L’interface  de  programmation fanotify n’est disponible que si le noyau a été construit avec l’option de
       configuration CONFIG_FANOTIFY activée. De plus, le traitement de permission fanotify n’est disponible que
       si l’option de configuration CONFIG_FANOTIFY_ACCESS_PERMISSIONS est activée.

   Limites et réserves
       Fanotify ne signale que les événements déclenchés par un programme en espace utilisateur à  l’aide  d’une
       interface  de  programmation de système de fichiers. Par conséquent, elle n’intercepte pas les événements
       qui surviennent sur les systèmes de fichiers en réseau.

       L'interface fanotify ne signale pas les accès ni les modifications de fichier qui pourraient  survenir  à
       cause de mmap(2), msync(2) ou munmap(2).

       Les  événements  pour  répertoire  ne  sont  créés que si le répertoire lui-même est ouvert, lu et fermé.
       Ajouter, supprimer ou modifier les enfants d’un  répertoire  marqué  ne  crée  pas  d’événement  pour  le
       répertoire surveillé lui-même.

       La  surveillance fanotify des répertoires n'est pas récursive : pour surveiller les sous-répertoires, des
       marques supplémentaires doivent être créées. L’évènement FAN_CREATE peut être utilisé pour détecter quand
       un sous-répertoire a été créé dans un répertoire marqué. Une marque supplémentaire doit être définie dans
       le sous-répertoire nouvellement créé. Cette approche crée une situation  de  compétition,  parce  qu’elle
       peut  perdre  les  évènements  qui se produisent dans le nouveau sous-répertoire avant qu’une marque soit
       ajoutée dans ce sous-répertoire. La surveillance des montages offre la capacité de  surveiller  un  arbre
       entier  de  répertoires  sans ce problème de chronologie. La surveillance de système de fichiers offre la
       capacité de surveiller tout montage d’une instance de système de fichiers sans situation de compétition.

       La file d'événements peut déborder. Dans ce cas, les événements sont perdus.

BOGUES

       Avant Linux 3.19, fallocate(2) ne créait pas  d'événement  fanotify.  Depuis  Linux 3.19,  les  appels  à
       fallocate(2) créent des événements FAN_MODIFY.

       Dans Linux 3.17, les bogues suivants existent :

       -  Dans  Linux,  un  objet  du système de fichiers pourrait être accessible par de multiples chemins. Par
          exemple, une partie d'un système de fichiers pourrait être remontée avec l'option --bind de  mount(8).
          Un  écoutant  ayant  marqué  un montage ne sera notifié que des événements déclenchés pour un objet du
          système de fichiers utilisant le même montage. Tout autre événement passera inaperçu.

       -  Quand un  événement  est  créé,  aucune  vérification  n’est  effectuée  pour  voir  si  l’identifiant
          utilisateur  du  processus  recevant  a  le  droit  de  lire  ou  écrire le fichier avant de passer un
          descripteur de  fichier  pour  ce  fichier.  Cela  pose  un  risque  de  sécurité  quand  la  capacité
          CAP_SYS_ADMIN est définie pour un programme exécuté par les utilisateurs ordinaires.

       -  Si  un  appel de read(2) traite plusieurs événements de la file fanotify et qu’une erreur survient, la
          valeur de retour sera la taille totale des événements copiés  correctement  dans  le  tampon  d’espace
          utilisateur  avant  que l’erreur ne survienne. La valeur de retour ne sera pas -1 et errno ne sera pas
          définie. Ainsi, l’application lisant n’a aucun moyen de détecter l’erreur.

EXEMPLES

       Les deux programmes ci-dessous montrent l’utilisation de l’API de fanotify.

   Exemple de programme : fanotify_example.c
       Le programme suivant montre l’utilisation de l’interface de programmation fanotify avec les  informations
       d’évènements  d’objet  passées  sous  la forme d’un descripteur de fichier. Il marque le point de montage
       passé en argument de ligne de commande et attend les événements de type FAN_OPEN_PERM et FAN_CLOSE_WRITE.
       Quand un événement de permission survient, une réponse FAN_ALLOW est donnée.

       La sortie suivante de session  d’interpréteur  de  commande  montre  un  exemple  de  l’exécution  de  ce
       programme.  Cette  session  concerne l’édition du fichier /home/utilisateur/temp/notes. Avant d’ouvrir le
       fichier,  un  événement  FAN_OPEN_PERM  est  survenu.  Après  la  fermeture  du  fichier,  un   événement
       FAN_CLOSE_WRITE est survenu. L’exécution du programme se termine quand l’utilisateur appuie sur la touche
       Entrée.

           # ./fanotify_exemple /home
           Appuyer sur la touche Entrée pour quitter.
           En écoute d’événements.
           FAN_OPEN_PERM : Fichier /home/utilisateur/temp/notes
           FAN_CLOSE_WRITE : Fichier /home/utilisateur/temp/notes

           Arrêt de l’écoute d’événements.

   Source du programme : fanotify_example.c

       #define _GNU_SOURCE  /* Nécessaire pour obtenir la définition de 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'. */

       static void
       handle_events(int fd)
       {
           const struct fanotify_event_metadata *metadata;
           struct fanotify_event_metadata buf[200];
           ssize_t len;
           char path[PATH_MAX];
           ssize_t path_len;
           char procfd_path[PATH_MAX];
           struct fanotify_response response;

           /* Boucler tant que les événements peuvent être lus à partir du
              descripteur de fichier fanotify */

           for (;;) {

               /* Lire certains événements */

               len = read(fd, buf, sizeof(buf));
               if (len == -1 && errno != EAGAIN) {
                   perror("read");
                   exit(EXIT_FAILURE);
               }

               /* Vérifier si la fin des données disponibles est atteinte */

               if (len <= 0)
                   break;

               /* Pointer vers le premier événement du tampon */

               metadata = buf;

               /* Boucler sur tous les événements du tampon */

               while (FAN_EVENT_OK(metadata, len)) {

                   /* Vérifier que les structures au moment de l’exécution et
                      de la compilation correspondent */

                   if (metadata->vers != FANOTIFY_METADATA_VERSION) {
                       fprintf(stderr,
                   "Non correspondance de version de métadonnées fanotify.\n");
                       exit(EXIT_FAILURE);
                   }

                   /* metadata->fd contient soit FAN_NOFD, indiquant un
                      dépassement de file, soit un descripteur de fichier
                      (un entier positif).
                      Ici, le dépassement de file est simplement ignoré. */

                   if (metadata->fd >= 0) {

                       /* Traiter l’événement de permission d’ouverture */

                       if (metadata->mask & FAN_OPEN_PERM) {
                           printf("FAN_OPEN_PERM : ");

                           /* Permettre d’ouvrir le fichier */

                           response.fd = metadata->fd;
                           response.response = FAN_ALLOW;
                           write(fd, &response, sizeof(response));
                       }

                       /* Traiter l’événement de fermeture de fichier ouvert
                          en écriture */

                       if (metadata->mask & FAN_CLOSE_WRITE)
                           printf("FAN_CLOSE_WRITE : ");

                       /* Récupérer et afficher le chemin du fichier accédé */

                       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\n", path);

                       /* Fermer le descripteur de fichier de l’événement */

                       close(metadata->fd);
                   }

                   /* Avancer au prochain événement */

                   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];

           /* Vérifier qu’un point de montage est fourni */

           if (argc != 2) {
               fprintf(stderr, "Utilisation : %s MONTAGE\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           printf("Appuyer sur la touche Entrée pour quitter.\n");

           /* Créer le descripteur de fichier pour accéder à l’interface de
              programmation fanotify */

           fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
                              O_RDONLY | O_LARGEFILE);
           if (fd == -1) {
               perror("fanotify_init");
               exit(EXIT_FAILURE);
           }

           /* Marquer le montage pour :
              — les événements de permission avant d’ouvrir les fichiers
              — les événements de notification après fermeture de descripteur
                de fichier ouvert en écriture */

           if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
                             FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,
                             argv[1]) == -1) {
               perror("fanotify_mark");
               exit(EXIT_FAILURE);
           }

           /* Préparer pour la scrutation (polling) */

           nfds = 2;

           fds[0].fd = STDIN_FILENO;       /* Entrée de console */
           fds[0].events = POLLIN;

           fds[1].fd = fd;                 /* Entrée fanotify */
           fds[1].events = POLLIN;

           /* Boucle en attente d’arrivée d’événements */

           printf("En écoute d’événements.\n");

           while (1) {
               poll_num = poll(fds, nfds, -1);
               if (poll_num == -1) {
                   if (errno == EINTR)     /* Interrompu par un signal */
                       continue;           /* Redémarrage de poll() */

                   perror("poll");         /* Erreur inattendue */
                   exit(EXIT_FAILURE);
               }

               if (poll_num > 0) {
                   if (fds[0].revents & POLLIN) {

                       /* Entrée de console disponible :
                          effacer l’entrée standard et quitter */

                       while (read(STDIN_FILENO, &buf, 1) > 0 && buf != '\n')
                           continue;
                       break;
                   }

                   if (fds[1].revents & POLLIN) {

                       /* Des événements fanotify sont disponibles */

                       handle_events(fd);
                   }
               }
           }

           printf("Arrêt de l’écoute d’événements.\n");
           exit(EXIT_SUCCESS);
       }

   Exemple de programme : fanotify_fid.c
       The  second  program  is  an  example of fanotify being used with a group that identifies objects by file
       handles. The program marks the filesystem object that is passed as  a  command-line  argument  and  waits
       until an event of type FAN_CREATE has occurred. The event mask indicates which type of filesystem object—
       either  a  file  or a directory—was created. Once all events have been read from the buffer and processed
       accordingly, the program simply terminates.

       Les sessions d’interpréteur de commande suivantes montrent deux invocations différentes avec des  actions
       différentes réalisées sur l’objet désiré.

       La  première  session montre une marque placée sur /home/utilisateur. Cela est suivi par la création d’un
       fichier normal, /home/utilisateur/fichiertest.txt. Cela aboutit  à  un  évènement  FAN_CREATE  généré  et
       rapporté  à  l’objet  de  répertoire  surveillé  parent  du  fichier  et à la création du nom de fichier.
       L’exécution du programme se termine une fois que tous les évènements capturés du tampon ont été traités.

           # ./fanotify_fid /home/user
           Listening for events.
           FAN_CREATE (file created):
                   Directory /home/user has been modified.
                   Entry 'testfile.txt' is not a subdirectory.
           All events processed successfully. Program exiting.

           $ touch /home/utilisateur/fichiertest.txt   # Dans un autre terminal

       La première session montre une marque placée sur /home/utilisateur. C’est  suivi  par  la  création  d’un
       répertoire,  /home/utilisateur/réptest.  Cette  action  spécifique aboutit à la génération d’un évènement
       FAN_CREATE et est rapporté avec l’attribut FAN_ONDIR défini et avec la création du nom de répertoire.

           # ./fanotify_fid /home/user
           Listening for events.
           FAN_CREATE | FAN_ONDIR (subdirectory created):
                   Directory /home/user has been modified.
                   Entry 'testdir' is a subdirectory.
           All events processed successfully. Program exiting.

           $ mkdir -p /home/utilisateur/réptest      # Dans un autre terminal

   Source du programme : fanotify_fid.c

       #define _GNU_SOURCE
       #include <errno.h>
       #include <fcntl.h>
       #include <limits.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <sys/fanotify.h>
       #include <unistd.h>

       #define BUF_SIZE 256

       int
       main(int argc, char *argv[])
       {
           int fd, ret, event_fd, mount_fd;
           ssize_t len, path_len;
           char path[PATH_MAX];
           char procfd_path[PATH_MAX];
           char events_buf[BUF_SIZE];
           struct file_handle *file_handle;
           struct fanotify_event_metadata *metadata;
           struct fanotify_event_info_fid *fid;
           const char *file_name;
           struct stat sb;

           if (argc != 2) {
               fprintf(stderr, "nb d’arguments de ligne de commande non valable.\n");
               exit(EXIT_FAILURE);
           }

           mount_fd = open(argv[1], O_DIRECTORY | O_RDONLY);
           if (mount_fd == -1) {
               perror(argv[1]);
               exit(EXIT_FAILURE);
           }

           /* Créer un descripteur de fichier avec FAN_REPORT_DFID_NAME sous
              forme d’attribut de façon que le programme puisse recevoir des
              évènements fid avec des noms de répertoire d’entrée */

           fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME, 0);
           if (fd == -1) {
               perror("fanotify_init");
               exit(EXIT_FAILURE);
           }

           /* Placer une marque sur un objet de système de fichiers
              fourni dans argv[1]. */

           ret = fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_ONLYDIR,
                               FAN_CREATE | FAN_ONDIR,
                               AT_FDCWD, argv[1]);
           if (ret == -1) {
               perror("fanotify_mark");
               exit(EXIT_FAILURE);
           }

           printf("En écoute d’événements.\n");

               /* Lire les évènements dans la file dans le tampon */

           len = read(fd, events_buf, sizeof(events_buf));
           if (len == -1 && errno != EAGAIN) {
               perror("read");
               exit(EXIT_FAILURE);
           }

               /* Traiter tous les événements du tampon */

           for (metadata = (struct fanotify_event_metadata *) events_buf;
                   FAN_EVENT_OK(metadata, len);
                   metadata = FAN_EVENT_NEXT(metadata, len)) {
               fid = (struct fanotify_event_info_fid *) (metadata + 1);
               file_handle = (struct file_handle *) fid->handle;

               /* Assurer que l’info d’évènement soit du type correct */

               if (fid->hdr.info_type == FAN_EVENT_INFO_TYPE_FID ||
                   fid->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID) {
                   file_name = NULL;
               } else if (fid->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID_NAME) {
                   file_name = file_handle->f_handle +
                               file_handle->handle_bytes;
               } else {
                   fprintf(stderr, "Type inattendu d’évènement reçu.\n");
                   exit(EXIT_FAILURE);
               }

               if (metadata->mask == FAN_CREATE)
                   printf("FAN_CREATE (file created):\n");

               if (metadata->mask == (FAN_CREATE | FAN_ONDIR))
                   printf("FAN_CREATE | FAN_ONDIR (sous_répertoire créé) :\n");

            /* metadata->fd is set to FAN_NOFD when the group identifies
               objects by file handles. To obtain a file descriptor for
               the file object corresponding to an event you can use the
               struct file_handle that's provided within the
               fanotify_event_info_fid in conjunction with the
               open_by_handle_at(2) system call. A check for ESTALE is
               done to accommodate for the situation where the file handle
               for the object was deleted prior to this system call. */

               event_fd = open_by_handle_at(mount_fd, file_handle, O_RDONLY);
               if (event_fd == -1) {
                   if (errno == ESTALE) {
                       printf("Le gestionnaire de fichiers n’est plus valable, "
                               "le fichier a été supprimé\n");
                       continue;
                   } else {
                       perror("open_by_handle_at");
                       exit(EXIT_FAILURE);
                   }
               }

               snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d",
                       event_fd);

               /* Retrouver et afficher le chemin de l’entrée modifiée */

               path_len = readlink(procfd_path, path, sizeof(path) - 1);
               if (path_len == -1) {
                   perror("readlink");
                   exit(EXIT_FAILURE);
               }

               path[path_len] = '\0';
               printf("\tDirectory '%s' has been modified.\n", path);

               if (file_name) {
                   ret = fstatat(event_fd, file_name, &sb, 0);
                   if (ret == -1) {
                       if (errno != ENOENT) {
                           perror("fstatat");
                           exit(EXIT_FAILURE);
                       }
                       printf("\tEntry '%s' does not exist.\n", file_name);
                   } else if ((sb.st_mode & S_IFMT) == S_IFDIR) {
                       printf("\tEntry '%s' is a subdirectory.\n", file_name);
                   } else {
                       printf("\tEntry '%s' is not a subdirectory.\n",
                               file_name);
                   }
               }

                       /* Fermer le descripteur de fichier de l’événement */

               close(event_fd);
           }

           printf("Tous les évènements traités avec succès, fin du programme.\n");
           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       fanotify_init(2), fanotify_mark(2), inotify(7)

TRADUCTION

       La traduction française de cette page de manuel a été créée par Christophe Blaess
       <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud
       <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard
       <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau
       <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François
       <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard
       <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot
       <david@tilapin.org> et Jean-Paul Guillonneau <guillonneau.jeanpaul@free.fr>

       Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License
       version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à
       debian-l10n-french@lists.debian.org.

Pages du manuel de Linux 6.03                    5 février 2023                                      fanotify(7)