Provided by: manpages-de-dev_4.26.0-1_all 

BEZEICHNUNG
mlock, mlock2, munlock, mlockall, munlockall - Speicher (ent)sperren
BIBLIOTHEK
Standard-C-Bibliothek (libc, -lc)
ÜBERSICHT
#include <sys/mman.h>
int mlock(const void Adresse[.len], size_t Länge);
int mlock2(const void Addresse[.len], size_t Länge, unsigned int Schalter);
int munlock(const void Adresse[.len], size_t Länge);
int mlockall(int Schalter);
int munlockall(void);
BESCHREIBUNG
mlock(), mlock2() und mlockall() sperrt den gesamten oder einen Teil des virtuellen Adressraums des
aufrufenden Prozesses im RAM und verhindern, dass der Speicherinhalt in den Auslagerungsbereich
ausgelagert wird.
munlock() und munlockall() führen die umgekehrte Aktion durch, d.h. entsperren den gesamten oder einen
Teil des virtuellen Adressraums des aufrufenden Prozesses, sodass die Seiten im angegebenen virtuellen
Adressbereich wieder ausgelagert werden können, wenn das von der Kernel-Speicherverwaltung verlangt wird.
(Ent)sperren des Speichers wird für ganze Speicherseiten durchgeführt.
mlock(), mlock2() und munlock()
mlock() sperrt Seiten im Adressbereich, der bei Adresse beginnt und sich über Länge Byte erstreckt. Alle
Seiten, die einen Teil des angegebenen Adressbereichs enthalten, verbleiben nach einem erfolgreichen
Aufruf garantiert im RAM; die Seiten bleiben garantiert im RAM, bis sie wieder entsperrt werden.
mlock2() sperrt auch Seiten im Adressbereich, der bei Adresse beginnt und sich über Länge Byte erstreckt.
Der Status der Seiten, die in dem angegebenen Adressbereichs nach einem erfolgreichen Aufruf enthalten
sind, hängt vom Wert des Schalter-Arguments ab.
Das Argument Schalter kann entweder 0 oder die folgende Konstante sein:
MLOCK_ONFAULT
Sperrt Seiten, die derzeit im Speicher sind, und markiert den gesamten Bereich, so dass die
verbleibenden, nicht im Speicher befindlichen Seiten gesperrt sind, wenn Sie durch eine
Seitenausnahmebehandlung befüllt werden.
Wenn flags 0 ist, verhält sich mlock2() genau so wie mlock().
munlock() entsperrt Seiten im Adressbereich, der mit Adresse beginnt und sich über Länge Byte erstreckt.
Nach diesem Aufruf können alle Seiten, die einen Teil des angegebenen Speicherbereichs umfassen, erneut
vom Kernel in externen Auslagerungsspeicher ausgelagert werden.
mlockall() und munlockall()
mlockall() sperrt alle Seiten, die in den Adressraum des aufrufenden Prozesses gemappt sind. Dieses
bezieht sich auf die Seiten von Code-, Daten- und Stacksegment genauso wie auf dynamische Bibliotheken,
Kernel-Daten im Anwendungsraum, Gemeinsamen Speicher und in den Speicher gemappte Dateien. Es wird
garantiert, dass alle gemappten Speicherseiten im RAM sind, wenn der Aufruf von mlockall() erfolgreich
beendet wird. Es wird darüber hinaus garantiert, dass die Seiten solange im RAM bleiben, bis sie wieder
entsperrt werden.
Das Argument Schalter wird mittels logischem bitweisem ODER aus einer oder mehreren der folgenden
Konstanten konstruiert:
MCL_CURRENT
sperrt alle Seiten, die momentan in den Adressraum des Prozesses gemappt sind.
MCL_FUTURE
sperrt alle Seiten, die in Zukunft in den Adressraum des Prozesses gemappt werden. Das könnten zum
Beispiel neue Adress-Seiten sein, die bei einem sich vergrößernden Heap und Stack benötigt werden,
Dateien, die in den Speicher gemappt werden, oder gemeinsam benutzte Speicherbereiche.
MCL_ONFAULT (seit Linux 4.4)
Wird zusammen mit MCL_CURRENT, MCL_FUTURE oder beiden verwandt. Markiert alle aktuellen (mit
MCL_CURRENT) oder zukünftigen (mit MCL_FUTURE) Mappings, dass sie Seiten sperren, wenn diese durch
Ausnahmebehandlungen hereingekommen sind. Bei der Verwendung mit MCL_CURRENT, werden alle
vorhandenen Seiten gesperrt, aber mlockall() wird keine nicht vorhandenen Seiten durch
Ausnahmebehandlungen hereinbringen. Bei der Verwendung mit MCL_FUTURE werden alle zukünftigen
Mappings markiert, dass sie Seiten sperren, wenn diese durch Ausnahmebehandlungen hereinkommen,
sie werden aber durch die Sperre nicht befüllt, wenn das Mapping erstellt wird. MCL_ONFAULT muss
entweder mit MCL_CURRENT, MCL_FUTURE oder beiden verwandt werden.
Falls MCL_FUTURE angegeben wurde, kann ein späterer Systemaufruf (z. B. mmap(2), sbrk(2), malloc(3))
fehlschlagen, wenn durch ihn die Zahl gesperrter Bytes das zulässige Maximum überschreiten würde (siehe
unten). Unter den gleichen Voraussetzungen kann eine Vergrößerung des Stacks ebenfalls fehlschlagen: der
Kernel wird die Stack-Vergrößerung verweigern und dem Prozess ein SIGSEGV-Signal schicken.
munlockall() entsperrt alle in den Addressraum des aufrufenden Prozesses gemappten Seiten.
RÜCKGABEWERT
Bei Erfolg geben diese Systemaufrufe 0 zurück. Bei einem Fehler wird -1 zurückgegeben, errno gesetzt, um
den Fehler anzuzeigen und keine Änderungen an den Sperren im Adressraum des Prozesses durchgeführt.
FEHLER
EAGAIN (mlock(), mlock2() und munlock()) Ein Teil des angegebenen Adressbereichs oder der gesamte
Adressbereich konnten nicht gesperrt werden.
EINVAL (mlock(), mlock2() und munlock()) Das Ergebnis der Addition Adresse+Länge war kleiner als Adresse
(z. B. kann die Addition einen Überlauf verursacht haben).
EINVAL (mlock2()) Es wurden unbekannte Schalter angegeben.
EINVAL (mlockall()) Es wurden entweder unbekannte Schalter angegeben oder MCL_ONFAULT wurde weder mit
MCL_FUTURE noch mit MCL_CURRENT angegeben.
EINVAL (Nicht unter Linux) Adresse war kein Vielfaches der Seitengröße.
ENOMEM (mlock(), mlock2() und munlock()) Ein Teil des angegebenen Adressbereichs entspricht nicht
Seiten, die in den Adressraum des Prozesses gemappt sind.
ENOMEM (mlock(), mlock2() und munlock()) Sperren oder Entsperren eines Bereiches würde dazu führen, dass
die Gesamtanzahl der Mappings mit eindeutigen Attributen (z.B. gesperrt oder nicht gesperrt) das
erlaubte Maximum überschreiten würde. (Beispielsweise würde das Entsperren eines Bereichs in der
Mitte eines derzeit gesperrten Bereichs zu drei Mappings führen: zwei gesperrte Mappings an jedem
Ende und ein entsperrtes Mapping in der Mitte.)
ENOMEM (Linux 2.6.9 und neuer) Der Aufrufende hatte eine weiche Ressourcenbegrenzung RLIMIT_MEMLOCK
ungleich null, versuchte aber über diese Grenze hinaus Speicher zu sperren. Diese Grenze wird
nicht erzwungen, wenn der Prozess privilegiert ist (CAP_IPC_LOCK).
ENOMEM (Linux 2.4 und älter) Der aufrufende Prozess versuchte, mehr als die Hälfte des RAMs zu sperren.
EPERM Der Aufrufende ist nicht privilegiert, benötigt aber zur Durchführung der angeforderten Aktionen
Privilegien (CAP_IPC_LOCK).
EPERM (munlockall()) (Linux 2.6.8 und älter) Der Aufrufende war nicht privilegiert (CAP_IPC_LOCK).
VERSIONEN
Linux
Unter Linux runden mlock(), mlock2() und munlock() Adresse automatisch zur nächsten Seitengrenze ab. Da
aber die POSIX.1-Spezifikation von mlock() und munlock() Implementierungen gestattet, welche die
Ausrichtung von Adresse an Seitengrenzen fordern, sollten portable Anwendungen die Ausrichtung
sicherstellen.
Das Feld VmLck der Linux-spezifischen Datei /proc/PID/status gibt an, wie viele Kilobyte Speicher der
Prozess mit der Kennung PID mittels mlock(), mlock2(), mlockall() und mmap(2) mit dem Schalter MAP_LOCKED
gesperrt hat.
STANDARDS
mlock()
munlock()
mlockall()
munlockall()
POSIX.1-2008.
mlock2()
Linux.
Auf POSIX-Systemen, auf denen mlock() und munlock() verfügbar sind, ist _POSIX_MEMLOCK_RANGE in
<unistd.h> definiert und die Anzahl der Bytes pro Seite kann der Konstante PAGESIZE (wenn sie definiert
ist) in <limits.h> entnommen werden oder durch einen Aufruf von sysconf(_SC_PAGESIZE) bestimmt werden.
Auf POSIX-Systemen, auf denen mlockall() und munlockall() verfügbar sind, ist _POSIX_MEMLOCK in
<unistd.h> als ein Wert größer als 0 definiert. (Siehe auch sysconf(3).)
GESCHICHTE
mlock()
munlock()
mlockall()
munlockall()
POSIX.1-2001, POSIX.1-2008, SVr4.
mlock2()
Linux 4.4, Glibc 2.27.
ANMERKUNGEN
Das Sperren von Speicher hat zwei Hauptanwendungen: Echtzeitalgorithmen und
Hochsicherheits-Datenverarbeitung. Echtzeitanwendungen erfordern deterministisches Timing, und, wie auch
Scheduling, ist Paging einer der Hauptgründe für unerwartete Verzögerungen in der Programmausführung.
Echtzeitanwendungen werden außerdem für gewöhnlich mit sched_setscheduler(2) auf einen Echtzeit-Scheduler
umschalten. Kryptographische Sicherheitssoftware stellt oft sicherheitskritische Bytes wie Passwörter
oder geheime Schlüssel als Datenstrukturen dar. Durch Paging könnten diese geheimen Daten auf ein
permanentes Auslagerungsspeichermedium übertragen werden, von wo aus sie auch dann noch Dritten
zugänglich sein können, lange nachdem das Programm die geheimen Daten aus dem RAM gelöscht und sich
beendet hat. (Bedenken Sie bitte, dass der Suspend-Modus von Laptops und manchen Desktop-Rechnern,
unabhängig von Speichersperren, eine Kopie des RAMs auf der Platte speichern wird.)
Echtzeitprozesse, die mittels mlockall() Verzögerungen durch Seitenausnahmebehandlungen vermeiden,
sollten ausreichend gesperrte Stackseiten reservieren, bevor sie in die zeitkritische Phase treten,
sodass durch einen Funktionsaufruf keine Seitenausnahmebehandlung entstehen kann. Dies kann durch den
Aufruf einer Funktion erreicht werden, die eine ausreichend große automatische Variable (ein Feld)
erzeugt und in den Speicher schreibt, in dem die Variable liegt, um diese Stackseiten zu belegen. Auf
diesem Wege werden genug Seiten für den Stack gemappt und können im RAM gesperrt werden. Der
Schreibvorgang stellt sicher, dass nicht einmal ein Schreib-Kopier-Seitenausnahmebehandlung in der
kritischen Phase eintreten kann.
Speichersperren werden nicht an mittels fork(2) erzeugte Kindprozesse vererbt und durch einen Aufruf von
execve(2) oder das Ende des Prozesses automatisch entfernt (entsperrt). Die Einstellungen MCL_FUTURE und
MCL_FUTURE | MCL_ONFAULT in mlockall() werden nicht von einem Kindprozess ererbt, der mittels fork(2)
erzeugt wurde und werden während eines execve(2) gelöscht.
Beachten Sie, dass fork(2) den Adressraum für eine Kopieren-beim-Schreiben-Aktion vorbereiten wird. Die
Konsequenz ist, dass nachfolgende Schreibaktionen zu einer Seitenausnahmebehandlung führen werden, die
wiederum hohe Latenzen für Echtzeitprozesse hervorrufen. Daher ist es essenziell, fork(2) nicht nach
einer mlockall()- oder mlock()-Aktion auszuführen - selbst nicht aus einem Thread, der bei niedriger
Priorität innerhalb eines Prozesses läuft, der wiederum einen Thread hat, der mit erhöhter Priorität
läuft.
Die Speichersperrung wird automatisch entfernt, wenn der Adressbereich mittels munmap(2) entmappt wird.
Speichersperren werden nicht hochgezählt (»gestapelt«), das heißt, Seiten die mehrmals durch den Aufruf
von mlockall(), mlock2() oder mlock() gesperrt wurden werden durch einen einzigen Aufruf von munlock()
für den entsprechenden Bereich oder durch munlockall() sofort wieder freigegeben. Seiten, die an
verschiedene Orte oder für verschiedene Prozesse gemappt wurden, bleiben solange im RAM gesperrt, wie sie
mindestens an einem Ort oder durch einen Prozess gesperrt sind.
Wenn einem Aufruf von mlockall(), der den Schalter MCL_FUTURE nutzt, ein weiterer Aufruf folgt, der
diesen Schalter nicht angibt, gehen die durch den Aufruf von MCL_FUTURE erwirkten Änderungen verloren.
Der Schalter MLOCK_ONFAULT von mlock2() und der Schalter MCL_ONFAULT von mlockall() erlaubt effizientes
Speicher-Sperren für Anwendungen, die mit großen Mappings umgehen, bei denen nur ein (kleiner) Anteil von
Seiten im Mapping berührt werden. In diesen Fällen würde das Sperren aller Seiten in dem Mapping eine
erhebliche Einbuße für das Speicher-Sperren verursachen.
Grenzen und Zugriffsrechte
Bis einschließlich Linux 2.6.8 muss ein Prozess privilegiert sein (CAP_IPC_LOCK), um Speicher zu sperren.
Die weiche Systembegrenzung RLIMIT_MEMLOCK bestimmt einen Speicher-Schwellwert, den der Prozess sperren
darf.
Seit Linux 2.6.9 kann ein privilegierter Prozess unbegrenzt Speicher sperren. Die weiche Systembegrenzung
RLIMIT_MEMLOCK legt stattdessen fest, wieviel Speicher ein nicht privilegierter Prozess sperren darf.
FEHLER
In Linux 4.8 und älter bedeutete ein Fehler in der Bilanzierung des Kernels für gesperrten Speicher von
unprivilegierten Prozessen (d.h. solchen ohne CAP_IPC_LOCK), das die gesperrten Bytes, die einer
überlappenden (falls vorhanden) und durch Adresse und Länge festgelegte Region liegen, beim Prüfen gegen
die Begrenzung doppelt zählten. Solche Doppelbilanzierung konnte zu einem inkorrekten Wert für den »total
locked memory« für den Prozess, der die Begrenzung RLIMIT_MEMLOCK überschritt, führen. Damit konnten dann
mlock() und mlock2() fehlschlagen, obwohl die Anfragen hätten erfolgreich sein sollen. Dieser Fehler
wurde in Linux 4.9 behoben.
In Linux 2.4.x bis einschließlich 2.4.17 bewirkte ein Fehler, dass der Schalter MCL_FUTURE von mlockall()
über einen Aufruf von fork(2) vererbt wurde. Dies wurde in Linux 2.4.18 behoben.
Seit Linux 2.6.9 werden, falls ein privilegierter Prozess mlockall(MCL_FUTURE) aufruft und anschließend
Privilegien aufgibt (die Capability CAP_IPC_LOCK verliert, weil er beispielsweise seine effektive UID auf
einen von null verschiedenen Wert setzt), nachfolgende Speicherzuordnungen (z.B. mmap(2), brk(2))
fehlschlagen, wenn die Ressourcengrenze RLIMIT_MEMLOCK angetroffen wird.
SIEHE AUCH
mincore(2), mmap(2), setrlimit(2), shmctl(2), sysconf(3), proc(5), capabilities(7)
ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von Hanno Wagner <wagner@bidnix.bid.fh-hannover.de>,
Martin Schulze <joey@infodrom.org>, Michaela Hohenner <mhohenne@techfak.uni-bielefeld.de>, Martin
Eberhard Schauer <Martin.E.Schauer@gmx.de>, Mario Blättermann <mario.blaettermann@gmail.com> und Helge
Kreutzmann <debian@helgefjell.de> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer
bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die
Mailingliste der Übersetzer.
Linux man-pages 6.9.1 2. Mai 2024 mlock(2)