MLOCK(2)

NOM
mlock, munlock, mlockall, munlockall - Verrouiller et déverrouiller la mémoire

SYNOPSIS
#include <sys/mman.h>

int mlock(const void *addr, size_t len);

int munlock(const void *addr, size_t len);

int mlockall(int flags);

int munlockall(void);

DESCRIPTION
mlock() et mlockall() verrouillent respectivement une partie et l'ensemble de l'espace mémoire virtuelle du processus appelant dans la mémoire physique (RAM), évitant que cette mémoire ne soit paginée dans l'espace d'échange (swap). munlock() et munlockall() effectuent l'opération inverse, déverrouillant respectivement une partie ou l'ensemble de l'espace mémoire virtuelle du processus appelant. Ainsi, les pages se trouvant dans l'espace mémoire virtuelle spécifié pourront être swappées si le gestionnaire de mémoire du noyau le juge nécessaire. Le verrouillage et le déverrouillage se font par multiples d'une page.

  mlock() et munlock()
mlock() verrouille les pages sur len octets à partir de l'adresse addr. Toutes les pages qui contiennent une partie de la zone mémoire indiquée sont résidentes en RAM lorsque l'appel s'achève avec succès. Il est garanti que ces pages restent en RAM jusqu'à leur déverrouillage. munlock() déverrouille la mémoire sur len octets à partir de l'adresse addr. Après cet appel, toutes les pages contenant une partie de la zone mémoire indiquée peuvent à nouveau être déplacées vers l'espace d'échange par le noyau.

  mlockall() et munlockall()
mlockall() verrouille toutes les pages situées dans l'espace d'adresse du processus appelant. Cela inclut les pages de code et de données, le segment de pile, les bibliothèques partagées, les données noyau de l'espace utilisateur, la mémoire partagée et les fichiers projetés en mémoire. Toutes les pages projetées sont résidentes en RAM lorsque l'appel s'achève avec succès. Il est garanti que ces pages restent en RAM jusqu'à leur déverrouillage. L'argument flags est contruit par un OU bit à bit de l'une ou plusieurs des constantes suivantes :

MCL_CURRENT
    Verrouiller toutes les pages actuellement projetées dans l'espace d'adresse du processus.

MCL_FUTURE
    Verrouiller toutes les pages qui seront projetées plus tard dans l'espace d'adresse du processus. Cela peut être, par exemple, de nouvelles pages rendues nécessaires par l'accroissement du tas et de la pile aussi bien que pour des fichiers projetés en mémoire ou des régions de mémoire partagée.

Si MCL_FUTURE a été spécifiée, un appel système ultérieur (par exemple : mmap(2), sbrk(2), malloc(3)), peut échouer s'il fait que le nombre d'octets verrouillés excède le maximum autorisé (voir plus loin). Dans les mêmes circonstances, un accroissement de la pile peut échouer de la même manière : le noyau refusera l'extension de la pile et délivrera un signal SIGSEGV au processus. munlockall() déverrouille toutes les pages projetées dans l'espace d'adresse du processus appelant.

VALEUR RENVOYÉE
S'ils réussissent, ces appels système renvoient 0 ; s'ils échouent, ils renvoient -1, errno est renseignée en conséquence, et les verrouillages de mémoire du processus ne sont pas modifiés.

ERREURS

ENOMEM
    (Linux 2.6.9 et suivants) L'appelant avait une limite de ressources souple RLIMIT_MEMLOCK non nulle mais a essayé de verrouiller plus de mémoire que la limite ne lui permettait. Cette limite ne s'applique pas si le processus est privilégié (CAP_IPC_LOCK).

ENOMEM
    (Linux 2.4 et antérieurs) Le processus appelant a essayé de verouiller plus de la moitié de la RAM.

EPERM
    (Linux 2.6.9 et suivants) Le processus appelant n'est pas privilégié (CAP_IPC_LOCK) et sa limite des ressources souple RLIMIT_MEMLOCK est nulle.

EPERM
    (Linux 2.6.8 et antérieurs) Le processus appelant n'a pas les privilèges suffisants pour appeler munlockall(). Sous Linux, la capacité CAP_IPC_LOCK est nécessaire.

Pour mlock() et munlock() :

EINVAL
    len est négatif.

EINVAL
    (Pas sous Linux) addr n'est pas un multiple de la taille de page.

ENOMEM
    Une partie des adresses incluses dans la zone désirée ne correspond pas à une page de l'espace d'adressage accessible du processus.

Pour mlockall() :

EINVAL
    Les flags spécifiés sont inconnus.

Pour munlockall() :

EPERM
    (Linux 2.6.8 et antérieurs) L'appelant n'est pas privilégié (CAP_IPC_LOCK).

CONFORMITÉ
POSIX.1-2001, SVr4.

