Provided by: manpages-fr-dev_4.19.0-7_all bug

NOM

       mremap - Modifier une projection de la mémoire virtuelle

BIBLIOTHÈQUE

       Bibliothèque C standard (libc, -lc)

SYNOPSIS

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

       void *mremap(void old_address[.old_size], size_t old_size,
                    size_t new_size, int flags, ... /* void *new_address */);

DESCRIPTION

       mremap()  agrandit  (ou  diminue)  une  projection (Ndt : mapping) de mémoire virtuelle en
       mémoire réelle, en la déplaçant éventuellement (sous contrôle de l'argument flags et de la
       place disponible dans l'espace d'adressage virtuel).

       old_address  est  l'ancienne  adresse  du  bloc  de  mémoire  virtuelle  à  agrandir (ou à
       diminuer). Veuillez noter que old_address doit être alignée sur  une  frontière  de  page.
       old_size  est  l'ancienne  taille  du  bloc  de  mémoire virtuelle. new_size est la taille
       désirée pour le  nouveau  bloc  de  mémoire.  Un  cinquième  argument,  new_address,  peut
       éventuellement être fourni ; voyez la description de MREMAP_FIXED ci-dessous.

       Si  la  valeur  de  old_size  est  de  zéro  et  si  old_address  renvoie à une projection
       partageable (voir MAP_SHARED de mmap(2)), mremap()  créera  une  nouvelle  projection  des
       mêmes  pages.  new_size  sera  la  taille de la nouvelle projection et l'emplacement de la
       nouvelle  projection  peut  être  indiqué  avec  new_address ;  voir  la  description   de
       MREMAP_FIXED  ci-dessous.  Si  une  nouvelle  projection  est  demandée  à l'aide de cette
       méthode, l'attribut MREMAP_MAYMOVE doit être indiqué également.

       L'argument de masquage flags est soit 0, soit un des attributs suivants :

       MREMAP_MAYMOVE
              Par défaut, s'il n'y a pas suffisamment d'espace pour agrandir une projection à son
              emplacement  actuel,  mremap()  échoue.  Si  ce  drapeau  est utilisé, le noyau est
              autorisé à déplacer la projection à une autre adresse virtuelle si  nécessaire.  Si
              la  projection  est  déplacée,  les  pointeurs  absolus  vers l'ancienne projection
              deviennent caduques (il faut utiliser des décalages  par  rapport  à  l'adresse  de
              début de la projection).

       MREMAP_FIXED (depuis Linux 2.3.31)
              Ce  drapeau a un but similaire à MAP_FIXED pour mmap(2). S'il est utilisé, mremap()
              prend un cinquième argument void *new_address qui contient une adresse alignée  sur
              un  début  de page vers laquelle la projection doit être déplacée. Toute projection
              existant précédemment dans la zone entre new_address et new_size est supprimée.

              Si MREMAP_FIXED est indiqué, MREMAP_MAYMOVE doit également être indiqué.

       MREMAP_DONTUNMAP (depuis Linux 5.7)
              Cet attribut, qui doit être utilisé avec MREMAP_MAYMOVE, refait une projection vers
              une nouvelle adresse mais il ne supprime pas celle à old_address.

              L'attribut  MREMAP_DONTUNMAP  ne  peut être utilisé qu'avec des projections privées
              anonymes (voir la description de MAP_PRIVATE et de MAP_ANONYMOUS dans mmap(2)).

              À la fin, tous les accès à la plage indiquée par old_address et old_size  donneront
              une  erreur  de  pagination.  Elle sera gérée par un gestionnaire userfaultfd(2) si
              l'adresse se situe dans une plage  précédemment  enregistrée  avec  userfaultfd(2).
              Sinon, le noyau alloue une page remplie de zéros pour gérer cette erreur.

              L'attribut MREMAP_DONTUNMAP peut être utilisé pour déplacer de manière atomique une
              projection  tout  en  laissant  la  source  associée.  Voir  les  NOTES  pour   des
              applications possibles de MREMAP_DONTUNMAP.

       Si  le segment de mémoire indiqué par old_address et old_size est verrouillé (par mlock(2)
       ou similaire), ce verrou est maintenu quand le segment  est  modifié  et/ou  déplacé.  Par
       conséquent, la quantité de mémoire verrouillée par le processus peut changer.

VALEUR RENVOYÉE

       mremap()  renvoie  un  pointeur sur la nouvelle zone de mémoire virtuelle s'il réussit. En
       cas d'échec, la valeur MAP_FAILED (c'est-à-dire (void *) -1) est  renvoyée  et  errno  est
       défini pour indiquer l'erreur.

