Man page - munmap(2)

Packages contains this manual

Available languages:

en fr pl nl ja ru de

Manual

mmap

NOM
BIBLIOTHÈQUE
SYNOPSIS
DESCRIPTION
Le paramĂštre des attributs
munmap()
VALEUR RENVOYÉE
ERREURS
ATTRIBUTS
VERSIONS
Différences entre bibliothÚque C et noyau
STANDARDS
HISTORIQUE
NOTES
Utilisation sûre de MAP_FIXED
Modifications d’horodatage pour les projections prises en charge par unfichier
Projections de pages immenses (Huge TLB)
BOGUES
EXEMPLES
Source du programme
VOIR AUSSI
TRADUCTION

NOM

mmap, munmap - Établir/supprimer une projection en mĂ©moire (map/unmap) des fichiers ou des pĂ©riphĂ©riques

BIBLIOTHÈQUE

BibliothĂšque C standard ( libc , -lc )

SYNOPSIS

#include <sys/mman.h>

void *mmap(void addr [. length ], size_t length , int prot , int flags ,
int
fd , off_t offset );
int munmap(void
addr [. length ], size_t length );

Consultez la section NOTES pour plus d’informations sur les exigences de la macro de test de fonctionnalitĂ©.

DESCRIPTION

mmap () crĂ©e une nouvelle projection dans l’espace d’adressage virtuel du processus appelant. L’adresse de dĂ©marrage de la nouvelle projection est indiquĂ©e dans addr . Le paramĂštre length indique la longueur de la projection (qui doit ĂȘtre supĂ©rieure Ă  0 ).

Si addr est NULL, le noyau choisit l’adresse (alignĂ©e sur une page) Ă  laquelle dĂ©marrer la projection ; c’est la mĂ©thode la plus portable pour crĂ©er une nouvelle projection. Si addr n’est pas NULL, le noyau le considĂšre comme une indication sur l’endroit oĂč placer la projection ; sous Linux, elle sera placĂ©e Ă  une frontiĂšre de page proche (mais toujours supĂ©rieure ou Ă©gale Ă  la valeur indiquĂ©e par /proc/sys/vm/mmap_min_addr ) et tente d’y crĂ©er la projection. Si une projection y existe dĂ©jĂ , le noyau prend une nouvelle adresse qui peut ou pas dĂ©pendre de l’indication. L’adresse de la nouvelle projection est renvoyĂ©e comme rĂ©sultat de l’appel.

Le contenu d’une projection de fichier (par opposition Ă  une projection anonyme ; voir ci-dessous MAP_ANONYMOUS ) est initialisĂ© avec length octets Ă  partir de la position offset dans le fichier (ou autre objet) correspondant au descripteur de fichier fd . offset doit ĂȘtre un multiple de la taille de la page renvoyĂ©e par sysconf(_SC_PAGE_SIZE) .

AprĂšs le retour de l’appel mmap (), le descripteur de fichier fd peut ĂȘtre fermĂ© immĂ©diatement sans invalider la projection.

L’argument prot indique la protection que l’on dĂ©sire pour cette zone de mĂ©moire et ne doit pas entrer en conflit avec le mode d’ouverture du fichier. Il s’agit soit de PROT_NONE (le contenu de la mĂ©moire est inaccessible) soit d’un OU binaire entre les constantes suivantes :

PROT_EXEC

Il est possible d’exĂ©cuter les pages.

PROT_READ

Il est possible de lire les pages.

PROT_WRITE

Il est possible d’écrire les pages.

PROT_NONE

Il n’est pas possible d’accĂ©der aux pages.

Le paramĂštre des attributs

Le paramĂštre flags dĂ©termine si les modifications de la projection sont visibles depuis les autres processus projetant la mĂȘme rĂ©gion et si les modifications sont appliquĂ©es au fichier sous-jacent. Ce comportement est dĂ©terminĂ© en incluant exactement une des valeurs suivantes dans flags :
MAP_SHARED

Partager la projection. Les modifications de la projection sont visibles dans les autres processus qui projettent la mĂȘme rĂ©gion et (en cas de projection file-backed) elles sont appliquĂ©es au fichier sous-jacent (pour contrĂŽler prĂ©cisĂ©ment le moment des mises Ă  jour du fichier sous-jacent, il faut utiliser msync (2)).

