Provided by: manpages-fr-dev_4.15.0-9_all bug

NOM

       memfd_create - Créer un fichier anonyme

SYNOPSIS

       #define _GNU_SOURCE         /* Consultez feature_test_macros(7) */
       #include <sys/mman.h>

       int memfd_create(const char *name, unsigned int flags);

DESCRIPTION

       memfd_create()  crée  un  fichier  anonyme  et  renvoie  un descripteur de fichier qui s'y
       rapporte. Le fichier se comporte comme un fichier  normal,  il  peut  donc  être  modifié,
       tronqué, projeté en mémoire, et ainsi de suite. Mais contrairement à un fichier normal, il
       réside dans la RAM et son stockage est volatile. Une fois que  toutes  les  références  au
       fichier  ont  disparu, il est automatiquement libéré. La mémoire anonyme est utilisée pour
       toutes les pages de sauvegarde du fichier. Les fichiers créés par memfd_create() ont  donc
       la  même  sémantique  que  les autres allocations de mémoire anonyme telles que celles qui
       utilisent mmap(2) avec l'attribut MAP_ANONYMOUS.

       La taille initiale du fichier est positionnée  à  0.  Après  l'appel,  elle  devrait  être
       définie  en  utilisant  ftruncate(2)  (ou  le  fichier  peut  être rempli par des appels à
       write(2) ou équivalent).

       Le nom fourni dans name est utilisé comme nom de fichier et sera affiché en tant que cible
       du  lien  symbolique  correspondant  dans  le  répertoire /proc/self/fd/. Le nom affiché a
       toujours un préfixe memfd: et il ne sert que pour le débogage. Les noms ne changent pas le
       comportement  du  descripteur  de  fichier  et en tant que tels plusieurs fichiers peuvent
       avoir le même nom sans effets de bord.

       Les valeurs suivantes peuvent subir une opération OU logique bit à  bit  dans  flags  pour
       modifier le comportement de memfd_create() :

       MFD_CLOEXEC
              Placer  l'attribut  « close-on-exec »  (FD_CLOEXEC)  sur  le nouveau descripteur de
              fichier. Consultez la description de l'attribut O_CLOEXEC dans open(2) pour  savoir
              pourquoi cela peut être utile.

       MFD_ALLOW_SEALING
              Permettre  des  opérations  de  verrouillage  sur ce fichier. Voir le point sur les
              opérations  F_ADD_SEALS  et  F_GET_SEALS  dans  fcntl(2),  ainsi  que   les   NOTES
              ci-dessous.  Le  positionnement initial des verrous est vide. Si cet attribut n'est
              pas défini, le positionnement initial des verrous sera  F_SEAL_SEAL,  ce  qui  veut
              dire qu'aucun autre verrou ne peut être positionné sur le fichier.

       MFD_HUGETLB (depuis Linux 4.14)
              Le  fichier  anonyme  sera  créé  sur le système de fichiers hugetlbfs en utilisant
              d'immenses pages. Voir le fichier Documentation/admin-guide/mm/hugetlbpage.rst  des
              sources du noyau Linux pour plus d'informations sur hugetlbfs. Le fait d'indiquer à
              la fois MFD_HUGETLB et MFD_ALLOW_SEALING dans flags est pris en charge depuis Linux
              4.16.

       MFD_HUGE_2MB, MFD_HUGE_1GB, ...
              Utilisé  avec  MFD_HUGETLB  pour  sélectionner  d'autres  tailles  de  page hugetlb
              (respectivement 2 Mo, 1 Go, ...) sur les systèmes qui gèrent plusieurs  tailles  de
              page hugetlb. Les définitions des tailles de page immenses connues figurent dans le
              fichier d'entête <linux/memfd.h>.

              Pour des détails sur l'encodage des tailles des pages immenses ne figurant pas dans
              le fichier d'entête, voir le point sur les constantes du même nom dans mmap(2).

       Les bits inusitées dans flags doivent valoir 0.

       En  code de retour, memfd_create() renvoie un nouveau descripteur de fichier qui peut être
       utilisé pour se référer au fichier. Ce descripteur de fichier est ouvert en lecture et  en
       écriture (O_RDWR)  et O_LARGEFILE est positionné pour le descripteur de fichier.

       Par  rapport à fork(2) et execve(2), la sémantique habituelle s'applique au descripteur de
       fichier créé par memfd_create(). Une copie du descripteur de  fichier  est  récupérée  par
       l'enfant  produit  par  fork(2)  et  elle  se  rapporte au même fichier. Le descripteur de
       fichier est préservé  pendant  un  execve(2),  sauf  si  l'attribut  close-on-exec  a  été
       positionné.