DISPONIBILITÉ
Sur les systèmes POSIX sur lesquels mlock() et munlock() sont disponibles, la constante symbolique _POSIX_MEMLOCK_RANGE est définie dans <unistd.h> et le nombre d'octets par page peut être déterminé grâce à la constante PAGESIZE (si elle est définie) de <limits.h> ou par un appel à sysconf(_SC_PAGESIZE). Sur les systèmes POSIX sur lesquels mlockall() et munlockall() sont disponibles, la constante symbolique _POSIX_MEMLOCK est définie dans <unistd.h> comme étant une valeur supérieure à 0. (Voir aussi sysconf(3).)

NOTES
Il y a deux domaines principaux d'applications au verrouillage de pages : les algorithmes en temps réel, et le traitement de données confidentielles. Les applications temps réel réclament un comportement temporel déterministe, et la pagination est, avec l'ordonnancement, une cause majeure de délais imprévus. Ces algorithmes basculent habituellement sur un ordonnancement temps réel avec sched_setscheduler(2). Les logiciels de cryptographie manipulent souvent quelques octets hautement confidentiels, comme des mots de passe ou des clés privées. À cause de la pagination, ces données secrètes risquent d'être transférées sur un support physique où elles pourraient être lues par un ennemi longtemps après que le logiciel se soit terminé. (Soyez toutefois conscient que le mode suspendu sur les portables et certains ordinateurs de bureau sauvegarde une copie de la mémoire sur le disque, quels que soient les verrouillages.) Les processus temps réel qui utilisent mlockall() pour s'affranchir des délais sur les fautes de pages devraient réserver suffisamment de pages de pile avant d'entrer dans la partie critique, ainsi, aucune faute de page ne serait provoquée par ces appels. Cela peut être fait en appelant une fonction qui alloue, de manière automatique, une grande variable de type tableau et qui écrit dans la mémoire occupée par ce tableau afin de toucher (Ndt : to touch) ces pages de pile. De cette manière, il y aura suffisamment de pages projetées pour la pile verrouillée en RAM. Cette écriture apparement inutile, permet de garantir qu'aucune faute de page (même due au mécanisme de copie-à-l'écriture) ne se produira dans la section critique. Les verrouillages de mémoire ne sont pas hérités par un fils créé avec fork(2) et sont automatiquement supprimés (déverrouillage) lors d'un execve(2) ou lorsque le processus se termmine. Le verrouillage de mémoire sur un espace d'adresse est automatiquement retiré si l'espace d'adresse est démappé avec munmap(2). Il n'y a pas d'empilement des verrouillages mémoire, ce qui signifie qu'une page verrouillée plusieurs fois par mlock() ou mlockall() sera libérée en un seul appel à munlock() pour la zone mémoire correspondante ou par un appel à munlockall(). Les pages qui sont verrouillées par plusieurs zones, ou par plusieurs processus restent verrouillées en mémoire vive tant qu'il y a au moins un processus ou une zone qui les verrouille.

  Notes Linux
Sous Linux, mlock() et munlock() arrondissent par défaut automatiquement addr à la frontière de page la plus proche. Toutefois, POSIX.1-2001 permet à l'implémentation d'imposer que addr soit alignée sur une frontière de page. Les programmes portables en prendront soin.

  Limites et permissions
Sous Linux 2.6.8 et antérieurs, un processus devait être privilégié (CAP_IPC_LOCK) pour verrouiller de la mémoire et la limite de ressources souple RLIMIT_MEMLOCK définissait une limite sur la taille de la mémoire que le processus pouvait verrouiller. Depuis Linux 2.6.9, aucune limite n'existe sur la quantité de mémoire que le processus privilégié peut verrouiller et la limite de ressources souple RLIMIT_MEMLOCK définit la quantité de mémoire qu'un processus non privilégié peut verrouiller.

BOGUES
Dans les noyaux de la série 2.4 jusqu'au 2.4.17 inclus, un bogue faisait que l'attribut MCL_FUTURE de mlockall() était hérité à travers fork(2). Cela a été corrigé dans le noyau 2.4.18. Depuis le noyau 2.6.9, si un processus privilégié appelle mlockall(MCL_FUTURE) et par la suite se débarrasse de ses privilèges (perd la capacité CAP_IPC_LOCK en configurant, par exemple, son UID effectif à une valeur non nulle), les allocations mémoires suivantes (par exemple, mmap(2), brk(2)) échoueront si la limite RLIMIT_MEMLOCK est atteinte.

VOIR AUSSI
mmap(2), setrlimit(2), shmctl(2), sysconf(3), capabilities(7)

TRADUCTION

Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 11 octobre 1996, mise à jour par Alain Portal <aportal AT univ-monpt2 DOT fr> le 30 mai 2006 et révisée le 17 juillet 2008.

L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 2 mlock ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.