MAP_SHARED_VALIDATE (depuis Linux 4.15)

Cet attribut apporte le mĂȘme comportement que MAP_SHARED sauf que les projections MAP_SHARED ignorent les attributs inconnus dans flags . Au contraire, lors de la crĂ©ation d’une projection en utilisant MAP_SHARED_VALIDATE , le noyau vĂ©rifie que tous les attributs passĂ©s sont connus et il fait Ă©chouer la projection avec l’erreur EOPNOTSUPP pour les attributs inconnus. Ce type de projection est aussi nĂ©cessaire pour pouvoir utiliser certains attributs de projection (comme MAP_SYNC ).

MAP_PRIVATE

CrĂ©er une projection privĂ©e, utilisant la mĂ©thode de copie Ă  l’écriture. Les modifications de la projection ne sont pas visibles depuis les autres processus projetant le mĂȘme fichier, et ne modifient pas le fichier lui-mĂȘme. Il n’est pas prĂ©cisĂ© si les changements effectuĂ©s dans le fichier aprĂšs l’appel mmap () seront visibles dans la rĂ©gion projetĂ©e.

MAP_SHARED et MAP_PRIVATE sont décrits dans POSIX.1-2001 et POSIX.1-2008. MAP_SHARED_VALIDATE est une extension Linux.

De plus, zĂ©ro ou plus des valeurs suivantes peuvent ĂȘtre incluses dans flags (avec un OU binaire) :
MAP_32BIT
(depuis Linux 2.4.20, 2.6)

Placer la projection dans les deux premiers gigaoctets de l’espace d’adressage du processus. Cet attribut n’est pris en charge que sous x86-64, pour les programmes 64 bits. Il a Ă©tĂ© ajoutĂ© pour permettre Ă  la pile d’un fil d’exĂ©cution d’ĂȘtre allouĂ©e dans les deux premiers gigaoctets de mĂ©moire, afin d’amĂ©liorer les performances des changements de contexte sur les premiers processeurs 64 bits. Les processeurs x86-64 modernes n’ont plus ces problĂšmes de performance, donc l’utilisation de cet attribut n’est pas nĂ©cessaire sur ces systĂšmes. L’attribut MAP_32BIT est ignorĂ© quand MAP_FIXED est positionnĂ©.

MAP_ANON

Synonyme de MAP_ANONYMOUS ; fourni pour une compatibilitĂ© avec d’autres implĂ©mentations.

MAP_ANONYMOUS

La projection n’est prise en charge par aucun fichier ; son contenu est initialisĂ© Ă  0 . L’argument fd est ignoré ; cependant, certaines implĂ©mentations demandent que fd soit -1 si MAP_ANONYMOUS (ou MAP_ANON ) est utilisĂ©, et les applications portables doivent donc s’en assurer. L’argument offset devrait ĂȘtre 0 . La prise en charge de MAP_ANONYMOUS avec MAP_SHARED a Ă©tĂ© ajoutĂ©e dans Linux 2.4.

MAP_DENYWRITE

Cet attribut est ignorĂ© (autrefois — Linux 2.0 et antĂ©rieur — il signalait une tentative d’écriture dans le fichier sous-jacent et qui Ă©chouait avec l’erreur ETXTBUSY . Mais cela permettait des attaques par dĂ©ni de service).

MAP_EXECUTABLE

Cet attribut est ignoré.

MAP_FILE

Attribut pour compatibilité. Ignoré.

MAP_FIXED

Ne pas considĂ©rer addr comme une indication : n’utiliser que l’adresse indiquĂ©e. addr doit ĂȘtre correctement alignĂ©e : pour la plupart des architectures, un multiple de la taille de page suffit, toutefois certaines architectures imposent des limitations supplĂ©mentaires. Si la zone mĂ©moire indiquĂ©e par addr et length recouvre des pages d’une projection existante, la partie recouverte de la projection existante sera ignorĂ©e. Si l’adresse indiquĂ©e ne peut ĂȘtre utilisĂ©e, mmap () Ă©chouera.

