mremap(2) System Calls Manual mremap(2) BEZEICHNUNG mremap - eine virtuelle Speicheradresse neu mappen BIBLIOTHEK Standard-C-Bibliothek (libc, -lc) UBERSICHT #define _GNU_SOURCE /* siehe feature_test_macros(7) */ #include void *mremap(void alte_Adresse[.alte_Grosse], size_t alte_Grosse, size_t neue_Grosse, int Schalter, /* void *neue_Adresse */); BESCHREIBUNG mremap() erweitert (oder verkleinert) ein bestehendes Speicher-Mapping, potenziell durch gleichzeitiges Verschieben (bestimmt durch das Argument Schalter und den zur Verfugung stehenden virtuellen Speicherplatz). alte_Adresse ist die alte Adresse des virtuellen Speicherblocks, den man vergrossern (oder verkleinern) mochte. Beachten Sie, dass alte_Adresse an den Speicherseiten ausgerichtet sein muss. alte_Grosse ist die alte Grosse des virtuellen Speicherblocks. neue_Grosse ist die angeforderte Grosse des virtuellen Speicherblocks nach der Grossenanderung. Optional kann ein funftes Argument, neue_Adresse, angegeben werden; siehe die folgende Beschreibung von MREMAP_FIXED. Falls der Wert von alte_Grosse Null ist und sich alte_Adresse auf ein gemeinsam benutzbares Mapping bezieht (siehe die Beschreibung von MAP_SHARED in mmap(2)), dann wird mremap() ein neues Mapping der gleichen Seiten erstellen. neue_Grosse wird die Grosse des neuen Mappings sein und der Ort des neuen Mappings kann mit neue_Adresse festgelegt werden, siehe die nachfolgende Beschreibung von MREMAP_FIXED. Falls mittels dieser Methode ein neues Mapping angefordert wird, dann muss der Schalter MREMAP_MAYMOVE angegeben werden. Das Bitmasken-Argument Schalter kann 0 sein oder die folgenden Schalter enthalten: MREMAP_MAYMOVE Per Voreinstellung schlagt mremap() fehl, wenn an der aktuellen Position nicht ausreichend Platz vorhanden ist, um ein Mapping zu vergrossern. Wird dieser Schalter angegeben, darf der Kernel das Speicher-Mapping an eine neue virtuelle Adresse verlegen, falls das erforderlich ist. Wenn das Mapping verlegt wurde, werden absolute Zeiger zum Ort des alten Mappings ungultig. (Es sollten Offsets relativ zur Anfangsadresse des Mappings verwendet werden.) MREMAP_FIXED (seit Linux 2.3.31) Dieser Schalter dient einem ahnlichen Zweck wie der Schalter MAP_FIXED von mmap(2). Wenn dieser Schalter angegeben wird, dann akzeptiert mremap() ein funftes Argument, void *neue_Adresse, das eine an Seiten ausgerichtete Adresse angibt, an die das Mapping verschoben werden muss. Alle fruheren Mappings auf den von neue_Adresse und neue_Grosse angegebenen Adressbereich werden verworfen. Falls MREMAP_FIXED angegeben wird, muss ebenfalls MREMAP_MAYMOVE angegeben werden. MREMAP_DONTUNMAP (seit Linux 5.7) Dieser Schalter, der zusammen mit MREMAP_MAYMOVE verwandt werden muss, verlegt das Mapping auf eine neue Adresse, aber entfernt das Mapping an der alte_Adresse nicht. Der Schalter MREMAP_DONTUNMAP kann nur zusammen mit privaten anonymen Mappings verwandt werden (siehe die Beschreibung von MAP_PRIVATE und MAP_ANONYMOUS in mmap(2)). Nach Abschluss wird jeder Zugriff auf den durch alte_Adresse und alte_Grosse festgelegten Bereich zu einer Seitenausnahmebehandlung fuhren. Die Seitenausnahmebehandlung wird durch den Handler userfaultfd(2) erledigt, falls die Adresse in dem vorher mit userfaultfd(2) registrierten Bereich liegt. Andernfalls wird der Kernel einen mit Nullen gefullten Bereich belegen, der die Ausnahmebehandlung erledigt. Der Schalter MREMAP_DONTUNMAP kann zur atomaren Verschiebung eines Mappings verwandt werden, wobei die Quelle gemappt bleibt. Siehe ANMERKUNGEN fur mogliche Anwendungen von MREMAP_DONTUNMAP. Falls das von alte_Adresse und alte_Grosse angegebene Speichersegment gesperrt ist (mittels mlock(2) oder etwas Ahnlichem), wird diese Sperre aufrecht erhalten, wenn das Speichersegment verschoben oder seine Grosse geandert wird. Als Folge davon kann sich die Grosse des durch einen Prozess gesperrten Speichers andern. RUCKGABEWERT Bei Erfolg gibt mremap() einen Zeiger auf den neuen virtuellen Speicherbereich zuruck. Im Fehlerfall wird der Wert von MAP_FAILED (d.h. (void *) -1) zuruckgegeben und errno gesetzt, um den Fehler anzuzeigen. FEHLER EAGAIN Der Aufrufende versuchte, ein gesperrtes Speichersegment zu vergrossern. Das war nicht moglich, ohne die Resourcen-Begrenzung RLIMIT_MEMLOCK zu uberschreiten. EFAULT Eine Adresse im Bereich von alte_Adresse bis alte_Adresse+alte_Grosse ist fur diesen Prozess eine ungultige virtuelle Speicheradresse. Man erhalt sogar EFAULT, wenn Mappings existieren, die den gesamten angeforderten Adressraum abdecken, aber von unterschiedlichem Typ sind. EINVAL Ein ungultiges Argument wurde ubergeben. Mogliche Grunde sind: o alte_Adresse war nicht an der Seitengrenze ausgerichtet o ein von MREMAP_MAYMOVE, MREMAP_FIXED oder MREMAP_DONTUNMAP verschiedener Wert wurde in Schalter ubergeben o neue_Grosse war Null o neue_Grosse oder neue_Adresse war ungultig o der neue Adressbereich, der in neue_Adresse und neue_Grosse angegeben wurde, uberlappte den in alte_Adresse und alte_Grosse angegebenen alten Adressbereich o MREMAP_FIXED oder MREMAP_DONTUNMAP wurde angegeben, ohne auch MREMAP_MAYMOVE anzugeben o MREMAP_DONTUNMAP wurde angegeben, aber eine oder mehrere Seiten in dem durch alte_Adresse und alte_Grosse festgelegten Bereich waren nicht privat anonym o MREMAP_DONTUNMAP wurde angegeben und alte_Grosse war nicht zu neue_Grosse identisch o alte_Grosse war Null und alte_Adresse bezieht sich nicht auf ein gemeinsam benutzbares Mapping (siehe aber FEHLER) o alte_Grosse war Null und der Schalter MREMAP_MAYMOVE war nicht angegeben ENOMEM Zur Ausfuhrung der Aktion war nicht genug Speicher verfugbar. Mogliche Grunde sind: o Der Speicherbereich kann an der aktuellen virtuellen Adresse nicht erweitert werden und in Schalter ist der Schalter MREMAP_MAYMOVE nicht gesetzt. Oder es gibt nicht genug freien (virtuellen) Speicher. o MREMAP_DONTUNMAP wurde verwandt und verursachte dadurch die Erstellung eines neuen Mappings, das den verfugbaren (virtuellen) Speicher uberschreiten wurde. Oder es wurde die maximale Anzahl an erlaubten Mappings uberschreiten. STANDARDS Linux. GESCHICHTE Vor Version 2.4 machte die Glibc die Definition von MREMAP_FIXED nicht verfugbar und der Prototyp fur mremap() liess das Argument neue_Adresse nicht zu. ANMERKUNGEN mremap() andert das Mapping zwischen virtuellen Adressen und Speicherseiten. Dies kann benutzt werden, um ein sehr effizientes realloc(3) zu implementieren. Unter Linux ist der Speicher in Seiten eingeteilt. Ein Prozess verfugt uber (ein oder) mehrere lineare virtuelle Speichersegmente. Jedes virtuelle Speichersegment hat ein oder mehr Mappings auf reale Speicherseiten (in der Seitentabelle). Jedes virtuelle Speichersegment hat seinen eigenen Schutz (Zugriffsrechte), welcher eine Segmentverletzung (Segmentation violation, SIGSEGV) verursachen kann, wenn auf den Speicher nicht korrekt zugegriffen wird (z.B. beim Schreiben in ein schreibgeschutztes Segment). Zugreifen auf virtuellen Speicher ausserhalb der Segmente verursacht ebenfalls eine Segmentverletzung. Falls mremap() dazu verwandt wird, einen mit mlock(2) oder Aquivalentem gesperrten Bereich zu verschieben oder zu erweitern, wird der Aufruf mremap() sich die beste Muhe geben, den neuen Bereich zu bestucken, wird aber nicht mit ENOMEM fehlschlagen, falls der Bereich nicht bestuckt werden kann. Anwendungsfalle fur MREMAP_DONTUNMAP Mogliche Anwendungen fur MREMAP_DONTUNMAP sind unter Anderem: o Nicht kooperatives userfaultfd(2): eine Anwendung kann sich einen virtuellen Adressbereich mittels MREMAP_DONTUNMAP schnappen und dann einen userfaultfd(2)-Handler einsetzen, um die Seitenausnahmebehandlungen zu handhaben, die nachfolgend auftreten, wenn andere Threads in dem Prozess auf Seiten in dem geschnappten Bereich zugreifen. o Automatische Speicherbereinigung: MREMAP_DONTUNMAP kann im Zusammenspiel mit userfaultfd(2) verwandt werden, um Algorithmen fur automatische Speicherbereinigung zu implementieren (z.B. in einer virtuellen Java-Maschine). Eine solche Implementierung kann billiger (und einfacher) als konventionelle automatische Speicherbereinigungstechniken sein, die Seiten mit einem PROT_NONE-Schutz im Zusammenspiel mit dem SIGSEGV-Handler markieren, um Zugriff auf diese Seiten abzufangen. FEHLER Vor Linux 4.14 erstellte mremap() ein neues privates Mapping ohne Bezug zum ursprunglichen Mapping, falls alte_Grosse Null war und das Mapping auf das alte_Adresse sich bezog, ein privates Mapping war (siehe die Beschreibung von MAP_PRIVATE in mmap(2)). Dieses Verhalten war nicht beabsichtigt und fur Anwendungen im Benutzerbereich unerwartet (da es das Ziel von mremap() ist, ein neues Mapping basierend auf dem ursprunglichen Mapping zu erstellen). Seit Linux 4.14 schlagt mremap() in diesem Szenario mit dem Fehler EINVAL fehl. SIEHE AUCH brk(2), getpagesize(2), getrlimit(2), mlock(2), mmap(2), sbrk(2), malloc(3), realloc(3) Ihr Lieblingsbuch uber Betriebssysteme fur weitere Informationen uber >>paged memory<<. (Modern Operating Systems von Andrew S. Tanenbaum, Inside Linux von Randolph Bentson, The Design of the UNIX Operating System von Maurice J. Bach.) UBERSETZUNG Die deutsche Ubersetzung dieser Handbuchseite wurde von Patrick Rother , 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 16. Januar 2024 mremap(2)