mlock(2) System Calls Manual mlock(2) BEZEICHNUNG mlock, mlock2, munlock, mlockall, munlockall - Speicher (ent)sperren BIBLIOTHEK Standard-C-Bibliothek (libc, -lc) UBERSICHT #include int mlock(const void Adresse[.len], size_t Lange); int mlock2(const void Addresse[.len], size_t Lange, unsigned int Schalter); int munlock(const void Adresse[.len], size_t Lange); 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() fuhren 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 konnen, wenn das von der Kernel-Speicherverwaltung verlangt wird. (Ent)sperren des Speichers wird fur ganze Speicherseiten durchgefuhrt. mlock(), mlock2() und munlock() mlock() sperrt Seiten im Adressbereich, der bei adr beginnt und sich uber Lange 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 adr beginnt und sich uber Lange Byte erstreckt. Der Status der Seiten, die in dem angegebenen Adressbereichs nach einem erfolgreichen Aufruf enthalten sind, hangt 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 befullt werden. Wenn flags 0 ist, verhalt sich mlock2() genau so wie mlock(). munlock() entsperrt Seiten im Adressbereich, der mit adr beginnt und sich uber Lange Byte erstreckt. Nach diesem Aufruf konnen 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 daruber 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 konnten zum Beispiel neue Adress-Seiten sein, die bei einem sich vergrossernden Heap und Stack benotigt 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 zukunftigen (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 zukunftigen Mappings markiert, dass sie Seiten sperren, wenn diese durch Ausnahmebehandlungen hereinkommen, sie werden aber durch die Sperre nicht befullt, 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 spaterer Systemaufruf (z. B. mmap(2), sbrk(2), malloc(3)) fehlschlagen, wenn durch ihn die Zahl gesperrter Bytes das zulassige Maximum uberschreiten wurde (siehe unten). Unter den gleichen Voraussetzungen kann eine Vergrosserung des Stacks ebenfalls fehlschlagen: der Kernel wird die Stack-Vergrosserung verweigern und dem Prozess ein SIGSEGV-Signal schicken. munlockall() entsperrt alle in den Addressraum des aufrufenden Prozesses gemappten Seiten. RUCKGABEWERT Bei Erfolg geben diese Systemaufrufe 0 zuruck. Bei einem Fehler wird -1 zuruckgegeben, errno gesetzt, um den Fehler anzuzeigen und keine Anderungen an den Sperren im Adressraum des Prozesses durchgefuhrt. 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 adr+Lange war kleiner als adr (z. B. kann die Addition einen Uberlauf 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) addr war kein Vielfaches der Seitengrosse. 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 wurde dazu fuhren, dass die Gesamtanzahl der Mappings mit eindeutigen Attributen (z.B. gesperrt oder nicht gesperrt) das erlaubte Maximum uberschreiten wurde. (Beispielsweise wurde das Entsperren eines Bereichs in der Mitte eines derzeit gesperrten Bereichs zu drei Mappings fuhren: 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 uber diese Grenze hinaus Speicher zu sperren. Diese Grenze wird nicht erzwungen, wenn der Prozess privilegiert ist (CAP_IPC_LOCK). ENOMEM (Linux 2.4 und alter) Der aufrufende Prozess versuchte, mehr als die Halfte des RAMs zu sperren. EPERM Der Aufrufende ist nicht privilegiert, benotigt aber zur Durchfuhrung der angeforderten Aktionen Privilegien (CAP_IPC_LOCK). EPERM (munlockall()) (Linux 2.6.8 und alter) Der Aufrufende war nicht privilegiert (CAP_IPC_LOCK). VERSIONEN Linux Unter Linux runden mlock(), mlock2() und munlock() adr automatisch zur nachsten Seitengrenze ab. Da aber die POSIX.1-Spezifikation von mlock() und munlock() Implementierungen gestattet, welche die Ausrichtung von adr 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() verfugbar sind, ist _POSIX_MEMLOCK_RANGE in definiert und die Anzahl der Bytes pro Seite kann der Konstante PAGESIZE (wenn sie definiert ist) in entnommen werden oder durch einen Aufruf von sysconf(_SC_PAGESIZE) bestimmt werden. Auf POSIX-Systemen, auf denen mlockall() und munlockall() verfugbar sind, ist _POSIX_MEMLOCK in als ein Wert grosser 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 Hauptgrunde fur unerwartete Verzogerungen in der Programmausfuhrung. Echtzeitanwendungen werden ausserdem fur gewohnlich mit sched_setscheduler(2) auf einen Echtzeit-Scheduler umschalten. Kryptographische Sicherheitssoftware stellt oft sicherheitskritische Bytes wie Passworter oder geheime Schlussel als Datenstrukturen dar. Durch Paging konnten diese geheimen Daten auf ein permanentes Auslagerungsspeichermedium ubertragen werden, von wo aus sie auch dann noch Dritten zuganglich sein konnen, lange nachdem das Programm die geheimen Daten aus dem RAM geloscht und sich beendet hat. (Bedenken Sie bitte, dass der Suspend-Modus von Laptops und manchen Desktop-Rechnern, unabhangig von Speichersperren, eine Kopie des RAMs auf der Platte speichern wird.) Echtzeitprozesse, die mittels mlockall() Verzogerungen 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 grosse 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 fur den Stack gemappt und konnen 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 wahrend eines execve(2) geloscht. Beachten Sie, dass fork(2) den Adressraum fur eine Kopieren-beim-Schreiben-Aktion vorbereiten wird. Die Konsequenz ist, dass nachfolgende Schreibaktionen zu einer Seitenausnahmebehandlung fuhren werden, die wiederum hohe Latenzen fur Echtzeitprozesse hervorrufen. Daher ist es essenziell, fork(2) nicht nach einer mlockall()- oder mlock()-Aktion auszufuhren - selbst nicht aus einem Thread, der bei niedriger Prioritat innerhalb eines Prozesses lauft, der wiederum einen Thread hat, der mit erhohter Prioritat lauft. Die Speichersperrung wird automatisch entfernt, wenn der Adressbereich mittels munmap(2) entmappt wird. Speichersperren werden nicht hochgezahlt (>>gestapelt<<), das heisst, Seiten die mehrmals durch den Aufruf von mlockall(), mlock2() oder mlock() gesperrt wurden werden durch einen einzigen Aufruf von munlock() fur den entsprechenden Bereich oder durch munlockall() sofort wieder freigegeben. Seiten, die an verschiedene Orte oder fur 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 Anderungen verloren. Der Schalter MLOCK_ONFAULT von mlock2() und der Schalter MCL_ONFAULT von mlockall() erlaubt effizientes Speicher-Sperren fur Anwendungen, die mit grossen Mappings umgehen, bei denen nur ein (kleiner) Anteil von Seiten im Mapping beruhrt werden. In diesen Fallen wurde das Sperren aller Seiten in dem Mapping eine erhebliche Einbusse fur das Speicher-Sperren verursachen. Grenzen und Zugriffsrechte Bis einschliesslich 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 alter bedeutete ein Fehler in der Bilanzierung des Kernels fur gesperrten Speicher von unprivilegierten Prozessen (d.h. solchen ohne CAP_IPC_LOCK), das die gesperrten Bytes, die einer uberlappenden (falls vorhanden) und durch adr und Lange festgelegte Region liegen, beim Prufen gegen die Begrenzung doppelt zahlten. Solche Doppelbilanzierung konnte zu einem inkorrekten Wert fur den >>total locked memory<< fur den Prozess, der die Begrenzung RLIMIT_MEMLOCK uberschritt, fuhren. Damit konnten dann mlock() und mlock2() fehlschlagen, obwohl die Anfragen hatten erfolgreich sein sollen. Dieser Fehler wurde in Linux 4.9 behoben. In Linux 2.4.x bis einschliesslich 2.4.17 bewirkte ein Fehler, dass der Schalter MCL_FUTURE von mlockall() uber 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 anschliessend 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) UBERSETZUNG Die deutsche Ubersetzung dieser Handbuchseite wurde von Hanno Wagner , Martin Schulze , Michaela Hohenner , Martin Eberhard Schauer , Mario Blattermann und Helge Kreutzmann erstellt. Diese Ubersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezuglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG ubernommen. Wenn Sie Fehler in der Ubersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Ubersetzer . Linux man-pages 6.06 31. Oktober 2023 mlock(2)