Les logiciels qui aspirent Ă  la portabilitĂ© devraient utiliser l’attribut MAP_FIXED prudemment, en gardant Ă  l’esprit que l’aspect exact des projections de mĂ©moire du processus est autorisĂ© Ă  changer significativement entre les versions de Linux, de la glibc et du systĂšme d’exploitation. Lisez attentivement le point sur cet attribut dans les NOTES !

MAP_FIXED_NOREPLACE (depuis Linux 4.17)

Cet attribut offre un comportement identique Ă  MAP_FIXED par rapport Ă  l’application de addr , mais il s’en distingue en ce que MAP_FIXED_NOREPLACE n’écrase jamais une plage projetĂ©e existante. Si la plage demandĂ©e entre en conflit avec une projection existante, cet appel Ă©choue avec l’erreur EEXIST. Cet attribut peut donc ĂȘtre utilisĂ© comme une façon d’essayer de projeter une plage d’adresses de maniĂšre atomique (vis-Ă -vis d’autres fils d’exĂ©cutions) : un thread rĂ©ussira, tous les autres signaleront un Ă©chec.

Remarquez que les anciens noyaux qui ne reconnaissent pas l’attribut MAP_FIXED_NOREPLACE se rabattront gĂ©nĂ©ralement (en dĂ©tectant une collision avec une projection existante) sur un type de comportement « sans MAP_FIXED » : ils renverront une adresse diffĂ©rente de celle demandĂ©e. Les logiciels rĂ©tro-compatibles devront donc vĂ©rifier l’adresse renvoyĂ©e vis-Ă -vis de l’adresse demandĂ©e.

MAP_GROWSDOWN

Cet attribut est utilisĂ© pour les piles. Il indique au noyau le systĂšme de mĂ©moire virtuelle vers lequel la projection devrait descendre dans la mĂ©moire. L’adresse renvoyĂ©e est une page infĂ©rieure Ă  la zone de mĂ©moire créée dans l’espace d’adressage virtuel du processus. La modification d’une adresse dans la page de « garde » sous la projection fera agrandir la projection d’une page. Cette croissance peut se rĂ©pĂ©ter jusqu’à ce que la taille de la projection dans la page atteigne l’extrĂ©mitĂ© haute de la projection plus basse suivante, point oĂč la modification de la page de « garde » donnera un signal SIGSEGV .

MAP_HUGETLB (depuis Linux 2.6.32)

Allouer la projection Ă  l’aide de « pages immenses ». Consultez le fichier Documentation/vm/hugetlbpage.txt des sources du noyau Linux pour plus d’informations ainsi que les NOTES ci-dessous.

MAP_HUGE_2MB
MAP_HUGE_1GB
(depuis Linux 3.8)

UtilisĂ© avec MAP_HUGETLB pour sĂ©lectionner d’autres tailles de pages immenses (hugetlb) (respectivement 2 Mo et 1 Go) sur les systĂšmes qui gĂšrent plusieurs tailles de page hugetlb.

Plus gĂ©nĂ©ralement, la taille de la page immense souhaitĂ©e peut ĂȘtre configurĂ©e en encodant le logarithme de base 2 de la taille de la page dĂ©sirĂ©e dans les six bits situĂ©s sur MAP_HUGE_SHIFT (une valeur de zĂ©ro dans ce champ de bit fournit la taille de page immense par dĂ©faut ; vous pouvez connaĂźtre celle-ci Ă  l’aide du champ Hugepagesize qui apparaĂźt dans /proc/meminfo ). Ainsi, les deux constantes ci-dessus sont dĂ©finies comme suit :

#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)

Vous pouvez connaĂźtre l’intervalle de tailles des pages immenses gĂ©rĂ©es par le systĂšme en listant les sous-rĂ©pertoires de /sys/kernel/mm/hugepages .

MAP_LOCKED (depuis Linux 2.5.37)

