MINHERIT(2)

名称
minherit - ページの継承を制御する

ライブラリ
libc

書式
<sys/mman.h> int minherit(void *addr, size_t len, int inherit)

解説
minherit() システムコールは、指定のページが継承の際の特性として inherit を持つように変更します。 すべての実装において、継承の際の特性がページ単位で設定できることが 保証されるているわけではありません。 変更の単位はリージョン全体かもしれません。 FreeBSD は、ページ毎に継承特性を調整する機能を持ちます。 継承は、 fork() で作成された子供に対してのみ影響します。 exec() には影響ありません。 exec されたプロセスは、アドレス空間全体を置き換えます。 このシステムコールは親のアドレス空間に対してもまた影響ありません (親子によるアドレス空間の共有は潜在的にあり得ますが、これは除外します)。

継承は難解な機能であり、ほとんどが mmap() の MAP_SHARED 機能で置き換えられています。 しかしながら、 minherit() を使用して、 MAP_PRIVATE でマップされたメモリブロックを親子間で共有可能です。 これにより、親もしくは子による修正は共有されますが、 元々下層にあるファイルは変更されません。

INHERIT_SHARE
    本オプションは、対象のアドレス空間を親子間で共有させます。 本オプションは、 元々下層にあるバッキングストアがどのようにマップされるかには、影響しません。

INHERIT_NONE
    本オプションは、対象のアドレス空間の継承を完全に防止します。 当該アドレス空間は子の中ではアンマップされます。

INHERIT_COPY
    本オプションは、アドレス空間を子に対しコピーオンライトで継承させます。 本オプションには不幸な副作用があり、 親が fork するときにアドレス空間がコピーオンライトになってしまいます。 元々のマッピングが MAP_SHARED の場合、 親が fork した後にはこれは親においては共有されません。 また、元の共有バッキングストアマッピングは、 親においてアンマップして再マップする以外に回復しようがありません。

戻り値

エラー
minherit() システムコールは次の場合に処理を失敗します:

[EINVAL]
    addr 引数と len 引数によって指定される仮想アドレス範囲が有効ではありません。

[EACCES]
    inherit 引数によって指定されるフラグが、 addr 引数と len 引数によって指定されたページに対して適切ではありませんでした。

バグ
一度 MAP_PRIVATE もしくは MAP_SHARED しているものに継承を設定すると、領域をアンマップして再マップする以外に もともとのコピーオンライトの意味を回復させることはできません。

関連項目
fork(2), madvise(2), mincore(2), mprotect(2), msync(2), munmap(2), rfork(2)

歴史
minherit() システムコールは OpenBSD ではじめて登場しました。