ERREURS

       EAGAIN L'appelant  a  tenté  d'agrandir  un  segment  de  mémoire  verrouillé,  mais c'est
              impossible sans dépasser la limite RLIMIT_MEMLOCK.

       EFAULT Une adresse dans l'intervalle entre old_address et old_address+old_size  n'est  pas
              une  adresse  virtuelle valable pour ce processus. On peut également obtenir EFAULT
              même s'il existe des projections recouvrant la zone complète demandée, mais que ces
              projections sont de types différents.

       EINVAL Un paramètre non valable a été donné. Parmi les causes possibles :

              •  old_address n'était pas aligné sur une page ;

              •  une  autre  valeur  que  MREMAP_MAYMOVE,  MREMAP_FIXED ou MREMAP_DONTUNMAP a été
                 indiquée dans flags ;

              •  new_size était zéro ;

              •  new_size ou new_address n'était pas valable ;

              •  la nouvelle plage d'adresses indiquée  par  new_address  et  new_size  chevauche
                 l'ancienne plage d'adresses indiquée par old_address et old_size ;

              •  MREMAP_FIXED ou MREMAP_DONTUNMAP était indiqué sans MREMAP_MAYMOVE ;

              •  MREMAP_DONTUNMAP  était indiqué mais une ou plusieurs pages de la plage indiquée
                 par old_address et old_size n'étaient pas privées et anonymes ;

              •  MREMAP_DONTUNMAP était indiqué et old_size n'était pas égal à new_size ;

              •  old_size  était  de  zéro  et  old_address  ne  renvoie  pas  à  une  projection
                 partageable (mais voir BOGUES) ;

              •  old_size valait zéro et l'attribut MREMAP_MAYMOVE n'était pas indiqué.

       ENOMEM Pas  assez  de  mémoire  disponible pour terminer l'opération. Les causes possibles
              sont :

              •  La zone de mémoire ne peut pas être agrandie à l'emplacement virtuel actuel,  et
                 l'option MREMAP_MAYMOVE n'a pas été fournie dans flags. Ou encore, il n'y a plus
                 assez de mémoire (virtuelle) disponible.

              •  MREMAP_DONTUNMAP a été utilisé, provoquant la création d'une nouvelle projection
                 qui  dépasserait  la mémoire (virtuelle) disponible. Ou alors elle excéderait le
                 nombre maximal de projections autorisées.

STANDARDS

       Cet appel système est spécifique  à  Linux  et  ne  devrait  pas  être  employé  dans  des
       programmes destinés à être portables.

NOTES

       mremap()  modifie la correspondance entre les adresses virtuelles et les pages de mémoire.
       Ce mécanisme peut être utilisé pour implémenter un realloc(3) très efficace.

       Sous Linux, la mémoire est divisée en pages. Un  processus  utilisateur  dispose  d'un  ou
       plusieurs  segments  linéaires  de  mémoire  virtuelle. À chaque segment correspond une ou
       plusieurs projections dans les pages de mémoire réelle (dans la table des  pages).  Chaque
       segment de mémoire virtuelle dispose de ses propres droits d'accès (sa protection), ce qui
       peut déclencher des fautes de segmentation (SIGSEGV) si l'accès à la mémoire est mal  géré
       (par  exemple,  en  écrivant  dans  un  segment  en lecture seule). De même, une tentative
       d'accès à la mémoire en dehors des segments déclenche une faute de segmentation.

       Si mremap() est utilisé pour déplacer ou étendre une zone  verrouillée  avec  mlock(2)  ou
       équivalent,  l'appel  mremap()  fera  le  maximum  pour  remplir  la nouvelle zone mais il
       n'échouera pas avec ENOMEM si la zone ne peut pas être remplie.

       Avant la glibc 2.4, glibc ne fournissait pas la définition de MREMAP_FIXED et le prototype
       de mremap() ne permettait pas de passer le paramètre new_address.

   Cas d'utilisation de MREMAP_DONTUNMAP
       Parmi les applications possibles de MREMAP_DONTUNMAP :

       •  userfaultfd(2)  non  coopératif :  une  application  peut  retirer une plage d'adresses
          virtuelles en utilisant MREMAP_DONTUNMAP, puis utiliser un gestionnaire  userfaultfd(2)
          pour  gérer  les erreurs de pagination qui arrivent ensuite lorsque d'autres threads du
          processus créent des pages dans la plage retirée.

       •  Récupérateur de mémoire : MREMAP_DONTUNMAP peut être utilisé avec  userfaultfd(2)  pour
          implémenter  des algorithmes de ramasse-miettes (garbage collection) (par exemple, dans
          une machine virtuelle Java). Une telle implémentation peut être moins coûteuse (et plus
          simple)  que  les  techniques de collecte traditionnelles qui impliquent de marquer des
          pages avec une protection PROT_NONE ainsi que l'utilisation d'un  gestionnaire  SIGSEGV
          pour capter les accès à ces pages.

BOGUES

       Avant  Linux 4.14,  si  old_size  valait  zéro  et  si  la projection à laquelle renvoyait
       old_address était une projection privée (MAP_PRIVATE  de  mmap(2)),  mremap()  créait  une
       nouvelle  projection  privée  sans  lien  avec  celle  d'origine.  Ce  comportement  était
       intentionnel et probablement non prévu  dans  des  applications  de  l'espace  utilisateur
       (l'intention  de  mremap()  étant  de  créer  une  nouvelle  projection  à partir de celle
       d'origine). Depuis Linux 4.14, mremap() échoue avec l'erreur EINVAL dans ce scénario.

VOIR AUSSI

       brk(2), getpagesize(2), getrlimit(2), mlock(2), mmap(2), sbrk(2), malloc(3), realloc(3)

       Votre  manuel  favori  à  propos  de  systèmes  d'exploitation,  pour   des   informations
       supplémentaires  sur la mémoire paginée (par exemple Modern Operating Systems de Andrew S.
       Tanenbaum, Inside Linux par Randolf Bentson, The Design of the UNIX Operating  System  par
       Maurice J. Bach)

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