Marquer la rĂ©gion projetĂ©e pour qu’elle soit verrouillĂ©e de la mĂȘme maniĂšre que mlock (2). Cette implĂ©mentation essaiera de remplir (prefault) toute la plage mais l’appel mmap () n’échouera pas avec ENOMEM si cela Ă©choue. Des erreurs Ă©normes pourraient donc se produire ultĂ©rieurement. La sĂ©mantique n’est donc pas aussi robuste que mlock (2). Vous devriez utiliser mmap () et mlock (2) si d’énormes erreurs ne sont pas acceptables aprĂšs l’initialisation de la projection. L’attribut MAP_LOCKED est ignorĂ© sur les anciens noyaux.

MAP_NONBLOCK (depuis Linux 2.5.46)

Cet attribut n’a de sens qu’en conjonction avec MAP_POPULATE . Ne pas effectuer de lecture anticipĂ©e : crĂ©er seulement les entrĂ©es de tables de page pour les pages dĂ©jĂ  prĂ©sentes en RAM. Depuis Linux 2.6.23, cet attribut fait que MAP_POPULATE n’a aucun effet. Un jour la combinaison de MAP_POPULATE et MAP_NONBLOCK pourra ĂȘtre implĂ©mentĂ©e de nouveau.

MAP_NORESERVE

Ne pas rĂ©server d’espace de swap pour les pages de cette projection. Une telle rĂ©servation garantit que l’on puisse modifier les zones soumises Ă  une copie-en-Ă©criture. Sans rĂ©servation, on peut recevoir un signal SIGSEGV durant une Ă©criture, s’il n’y a plus de place disponible. Consultez Ă©galement la description du fichier /proc/sys/vm/overcommit_memory dans la page proc (5). Avant Linux 2.6, cet attribut n’avait d’effet que pour les projections privĂ©es modifiables.

MAP_POPULATE (depuis Linux 2.5.46)

Remplir (prefault) les tables de pages pour une projection. Pour une projection de fichier, cela provoque une lecture anticipĂ©e du fichier. Les accĂšs ultĂ©rieurs Ă  la projection ne seront pas bloquĂ©s par des erreurs de pages. L’appel mmap n’échoue pas si la projection ne peut pas ĂȘtre remplie (par exemple Ă  cause de limitation sur le nombre de pages immenses mappĂ©es lors de l’utilisation de MAP_HUGETLB ). La prise en charge de MAP_POPULATE avec les projections privĂ©es a Ă©tĂ© ajoutĂ©e dans Linux 2.6.23.

MAP_STACK (depuis Linux 2.6.27)

Allouer la projection à une adresse qui convient à la pile d’un processus ou d’un thread.

Cet attribut n’est pas opĂ©rationnel pour l’instant sur Linux. Mais son utilisation permet aux applications de s’assurer qu’elles le gĂšreront de maniĂšre transparente s’il est implĂ©mentĂ© dans le futur. Ainsi, il est utilisĂ© dans l’implĂ©mentation de threading de la glibc pour accepter le fait que certaines architectures pourront (plus tard) nĂ©cessiter un traitement spĂ©cial pour allouer des piles. Une autre raison d’utiliser cet attribut est la portabilité : MAP_STACK existe et a un effet sur d’autres systĂšmes (comme certains BSD).

MAP_SYNC (depuis Linux 4.15)

Cet attribut n’est possible qu’avec le type de projection MAP_SHARED_VALIDATE ; les projections de type MAP_SHARED ignoreront silencieusement cet attribut. Il n’est pris en charge que pour des fichiers gĂ©rant le DAX (projection directe de mĂ©moire persistante). Pour les autres fichiers, crĂ©er une projection avec cet attribut provoquera une erreur EOPNOTSUPP .

Les projections de fichier partagĂ© ayant cet attribut fournissent une garantie que tant que la mĂ©moire est projetĂ©e avec accĂšs en Ă©criture dans l’espace d’adressage du processus, elle sera visible dans le mĂȘme fichier et au mĂȘme endroit mĂȘme aprĂšs un plantage ou un redĂ©marrage du systĂšme. CouplĂ© Ă  l’utilisation des instructions adĂ©quates du processeur, cela offre aux utilisateurs de telles projections une maniĂšre plus efficace de rendre des modifications de donnĂ©es persistantes.

MAP_UNINITIALIZED (depuis Linux 2.6.33)

