Provided by: manpages-fr-dev_4.13-4_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.

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

           /* Créer un fichier anonyme dans tmpfs ; permet de poser
               des verrous sur le fichier */

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

           /* Taille du fichier indiquée sur la ligne de commande */

           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 pour projeter le fichier et remplir le plan
              avec des données omises */

           /* Si un paramètre 'seals' de la ligne de commande est fourni,
              poser des verrous sur le fichier */

           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");
           }

           /* Continuer l’exécution pour que le fichier créé par
              memfd_create() continue à exister */

           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 pour associer le fichier et l'accès au contenu de la
              projection résultante omise */

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

Linux                                            1 novembre 2020                                 MEMFD_CREATE(2)