VALEUR RENVOYÉE

       En  cas  de  succès,  memfd_create()  renvoie  un  nouveau  descripteur de fichier. En cas
       d'erreur, -1 est renvoyé et errno est positionné pour indiquer l'erreur.

ERREURS

       EFAULT L'adresse dans name pointe vers une mémoire non valable.

       EINVAL flags comprend des bits inconnus.

       EINVAL name était trop long (la limite de 249 octets, n'incluant pas l'octet NULL final).

       EINVAL MFD_HUGETLB et MFD_ALLOW_SEALING ont tous deux été indiqués dans flags.

       EMFILE La limite du nombre de descripteurs de fichiers par processus a été atteinte.

       ENFILE La limite du nombre total  de  fichiers  ouverts  pour  le  système  entier  a  été
              atteinte.

       ENOMEM Mémoire insuffisante pour créer un nouveau fichier anonyme.

VERSIONS

       L'appel  système  memfd_create()  est  apparu dans Linux 3.17 ; la glibc le gère depuis la
       version 2.27.

       EPERM  The MFD_HUGETLB flag was specified, but the caller was not privileged (did not have
              the  CAP_IPC_LOCK  capability)  and is not a member of the sysctl_hugetlb_shm_group
              group; see the description of /proc/sys/vm/sysctl_hugetlb_shm_group in proc(5).

CONFORMITÉ

       L'appel système memfd_create() est spécifique à Linux.