Ne pas effacer pas les pages anonymes. Cet attribut n’a pour l’instant un effet que si le noyau a Ă©tĂ© configurĂ© avec l’option CONFIG_MMAP_ALLOW_UNINITIALIZED . À cause des implications sur la sĂ©curitĂ©, cette option n’est normalement active que sur des pĂ©riphĂ©riques embarquĂ©s (c’est-Ă -dire avec des pĂ©riphĂ©riques avec lesquels il est possible d’avoir un contrĂŽle total de la mĂ©moire utilisateur).

Parmi les attributs ci-dessus, seul MAP_FIXED est spécifié dans POSIX.1-2001 et POSIX.1-2008. Cependant, la plupart des systÚmes gÚrent aussi MAP_ANONYMOUS (ou son synonyme MAP_ANON ).

munmap()

L’appel systĂšme munmap () dĂ©truit la projection dans la zone de mĂ©moire spĂ©cifiĂ©e et s’arrange pour que toute rĂ©fĂ©rence ultĂ©rieure Ă  cette zone mĂ©moire dĂ©clenche une erreur d’adressage. La projection est aussi automatiquement dĂ©truite lorsque le processus se termine. À l’inverse, la fermeture du descripteur de fichier ne supprime pas la projection.

L’adresse addr doit ĂȘtre un multiple de la taille de la page (mais ce n’est pas obligatoire pour length ). Toutes les pages contenant une partie de l’intervalle indiquĂ© sont libĂ©rĂ©es, et tout accĂšs ultĂ©rieur dĂ©clenchera SIGSEGV . Aucune erreur n’est dĂ©tectĂ©e si l’intervalle indiquĂ© ne contient pas de page projetĂ©e.

VALEUR RENVOYÉE

En cas de succĂšs, mmap () renvoie un pointeur sur la zone projetĂ©e. 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.

S’il rĂ©ussit, munmap () renvoie 0 . En cas d’échec, -1 est renvoyĂ© et errno est dĂ©fini pour indiquer l’erreur (probablement EINVAL ).

ERREURS

EACCES

Le descripteur ne correspond pas Ă  un fichier normal ou une demande de projection de fichier a Ă©tĂ© demandĂ©e mais fd n’est pas ouvert en lecture, ou une demande de projection partagĂ©e MAP_SHARED avec protection PROT_WRITE a Ă©tĂ© demandĂ©e mais fd n’est pas ouvert en lecture et Ă©criture ( O_RDWR ), ou encore PROT_WRITE est demandĂ© mais le fichier est ouvert en ajout seulement.

EAGAIN

Le fichier est verrouillé ou trop de pages ont été verrouillées en mémoire (consultez setrlimit (2)).

EBADF

fd n’est pas un descripteur de fichier valable (et MAP_ANONYMOUS n’était pas prĂ©cisĂ©).

EEXIST

MAP_FIXED_NOREPLACE était indiqué dans flags et la plage couverte par addr et length est en conflit avec une projection existante.

EINVAL

addr ou length ou offset sont non valables (par exemple : zone trop grande, ou non alignée sur une frontiÚre de page).

EINVAL

(depuis Linux 2.6.12) length est nul.

EINVAL

flags ne contenait ni MAP_PRIVATE , ni MAP_SHARED , ni MAP_SHARED_VALIDATE .

ENFILE

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

ENODEV

Le systÚme de fichiers sous-jacent ne gÚre pas la projection en mémoire.

ENOMEM

Aucune mémoire disponible.

ENOMEM

Le nombre maximal de projections du processus serait dĂ©passĂ©. Cette erreur peut aussi se produire pour munmap () lors de la suppression d’une projection d’une rĂ©gion au milieu d’une projection existante, puisque cela provoque deux rĂ©gions plus petites de chaque cĂŽtĂ© de la rĂ©gion Ă  supprimer.

ENOMEM

(Depuis Linux 4.7) La limite RLIMIT_DATA du processus, décrite dans getrlimit (2), serait dépassée.

ENOMEM

addr n’est pas apprĂ©ciĂ© parce qu’il dĂ©passe l’espace d’adressage virtuel du processeur

EOVERFLOW

