Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       mlock, mlock2, munlock, mlockall, munlockall - メモリーのロックとロック解除を行う

書式

       #include <sys/mman.h>

       int mlock(const void *addr, size_t len);
       int mlock2(const void *addr, size_t len, int flags);
       int munlock(const void *addr, size_t len);

       int mlockall(int flags);
       int munlockall(void);

説明

       mlock()  と mlockall() は、呼び出し元プロセスの仮想アドレス空間の一部または全部を RAM 上に
       ロックし、メモリーがスワップエリアにページングされるのを防ぐ。

       munlock()  と munlockall()  は逆の操作で、それぞれ呼び出し元プロセスの仮想アドレス空間の一
       部または全部を  ロック解除する。つまり、指定された仮想アドレス範囲のページは  カーネルメモ
       リーマネージャーから要求されればスワップアウトするようになる。  メモリーのロックとロック解
       除はページ単位で行われる。

       メモリーのロックとロック解除はページ単位で行われる。

   mlock(), mlock2(), munlock()
       mlock()   は addr から始まる長さ len バイトのアドレス範囲のページをロックする。 呼び出しが
       成功した場合には、 指定されたアドレス範囲を含む全てのページは RAM に残り続けることが保証さ
       れる。 これらのページは後でロック解除されるまで RAM に残り続けることが保証される。

       mlock2()   also locks pages in the specified range starting at addr and continuing for len
       bytes.  However, the state of the pages contained in that range  after  the  call  returns
       successfully will depend on the value in the flags argument.

       The flags argument can be either 0 or the following constant:

       MLOCK_ONFAULT
              Lock  pages  that  are  currently  resident  and  mark the entire range so that the
              remaining nonresident pages are locked when they are populated by a page fault.

       If flags is 0, mlock2()  behaves exactly the same as mlock().

       munlock()  は、 addr から始まる長さ  len  バイトのアドレス範囲のページのロックを解除する。
       この呼び出しを行った後は、カーネルが、指定されたメモリー範囲を含む  全てのページを外部のス
       ワップ空間に移動できるようになる。

   mlockall()  munlockall()
       mlockall()   は呼び出し元プロセスのアドレス空間にマップされている全てのページを   ロックす
       る。これにはコード、データ、スタックの  各セグメント、共有ライブラリ、カーネルのユーザー空
       間データ、 共有メモリー、メモリーマップされたファイルが含まれる。 システムコールが成功した
       場合には全てのマップされたページは  RAM に 残ることを保証される。 これらのページは後でロッ
       ク解除されるまで RAM に残り続けることが保証される。

       flags 引数は以下の内容の一つまたは複数のビット OR から構成される:

       MCL_CURRENT
              現在、プロセスのアドレス空間にマップされている全てのページをロックする。

       MCL_FUTURE
              将来、プロセスのアドレス空間にマップされる全てのページをロックする。 例えば、ヒープ
              (heap)   やスタックの成長により新しく必要になったページだけで  なく、新しくメモリー
              マップされたファイルや共有メモリー領域もロックされる。

       MCL_ONFAULT (Linux 4.4 以降)
              Used together with MCL_CURRENT,  MCL_FUTURE,  or  both.   Mark  all  current  (with
              MCL_CURRENT)   or  future  (with  MCL_FUTURE)  mappings to lock pages when they are
              faulted in.  When  used  with  MCL_CURRENT,  all  present  pages  are  locked,  but
              mlockall()   will  not  fault in non-present pages.  When used with MCL_FUTURE, all
              future mappings will be marked to lock pages when they are  faulted  in,  but  they
              will not be populated by the lock when the mapping is created.  MCL_ONFAULT must be
              used with either MCL_CURRENT or MCL_FUTURE or both.

       MCL_FUTURE が指定されていると、以後のシステムコール (例えば、 mmap(2), sbrk(2), malloc(3))
       は、ロックするバイト数が許可された最大値  (下記参照) を超えた場合に 失敗する可能性がある。
       同様に、スタックの成長も失敗する可能性がある。    その場合、カーネルはスタックの拡張を拒否
       し、 SIGSEGV をプロセスに送る。

       munlockall()    は、呼び出し元プロセスのアドレス空間にマッピングされている  全てのページを
       ロック解除する。

返り値

       成功した場合は、これらのシステムコールはゼロを返す。 エラーの場合は -1 が返され、 errno が
       適切に設定され、プロセスのアドレス空間におけるロックは変更されない。

