Provided by: manpages-de-dev_4.15.0-9_all bug

BEZEICHNUNG

       mremap - eine virtuelle Speicheradresse neu mappen

ÜBERSICHT

       #define _GNU_SOURCE         /* siehe feature_test_macros(7) */
       #include <sys/mman.h>

       void *mremap(void *alte_Adresse, size_t alte_Größe,
                    size_t neue_Größe, 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  Verfügung
       stehenden virtuellen Speicherplatz).

       alte_Adresse  ist die alte Adresse des virtuellen Speicherblocks, den man vergrößern (oder
       verkleinern) möchte. Beachten Sie, dass alte_Adresse an  den  Speicherseiten  ausgerichtet
       sein muss. alte_Größe ist die alte Größe des virtuellen Speicherblocks. neue_Größe ist die
       angeforderte Größe des virtuellen Speicherblocks nach der  Größenänderung.  Optional  kann
       ein  fünftes Argument, neue_Adresse, angegeben werden; siehe die folgende Beschreibung von
       MREMAP_FIXED.

       Falls der Wert von alte_Größe Null ist und sich alte_Adresse auf ein gemeinsam benutzbares
       Mapping  bezieht  (siehe  mmap(2)  MAP_SHARED),  dann  wird mremap() ein neues Mapping der
       gleichen Seiten erstellen. neue_Größe wird die Größe 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  schlägt  mremap()  fehl,  wenn an der aktuellen Position nicht
              ausreichend Platz vorhanden ist, um ein Mapping zu vergrößern. 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 ungültig. (Es sollten Offsets relativ
              zur Anfangsadresse des Mappings verwendet werden.)

       MREMAP_FIXED (seit Linux 2.3.31)
              Dieser Schalter dient einem ähnlichen Zweck wie der Schalter MAP_FIXED von mmap(2).
              Wenn dieser Schalter angegeben wird, dann akzeptiert mremap() ein fünftes Argument,
              void *neue_Adresse, das eine an Seiten ausgerichtete Adresse  angibt,  an  die  das
              Mapping verschoben werden muss. Alle früheren Mappings auf den von neue_Adresse und
              neue_Größe 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_Größe
              festgelegten   Bereich    zu    einer    Seitenausnahmebehandlung    führen.    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   gefüllten  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 für mögliche
              Anwendungen von MREMAP_DONTUNMAP.

       Falls das von alte_Adresse und alte_Größe angegebene Speichersegment gesperrt ist (mittels
       mlock(2)   oder   etwas   Ähnlichem),  wird  diese  Sperre  aufrecht  erhalten,  wenn  das
       Speichersegment verschoben oder seine Größe geändert wird. Als Folge davon kann  sich  die
       Größe des durch einen Prozess gesperrten Speichers ändern.

RÜCKGABEWERT

       Bei  Erfolg gibt mremap() einen Zeiger auf den neuen virtuellen Speicherbereich zurück. Im
       Fehlerfall wird der  Wert  von  MAP_FAILED  (d.h.  (void *) -1)  zurückgegeben  und  errno
       gesetzt, um den Fehler anzuzeigen.