Sur architecture 32 bits avec l’extension de fichiers trĂšs grands (c’est-Ă -dire utilisant un off_t sur 64 bits) : le nombre de pages utilisĂ©es pour length plus le nombre de pages utilisĂ©es pour offset dĂ©passerait unsigned long (32 bits).

EPERM

L’argument prot a demandĂ© PROT_EXEC mais la zone appartient Ă  un fichier sur un systĂšme de fichiers montĂ© sans permission d’exĂ©cution.

EPERM

La lecture a été interrompue par un signal ; consultez fnctl (2).

EPERM

L’attribut MAP_HUGETLB Ă©tait indiquĂ©, mais l’appelant n’était pas priviliĂ©giĂ© (il n’avait pas la capacitĂ© CAP_IPC_LOCK ) et n’est pas membre du groupe sysctl_hugetlb_shm_group ; voir la desription de /proc/sys/vm/sysctl_hugetlb_shm_group dans proc_sys (5).

ETXTBSY

MAP_DENYWRITE a été réclamé mais fd est ouvert en écriture.

L’accĂšs Ă  une zone de projection peut dĂ©clencher les signaux suivants :
SIGSEGV

Tentative d’écriture dans une zone en lecture seule.

SIGBUS

Tentative d’accĂšs Ă  une page du tampon au-delĂ  de la fin du fichier projetĂ©. Pour une explication du traitement des octets dans la page correspondant Ă  la fin du fichier projetĂ© n’étant pas un multiple de la taille de la page, voir les NOTES.

ATTRIBUTS

Pour une explication des termes utilisés dans cette section, consulter attributes (7).

Image grohtml-3855070-1.png

VERSIONS

Sur certaines architectures matĂ©rielles (par exemple, i386), PROT_WRITE implique PROT_READ . Cela dĂ©pend de l’architecture si PROT_READ implique PROT_EXEC ou non. Les programmes portables doivent toujours indiquer PROT_EXEC s’ils veulent exĂ©cuter du code dans la projection.

La maniĂšre portable de crĂ©er une projection est de spĂ©cifier addr Ă  0 (NULL), et d’omettre MAP_FIXED dans flags . Dans ce cas, le systĂšme choisit l’adresse de la projection ; l’adresse est choisie de maniĂšre Ă  ne pas entrer en conflit avec une projection existante et de ne pas ĂȘtre nulle. Si l’attribut MAP_FIXED est indiquĂ© et si addr vaut 0 (NULL), l’adresse projetĂ©e sera zĂ©ro (NULL).

Certaines constantes de flags sont définies seulement si des macros de test de fonctionnalités adaptées sont définies (potentiellement par défaut) : _DEFAULT_SOURCE avec la glibc 2.19 ou supérieure, ou bien _BSD_SOURCE ou _SVID_SOURCE dans la glibc 2.19 et antérieure (la définition de _GNU_SOURCE suffit également, et son usage aurait été plus logique, puisque ces attributs sont tous spécifiques à Linux). Les attributs adéquats sont : MAP_32BIT , MAP_ANONYMOUS (et son synonyme MAP_ANON ), MAP_DENYWRITE , MAP_EXECUTABLE , MAP_FILE , MAP_GROWSDOWN , MAP_HUGETLB , MAP_LOCKED , MAP_NONBLOCK , MAP_NORESERVE , MAP_POPULATE , et MAP_STACK .

Différences entre bibliothÚque C et noyau

Cette page dĂ©crit l’interface fournie par la fonction mmap () de la glibc. Initialement, cette fonction appelait un appel systĂšme du mĂȘme nom. Depuis Linux 2.4, cet appel systĂšme a Ă©tĂ© remplacĂ© par mmap2 (2). De nos jours, la fonction mmap () de la glibc appelle mmap2 (2) avec la bonne valeur pour offset .

STANDARDS

POSIX.1-2008.

HISTORIQUE

POSIX.1-2001, SVr4, 4.4BSD.

Sur les systÚmes POSIX sur lesquels mmap (), msync (2) et munmap () sont disponibles, _POSIX_MAPPED_FILES est définie dans <unistd.h> comme étant une valeur supérieure à 0 (consultez aussi sysconf (3)).

NOTES

La mĂ©moire obtenue par mmap est prĂ©servĂ©e au travers d’un fork (2), avec les mĂȘmes attributs.

