oracular (2) mremap.2.gz

Provided by: manpages-de-dev_4.23.1-1_all bug

BEZEICHNUNG

       mremap - eine virtuelle Speicheradresse neu mappen

BIBLIOTHEK

       Standard-C-Bibliothek (libc, -lc)

ÜBERSICHT

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

       void *mremap(void alte_Adresse[.alte_Größe], 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 die Beschreibung von MAP_SHARED in mmap(2)), 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.

STANDARDS

       Linux.

GESCHICHTE

       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.

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.

   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 (siehe die
       Beschreibung von MAP_PRIVATE in mmap(2)). 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.)

Ü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⟩.