Provided by: manpages-fr_4.18.1-1_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 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ 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⟩.