Un fichier est projetĂ© en multiples de de la taille de la page. Pour un fichier dont la longueur n’est pas un multiple de la taille de page, la mĂ©moire restante est remplie de zĂ©ros lors de la projection, et les Ă©critures dans cette zone n’affectent pas le fichier. Les effets de la modification de la taille du fichier sous-jacent sur les pages correspondant aux zones ajoutĂ©es ou supprimĂ©es ne sont pas prĂ©cisĂ©s.

Une application peut dĂ©terminer les pages d’une projection se trouvant dans le tampon/le cache de page en utilisant mincore (2).

Utilisation sûre de MAP_FIXED

La seule utilisation sĂ»re de MAP_FIXED est quand la plage d’adresses indiquĂ©e par addr et length a Ă©tĂ© prĂ©alablement rĂ©servĂ©e en utilisant une autre projection ; sans quoi l’utilisation de MAP_FIXED est hasardeuse car elle supprime brutalement des projections prĂ©existantes, ce qui facilite la corruption par un processus multithread de son propre espace d’adressage.

Par exemple, supposons qu’un thread A cherche dans /proc/ pid /maps une plage d’adresses inutilisĂ©e oĂč il peut se projeter en utilisant MAP_FIXED , tandis qu’un thread B acquiert en mĂȘme temps tout ou partie de cette mĂȘme plage d’adresses. Quand le thread A utilisera ensuite mmap(MAP_FIXED) , il va de fait Ă©craser la projection créée par le thread B. Dans ce scĂ©nario, le thread B ne doit pas crĂ©er de projection directement ; un appel de bibliothĂšque qui, en interne, utilise dlopen (3) pour charger d’autres bibliothĂšques partagĂ©es, est suffisant. L’appel dlopen (3) projettera la bibliothĂšque dans l’espace d’adressage du processus. De plus, presque tous les appels de bibliothĂšques peuvent ĂȘtre implĂ©mentĂ©s d’une maniĂšre qui ajoute des projections de mĂ©moire aux espaces d’adressage, Ă  l’aide de cette technique ou en allouant simplement de la mĂ©moire. Parmi les exemples, figurent brk (2), malloc (3), pthread_create (3) et les bibliothĂšques PAM http://www.linux-pam.org .

Depuis Linux 4.17, un programme multithreadĂ© peut utiliser l’attribut MAP_FIXED_NOREPLACE pour Ă©viter le risque dĂ©crit ci-dessus quand on essaie de crĂ©er une projection Ă  une adresse fixe non rĂ©servĂ©e par une projection prĂ©existante.

Modifications d’horodatage pour les projections prises en charge par unfichier

Pour les projections prises en charge par un fichier, le champ st_atime du fichier peut ĂȘtre mis Ă  jour Ă  tout moment entre l’appel mmap () et le munmap () correspondant. Le premier accĂšs dans la page projetĂ©e mettra le champ Ă  jour si cela n’a pas Ă©tĂ© dĂ©jĂ  fait.

Les champs st_ctime et st_mtime pour un fichier projetĂ© avec PROT_WRITE et MAP_SHARED seront mis Ă  jour aprĂšs une Ă©criture dans la rĂ©gion projetĂ©e, et avant l’éventuel msync (2) suivant avec l’attribut MS_SYNC ou MS_ASYNC .

Projections de pages immenses (Huge TLB)

Pour les projections qui utilisent des pages immenses, les exigences des attributs de mmap () et de munmap () diffĂšrent quelque peu de celles pour des projections qui utilisent la taille native des pages du systĂšme.

Pour mmap (), offset doit ĂȘtre un multiple de la taille de la page immense sous-jacente. Le systĂšme aligne automatiquement length pour qu’il soit un multiple de la taille de la page immense sous-jacente.

Pour munmap (), addr et length doivent ĂȘtre tous deux un multiple de la taille de la page immense sous-jacente.

BOGUES

Sous Linux, il n’y a aucune garantie comme celles indiquĂ©es plus haut Ă  propos de MAP_NORESERVE . Par dĂ©faut, n’importe quel processus peut ĂȘtre tuĂ© Ă  tout moment lorsque le systĂšme n’a plus de mĂ©moire.