NOTES

       L'appel système memfd_create() offre une alternative simple au montage manuel d'un système
       de  fichiers  tmpfs(5)  et  à  la  création et l'ouverture d'un fichier dans ce système de
       fichiers. Le premier objectif  de  memfd_create()  est  de  créer  des  fichiers  et  leur
       descripteur associé, utilisés avec les API de verrou de fichiers fournis par fcntl(2).

       L'appel  système memfd_create() s'utilise également sans verrou de fichier (c'est pourquoi
       le verrouillage de  fichier  a  été  désactivé  sauf  demande  explicite  avec  l'attribut
       MFD_ALLOW_SEALING).  En particulier, il peut être utilisé comme alternative pour créer des
       fichiers dans tmp ou pour utiliser O_TMPFILE de open(2), si vous ne voulez  pas  rattacher
       le fichier résultant au système de fichiers.

   Verrou de fichiers
       En  l'absence  de  verrou  de fichier, les processus qui communiquent à travers la mémoire
       partagée doivent soit se faire confiance entre eux, soit prendre des mesures pour gérer la
       possibilité  qu'un  pair  non  fiable  manipule  la  région de mémoire partagée de manière
       problématique. Par exemple, un pair non fiable pourrait modifier le contenu de la  mémoire
       partagée  n'importe quand ou rétrécir la zone de mémoire partagée. La première éventualité
       rend    le    processus    local    vulnérable    aux    conflits    (race     conditions)
       time-of-check-to-time-of-use  (généralement  gérés  en  copiant  les données de la zone de
       mémoire partagée avant de les vérifier et de les utiliser). La deuxième  éventualité  rend
       le  processus  local  vulnérable  aux  signaux  SIGBUS  quand  on  essaie  d'accéder  à un
       emplacement inexistant dans la zone de mémoire partagée (gérer cette éventualité  implique
       d'utiliser un gestionnaire pour le signal SIGBUS).

       La  gestion  de pairs non fiables impose une plus grande complexité du code qui utilise la
       mémoire partagée. Les verrous mémoire éliminent  cette  complexité,  en  permettant  à  un
       processus d'agir en toute sécurité en sachant que son pair ne peut pas modifier la mémoire
       partagée de manière non souhaitée.

       Voici un exemple d'utilisation du mécanisme de verrouillage :

       1. Le premier processus crée un fichier  tmpfs(5)  en  utilisant  memfd_create().  L'appel
          donne un descripteur de fichier utilisé dans les étapes ultérieures.

       2. Le  premier  processus  dimensionne  le  fichier créé à l'étape précédente en utilisant
          ftruncate(2), il le projette en utilisant mmap(2) et il  remplit  la  mémoire  partagée
          avec les données désirées.

       3. Le  premier  processus  utilise  l'opération  F_ADD_SEALS  de fcntl(2) pour poser un ou
          plusieurs verrous sur le fichier afin de restreindre des modifications ultérieures  (si
          on  pose  un  verrou  F_SEAL_WRITE,  il  sera  nécessaire  de désassocier la projection
          modifiable partagée créée à l'étape précédente. Sinon, on peut obtenir un  comportement
          identique  à F_SEAL_WRITE en utilisant F_SEAL_FUTURE_WRITE, qui empêchera des écritures
          ultérieures à l'aide de mmap(2) et de write(2),  tout  en  conservant  les  projections
          modifiables partagées existantes).

       4. Un  deuxième processus obtient un descripteur de fichier pour le fichier tmpfs(5) et le
          projette. Parmi les origines possibles de cela, vous trouverez :

          –  Le processus qui a appelé memfd_create() a pu transférer le descripteur  de  fichier
             consécutif  au deuxième processus à l'aide d'un socket de domaine UNIX (voir unix(7)
             et cmsg(3)). Le deuxième processus projette alors le fichier en utilisant mmap(2).

          –  Le deuxième  processus  est  créé  à  l'aide  de  fork(2)  et,  ainsi,  il  récupère
             automatiquement  le  descripteur  de fichier et sa projection (remarquez que dans ce
             cas et dans le prochain, il existe une relation de  confiance  naturelle  entre  les
             deux  processus  puisqu'ils  tournent sous le même identifiant utilisateur. Donc, un
             verrou de fichier n'est, en principe, pas nécessaire).

          –  Le  deuxième  processus  ouvre  le  fichier  /proc/<pid>/fd/<fd>,   où   <pid>   est
             l'identifiant  de processus du premier processus (celui qui a appelé memfd_create())
             et <fd> est le numéro du descripteur de fichier renvoyé par l'appel  à  memfd_create
             dans  ce  processus.  Le deuxième processus projette ensuite le fichier en utilisant
             mmap(2).

       5. Le deuxième processus utilise l'opération F_GET_SEALS de  fcntl(2)  pour  récupérer  le
          masque  de  bits  de  verrous  appliqué  au  fichier.  Ce masque peut être examiné pour
          déterminer le type de restrictions posées aux modifications  du  fichier.  Si  vous  le
          souhaitez,  le  deuxième  processus  peut  appliquer  des  verrous supplémentaires pour
          imposer d'autres restrictions (tant que  le  verrou  F_SEAL_SEAL  n'a  pas  encore  été
          appliqué).

EXEMPLES

       Voici  deux  exemples de programme montrant l'utilisation de memfd_create() et de l'API de
       verrou de fichier.

       Le  premier  programme,  t_memfd_create.c,  crée  un   fichier   tmpfs(5)   en   utilisant
       memfd_create(),  donne  une  taille au fichier, le projette en mémoire et, en option, pose
       des verrous sur le fichier. Le programme accepte jusqu'à  trois  paramètres  en  ligne  de
       commande,  dont les deux premiers sont requis. Le premier paramètre est le nom à donner au
       fichier, le deuxième est la taille à lui donner, le troisième, optionnel, est  une  chaîne
       de caractères qui indique les verrous à poser sur le fichier.

       Le  deuxième  programme,  t_get_seals.c, peut être utilisé pour ouvrir un fichier existant
       créé à l'aide de memfd_create() et examiner les verrous qui y sont posés.

       La session d'interpréteur suivant montre l'utilisation  de  ces  programmes.  Nous  créons
       d'abord un fichier tmpfs(5) et nous posons des verrous dessus :

           $ ./t_memfd_create my_memfd_file 4096 sw &
           [1] 11775
           PID: 11775; fd: 3; /proc/11775/fd/3

       À  ce moment, le programme t_memfd_create continue à s'exécuter en tâche de fond. À partir
       d'un autre programme, nous pouvons obtenir un descripteur de fichier pour le fichier  créé
       par  memfd_create()  en  ouvrant  /proc/[pid]/fd  qui correspond au descripteur de fichier
       ouvert par memfd_create(). En utilisant ce chemin,  nous  examinons  le  contenu  du  lien
       symbolique  /proc/[pid]/fd  et  nous  utilisons  notre programme t_get_seals pour voir les
       verrous posés sur le fichier :

           $ readlink /proc/11775/fd/3
           /memfd:my_memfd_file (deleted)
           $ ./t_get_seals /proc/11775/fd/3
           Verrous existants : WRITE SHRINK

   Source du programme : t_memfd_create.c

       #define _GNU_SOURCE
       #include <stdint.h>
       #include <sys/mman.h>
       #include <fcntl.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <string.h>
       #include <stdio.h>

       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

       int
       main(int argc, char *argv[])
       {
           int fd;
           unsigned int seals;
           char *addr;
           char *name, *seals_arg;
           ssize_t len;

           if (argc < 3) {
               fprintf(stderr, "%s name size [seals]\n", argv[0]);
               fprintf(stderr, "\t'seals' can contain any of the "
                       "following characters:\n");
               fprintf(stderr, "\t\tg - F_SEAL_GROW\n");
               fprintf(stderr, "\t\ts - F_SEAL_SHRINK\n");
               fprintf(stderr, "\t\tw - F_SEAL_WRITE\n");
               fprintf(stderr, "\t\tW - F_SEAL_FUTURE_WRITE\n");
               fprintf(stderr, "\t\tS - F_SEAL_SEAL\n");
               exit(EXIT_FAILURE);
           }

           name = argv[1];
           len = atoi(argv[2]);
           seals_arg = argv[3];

           /* Create an anonymous file in tmpfs; allow seals to be
              placed on the file. */

           fd = memfd_create(name, MFD_ALLOW_SEALING);
           if (fd == -1)
               errExit("memfd_create");

           /* Size the file as specified on the command line. */

           if (ftruncate(fd, len) == -1)
               errExit("truncate");

           printf("PID: %jd; fd: %d; /proc/%jd/fd/%d\n",
                   (intmax_t) getpid(), fd, (intmax_t) getpid(), fd);

           /* Code to map the file and populate the mapping with data
              omitted. */

           /* If a 'seals' command-line argument was supplied, set some
              seals on the file. */

           if (seals_arg != NULL) {
               seals = 0;

               if (strchr(seals_arg, 'g') != NULL)
                   seals |= F_SEAL_GROW;
               if (strchr(seals_arg, 's') != NULL)
                   seals |= F_SEAL_SHRINK;
               if (strchr(seals_arg, 'w') != NULL)
                   seals |= F_SEAL_WRITE;
               if (strchr(seals_arg, 'W') != NULL)
                   seals |= F_SEAL_FUTURE_WRITE;
               if (strchr(seals_arg, 'S') != NULL)
                   seals |= F_SEAL_SEAL;

               if (fcntl(fd, F_ADD_SEALS, seals) == -1)
                   errExit("fcntl");
           }

           /* Keep running, so that the file created by memfd_create()
              continues to exist. */

           pause();

           exit(EXIT_SUCCESS);
       }

   Source du programme : t_get_seals.c

       #define _GNU_SOURCE
       #include <sys/mman.h>
       #include <fcntl.h>
       #include <unistd.h>
       #include <stdlib.h>
       #include <string.h>
       #include <stdio.h>

       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

       int
       main(int argc, char *argv[])
       {
           int fd;
           unsigned int seals;

           if (argc != 2) {
               fprintf(stderr, "%s /proc/PID/fd/FD\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           fd = open(argv[1], O_RDWR);
           if (fd == -1)
               errExit("open");

           seals = fcntl(fd, F_GET_SEALS);
           if (seals == -1)
               errExit("fcntl");

           printf("Existing seals:");
           if (seals & F_SEAL_SEAL)
               printf(" SEAL");
           if (seals & F_SEAL_GROW)
               printf(" GROW");
           if (seals & F_SEAL_WRITE)
               printf(" WRITE");
           if (seals & F_SEAL_FUTURE_WRITE)
               printf(" FUTURE_WRITE");
           if (seals & F_SEAL_SHRINK)
               printf(" SHRINK");
           printf("\n");

           /* Code to map the file and access the contents of the
              resulting mapping omitted. */

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       fcntl(2), ftruncate(2), mmap(2), shmget(2), shm_open(3)

COLOPHON

       Cette page fait partie de la publication 5.13 du projet man-pages Linux.  Une  description
       du  projet et des instructions pour signaler des anomalies et la dernière version de cette
       page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

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-Philippe MENGUAL
       <jpmengual@debian.org>

       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⟩.