エラー

       ENOMEM (Linux  2.6.9 以降) 呼び出し元は非ゼロの ソフト資源制限 RLIMIT_MEMLOCK を持つが、制
              限が許可している以上のメモリーをロックしようとした。     この制限は、プロセスが特権
              (CAP_IPC_LOCK) を持っている場合は適用されない。

       ENOMEM (Linux 2.4 以前) 呼び出し元プロセスが RAM の半分以上をロックしようとした。

       EPERM  呼び出し側が特権を持っていないが、  要求された操作を実行するには特権 (CAP_IPC_LOCK)
              が必要である。

       For mlock(), mlock2(), and munlock():

       EAGAIN 指定されたアドレス範囲の一部または全てをロックすることができなかった。

       EINVAL addr+len の加算の結果が addr よりも小さかった (例えば、加算でオーバーフローが発生し
              たなど)。

       EINVAL (Linux ではこの意味で使われない)  addr がページサイズの倍数ではない。

       ENOMEM 指定されたアドレス範囲がプロセスのアドレス空間にマップされたページと 一致しない。

       ENOMEM Locking  or  unlocking  a  region would result in the total number of mappings with
              distinct attributes (e.g., locked versus unlocked)  exceeding the allowed  maximum.
              (For  example,  unlocking a range in the middle of a currently locked mapping would
              result in three mappings: two locked mappings at each end and an  unlocked  mapping
              in the middle.)

       For mlock2():

       EINVAL 未知の flags が指定された。

       mlockall()  用として:

       EINVAL Unknown flags were specified or MCL_ONFAULT was specified without either MCL_FUTURE
              or MCL_CURRENT.

       munlockall()  用として:

       EPERM  (Linux 2.6.8 以前) 呼び出し元が権限 (CAP_IPC_LOCK)  を持っていない。

バージョン

       mlock2()  is available since Linux 4.4; glibc support was added in version 2.27.

準拠

       POSIX.1-2001, POSIX.1-2008, SVr4.

       mlock2() は Linux 固有である。

       mlock()  と munlock()  が使用可能な POSIX システムでは _POSIX_MEMLOCK_RANGE<unistd.h>
       で定義されている。  また、ページあたりのバイト数は、  <limits.h> で定義される定数 PAGESIZE
       から (定義されている場合)、もしくは sysconf(_SC_PAGESIZE) を呼び出すことで決定できる。

       mlockall()   と  munlockall()   が利用可能な  POSIX   システムでは、   _POSIX_MEMLOCK<unistd.h> で 0 より大きい値に定義されている (sysconf(3)  も参照のこと)。