Avant Linux 2.6.7, l’attribut MAP_POPULATE n’avait d’effet que si prot Ă©tait PROT_NONE .

SUSv3 indique que mmap () devrait Ă©chouer si length est 0. Cependant, avant Linux 2.6.12, mmap () rĂ©ussissait dans ce cas : aucune projection n’était créée, et l’appel renvoyait addr . Depuis Linux 2.6.12, mmap () Ă©choue avec le code d’erreur EINVAL si length est nul.

POSIX spĂ©cifie que le systĂšme devrait toujours remplir de zĂ©ros toutes les pages incomplĂštes Ă  la fin de l’objet et que le systĂšme n’écrira jamais de modification de l’objet au-delĂ  de sa fin. Sous Linux, lors de l’écriture de donnĂ©es vers ce genre de pages incomplĂštes aprĂšs la fin de l’objet, les donnĂ©es restent dans le cache de page mĂȘme aprĂšs que le fichier soit fermĂ© et dĂ©projetĂ©, et mĂȘme si les donnĂ©es ne sont jamais Ă©crites vers le fichier lui-mĂȘme, les projections suivantes pourraient voir le contenu modifiĂ©. Dans certains cas, cela pourrait ĂȘtre corrigĂ© en appelant msync (2) avant la dĂ©projection. Cependant, cela ne fonctionne pas sur tmpfs (5) (par exemple en utilisant l’interface de mĂ©moire partagĂ©e POSIX documentĂ©e dans shm_overview (7)).

EXEMPLES

Le programme suivant affiche la partie du fichier, prĂ©cisĂ© par le premier argument de la ligne de commande, sur la sortie standard. Les octets qui seront affichĂ©s sont prĂ©cisĂ©s Ă  partir d’un offset (dĂ©placement) et d’une longueur en deuxiĂšme et troisiĂšme paramĂštre. Le code fait une projection mĂ©moire des pages nĂ©cessaires du fichier puis utilise write (2) pour afficher les octets voulus.

Source du programme

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(int argc, char *argv[])
{
int fd;
char *addr;
off_t offset, pa_offset;
size_t length;
ssize_t s;
struct stat sb;
if (argc < 3 || argc > 4) {
fprintf(stderr, "%s position du fichier [longueur]\n", argv[0]);
exit(EXIT_FAILURE);
}
fd = open(argv[1], O_RDONLY);
if (fd == -1)
handle_error("open");
if (fstat(fd, &sb) == -1) /* To obtain file size */
handle_error("fstat");
offset = atoi(argv[2]);
pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
/* la position de mmap() doit ĂȘtre alignĂ©e sur la page */
if (offset >= sb.st_size) {
fprintf(stderr, "la position est au-delĂ  de la fin du fichier\n");
exit(EXIT_FAILURE);
}
if (argc == 4) {
length = atoi(argv[3]);
if (offset + length > sb.st_size)
length = sb.st_size - offset;
/* Ne peut pas afficher d’octets situĂ©s aprĂšs la fin du fichier */
} else { /* Pas d’affichage de longueur arg ==> à la fin du fichier */
length = sb.st_size - offset;
}
addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
MAP_PRIVATE, fd, pa_offset);
if (addr == MAP_FAILED)
handle_error("mmap");
s = write(STDOUT_FILENO, addr + offset - pa_offset, length);
if (s != length) {
if (s == -1)
handle_error("write");
fprintf(stderr, "écriture partielle");
exit(EXIT_FAILURE);
}
munmap(addr, length + offset - pa_offset);
close(fd);
exit(EXIT_SUCCESS);
}

VOIR AUSSI

ftruncate (2), getpagesize (2), memfd_create (2), mincore (2), mlock (2), mmap2 (2), mprotect (2), mremap (2), msync (2), remap_file_pages (2), setrlimit (2), shmat (2), userfaultfd (2), shm_open (3), shm_overview (7)

Dans proc (5), les descriptions des fichiers : /proc/ pid /maps , /proc/ pid /map_files et /proc/ pid /smaps .

B.O. Gallmeister, POSIX.4, O’Reilly, p. 128–129 et 389–391.

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 .