FEHLER

       EAGAIN Der  Aufrufende  versuchte,  ein  gesperrtes Speichersegment zu vergrößern. Das war
              nicht möglich, ohne die Resourcen-Begrenzung RLIMIT_MEMLOCK zu überschreiten.

       EFAULT Eine Adresse im Bereich von alte_Adresse bis alte_Adresse+alte_Größe ist für diesen
              Prozess  eine  ungültige  virtuelle  Speicheradresse. Man erhält sogar EFAULT, wenn
              Mappings existieren, die den gesamten angeforderten Adressraum abdecken,  aber  von
              unterschiedlichem Typ sind.

       EINVAL Ein ungültiges Argument wurde übergeben. Mögliche Gründe sind:

              *  alte_Adresse war nicht an der Seitengrenze ausgerichtet

              *  ein  von  MREMAP_MAYMOVE,  MREMAP_FIXED oder MREMAP_DONTUNMAP verschiedener Wert
                 wurde in Schalter übergeben

              *  neue_Größe war Null

              *  neue_Größe oder neue_Adresse war ungültig

              *  der neue Adressbereich, der in  neue_Adresse  und  neue_Größe  angegeben  wurde,
                 überlappte den in alte_Adresse und alte_Größe angegebenen alten Adressbereich

              *  MREMAP_FIXED  oder  MREMAP_DONTUNMAP  wurde  angegeben, ohne auch MREMAP_MAYMOVE
                 anzugeben

              *  MREMAP_DONTUNMAP wurde angegeben, aber eine oder mehrere  Seiten  in  dem  durch
                 alte_Adresse und alte_Größe festgelegten Bereich waren nicht privat anonym

              *  MREMAP_DONTUNMAP   wurde  angegeben  und  alte_Größe  war  nicht  zu  neue_Größe
                 identisch

              *  alte_Größe war Null und  alte_Adresse  bezieht  sich  nicht  auf  ein  gemeinsam
                 benutzbares Mapping (siehe aber FEHLER)

              *  alte_Größe war Null und der Schalter MREMAP_MAYMOVE war nicht angegeben

       ENOMEM Zur Ausführung der Aktion war nicht genug Speicher verfügbar. Mögliche Gründe sind:

              *  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.

              *  MREMAP_DONTUNMAP  wurde  verwandt  und  verursachte dadurch die Erstellung eines
                 neuen Mappings, das den verfügbaren (virtuellen) Speicher  überschreiten  würde.
                 Oder es würde die maximale Anzahl an erlaubten Mappings überschreiten.

KONFORM ZU

       Dieser  Aufruf  ist  Linux-spezifisch  und sollte nicht in portierbaren Programmen benutzt
       werden.

ANMERKUNGEN

       mremap() ändert 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 verfügt über (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 schreibgeschütztes  Segment).  Zugreifen  auf
       virtuellen Speicher außerhalb der Segmente verursacht ebenfalls eine Segmentverletzung.

       Falls mremap() dazu verwandt wird, einen mit mlock(2) oder Äquivalentem gesperrten Bereich
       zu verschieben oder zu erweitern, wird der Aufruf mremap() sich die beste Mühe geben,  den
       neuen  Bereich  zu  bestücken,  wird aber nicht mit ENOMEM fehlschlagen, falls der Bereich
       nicht bestückt werden kann.

       Vor Version 2.4 machte die Glibc die Definition von MREMAP_FIXED nicht verfügbar  und  der
       Prototyp für mremap() ließ das Argument neue_Adresse nicht zu.

   Anwendungsfälle für MREMAP_DONTUNMAP
       Mögliche Anwendungen für MREMAP_DONTUNMAP sind unter Anderem:

       *  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.

       *  Automatische  Speicherbereinigung:   MREMAP_DONTUNMAP   kann   im   Zusammenspiel   mit
          userfaultfd(2)  verwandt werden, um Algorithmen für 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 ursprünglichen
       Mapping,  falls  alte_Größe  Null war und das Mapping auf das alte_Adresse sich bezog, ein
       privates Mapping war (mmap(2) MAP_PRIVATE). Dieses Verhalten war  nicht  beabsichtigt  und
       für  Anwendungen im Benutzerbereich unerwartet (da es das Ziel von mremap() ist, ein neues
       Mapping basierend auf dem ursprünglichen Mapping zu erstellen). Seit  Linux  4.14  schlägt
       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  über  Betriebssysteme  für  weitere Informationen über »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.)

KOLOPHON

       Diese  Seite  ist  Teil  der  Veröffentlichung  5.13  des  Projekts  Linux-man-pages. Eine
       Beschreibung des Projekts, Informationen, wie Fehler  gemeldet  werden  können  sowie  die
       aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG

       Die  deutsche  Übersetzung  dieser  Handbuchseite wurde von Patrick Rother <krd@gulu.net>,
       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 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ 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 ⟨debian-l10n-german@lists.debian.org⟩.