注意

       メモリーのロックの用途としては主に二つある:  リアルタイム アルゴリズムと高いセキュリティの
       必要なデータ処理である。リアルタイムの  アプリケーションは決定的なタイミングやスケジューリ
       ングを必要とするが、    ページングは予期しないプログラムの実行遅延をもたらす主要な要因とな
       る。 リアルタイムのアプリケーションはたいていは sched_setscheduler(2)   でリアルタイムスケ
       ジューラに変更される。  暗号やセキュリティのソフトウェアはしばしばパスワードや秘密鍵のデー
       タの ような重要なバイト列を扱う。ページングの結果、これらの秘密が スワップ用の固定媒体に転
       送されるかもしれない。そして、セキュリティ  ソフトウェアが  RAM 上の秘密を削除して終了した
       ずっと後になっても、   このスワップされたデータには敵がアクセスできる可能性がある    (しか
       し、ラップトップといくつかのデスクトップコンピュータの サスペンドモードはシステムの RAM の
       内容をメモリーのロックに関わらず ディスクに保存することに注意)。

       リアルタイムプロセスが mlockall()   を使ってページフォールトによる遅延を防ごうとする場合、
       関数呼び出しによってページフォールトが発生しないように、              時間制限の厳しい部分
       (time-critical  section)  に入る前に  十分な量のロックされたスタックを確保しておく必要があ
       る。  これを実現するには、十分な大きさの自動変数  (の配列) を確保し、 これらのスタック用の
       ページがメモリー上に確保されるようにこの配列に  書き込みを行う関数を用意し、これを呼び出せ
       ばよい。こうすることで、  十分な量のページがスタックにマッピングされ、RAM にロックされる。
       ダミーの書き込みを行うことによって、 時間制限の厳しい部分 (critical section)  内では書き込
       み時コピーによる ページフォールトさえも発生しないことが保証される。

       Memory  locks  are  not  inherited  by  a child created via fork(2)  and are automatically
       removed (unlocked) during an execve(2)  or when the process  terminates.   The  mlockall()
       MCL_FUTURE  and MCL_FUTURE | MCL_ONFAULT settings are not inherited by a child created via
       fork(2) and are cleared during an execve(2).

       Note that fork(2)  will prepare the address space  for  a  copy-on-write  operation.   The
       consequence is that any write access that follows will cause a page fault that in turn may
       cause high latencies for a real-time process.  Therefore, it  is  crucial  not  to  invoke
       fork(2)   after an mlockall() or mlock()  operation—not even from a thread which runs at a
       low priority within a process which also has a thread running at elevated priority.

       あるアドレス範囲に対するメモリーロックは、そのアドレス範囲が munmap(2)  によってアンマップ
       された場合は削除される。

       メモリーのロックは累積しない。  すなわち複数回  mlock(), mlock2(), mlockall() を呼び出して
       ロックされたページでも、 対応する範囲に対して munlock()  を 1 回呼び出したり  munlockall()
       を呼び出したりするだけでロック解除される。    複数の場所や複数のプロセスにマップされている
       ページは、少なくとも一つの場所、 一つのプロセスでロックされている限りは RAM に残り続ける。

       If a call to mlockall()  which uses the MCL_FUTURE flag is followed by another  call  that
       does not specify this flag, the changes made by the MCL_FUTURE call will be lost.

       The  mlock2()   MLOCK_ONFAULT  flag  and  the mlockall()  MCL_ONFAULT flag allow efficient
       memory locking for applications that deal with large mappings where only a (small) portion
       of pages in the mapping are touched.  In such cases, locking all of the pages in a mapping
       would incur a significant penalty for memory locking.

   Linux での注意
       Linux では、 mlock(), mlock2(), munlock() は自動的に addr を端数切り捨てにより一番近いペー
       ジ境界へと丸める。 しかし POSIX.1 仕様の mlock() と munlock() は addr がページ境界に合って
       いることを要求する実装も許している。  そのため移植性を意図したアプリケーションではきちんと
       境界に合わせた方が良い。

       Linux  固有の  /proc/[pid]/status  ファイルの  VmLck  フィールドには、  mlock(), mlock2(),
       mlockall() および mmap(2) MAP_LOCKED を使って、 ID が  PID  のプロセスがロックしているメモ
       リー量 (キロバイト単位) が表示される。

   制限と権限
       Linux 2.6.8 以前では、メモリーをロックするためには特権 (CAP_IPC_LOCK)  が必要で、 ソフト資
       源制限 RLIMIT_MEMLOCK はプロセスがどれだけのメモリーをロックできるかの制限を定義する。

       Linux 2.6.9 以降では、特権を持つプロセスがロックできるメモリー量は無制限となり、  代わりに
       ソフト資源制限 RLIMIT_MEMLOCK は特権を持たないプロセスがロックできるメモリー量の制限を定義
       する。

バグ

       In Linux 4.8 and  earlier,  a  bug  in  the  kernel's  accounting  of  locked  memory  for
       unprivileged processes (i.e., without CAP_IPC_LOCK)  meant that if the region specified by
       addr and len overlapped an existing lock, then the already locked bytes in the overlapping
       region  were  counted twice when checking against the limit.  Such double accounting could
       incorrectly calculate a "total locked memory" value for  the  process  that  exceeded  the
       RLIMIT_MEMLOCK  limit,  with  the result that mlock()  and mlock2() would fail on requests
       that should have succeeded.  This bug was fixed in Linux 4.9.

       2.4.17 までの 2.4 シリーズの Linux カーネルには、 mlockall()  MCL_FUTURE フラグが  fork(2)
       で継承されると言うバグがある。 これはカーネル 2.4.18 で修正された。

       カーネル  2.6.9 以降では、特権を持ったプロセスが mlockall(MCL_FUTURE) を呼び出した後で、特
       権をなくした場合 (例えば、 実効 UID を 0 以外の値に変更するなどにより、 CAP_IPC_LOCK  ケー
       パビリティを失った場合)、リソース上限  RLIMIT_MEMLOCK に達すると、それ以降のメモリー割り当
       て (例えば mmap(2), brk(2))  は失敗する。

関連項目

       mincore(2), mmap(2), setrlimit(2), shmctl(2), sysconf(3), proc(5), capabilities(7)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの
       説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。