plucky (2) mlock.2.gz

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/ に書かれている。