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

名前

       getrlimit, setrlimit, prlimit - 資源の制限を取得/設定する

書式

       #include <sys/time.h>
       #include <sys/resource.h>

       int getrlimit(int resource, struct rlimit *rlim);
       int setrlimit(int resource, const struct rlimit *rlim);

       int prlimit(pid_t pid, int resource, const struct rlimit *new_limit,
        struct rlimit *old_limit);

   glibc 向けの機能検査マクロの要件 (feature_test_macros(7)  参照):

       prlimit(): _GNU_SOURCE

説明

       getrlimit()  と  setrlimit()  は、資源 (resource) の制限 (limit) の設定と取得を行う。 各リ
       ソースには、それに対応するソフトリミットとハードリミットがあり、  rlimit  構造体で定義され
       る:

           struct rlimit {
               rlim_t rlim_cur;  /* ソフトリミット */
               rlim_t rlim_max;  /* ハードリミット
                                    (rlim_cur より小さくない) */
           };

       ソフトリミットは、カーネルが対応するリソースに対して課す制限値である。  ハードリミットはソ
       フトリミットの上限として働く。 特権を持たないプロセスは、ソフトリミットの値を 0 からハード
       リミットの範囲に設定することと、  ハードリミットを下げることのみができる (一度下げたハード
       リミットは上げられない)。 特権プロセス (Linux では初期ユーザー名前空間で  CAP_SYS_RESOURCE
       ケーパビリティ  (capability) を持つプロセス) は ソフトリミットとハードリミットを自由に変更
       できる。

       値 RLIM_INFINITY はリソースに制限がないことを表す  (この値は  getrlimit()   が返す構造体と
       setrlimit()  に渡す構造体の両方で使用される)。

       resource 引数は次のいずれか 1 つである。

       RLIMIT_AS
              This  is  the  maximum  size  of the process's virtual memory (address space).  The
              limit is specified in bytes, and is rounded down to the  system  page  size.   This
              limit  affects  calls  to brk(2), mmap(2), and mremap(2), which fail with the error
              ENOMEM upon exceeding this limit.  In addition,  automatic  stack  expansion  fails
              (and generates a SIGSEGV that kills the process if no alternate stack has been made
              available via sigaltstack(2)).  Since the value is  a  long,  on  machines  with  a
              32-bit long either this limit is at most 2 GiB, or this resource is unlimited.

       RLIMIT_CORE
              This  is  the  maximum size of a core file (see core(5))  in bytes that the process
              may dump.  When 0 no core dump files are created.  When nonzero, larger  dumps  are
              truncated to this size.

       RLIMIT_CPU
              This  is  a  limit,  in  seconds,  on  the  amount of CPU time that the process can
              consume.  When the process reaches the soft limit, it is  sent  a  SIGXCPU  signal.
              The  default  action  for  this  signal  is to terminate the process.  However, the
              signal can be caught, and the handler can return control to the main  program.   If
              the  process continues to consume CPU time, it will be sent SIGXCPU once per second
              until the hard limit is reached, at which time it is sent  SIGKILL.   (This  latter
              point  describes  Linux behavior.  Implementations vary in how they treat processes
              which continue to consume  CPU  time  after  reaching  the  soft  limit.   Portable
              applications  that  need to catch this signal should perform an orderly termination
              upon first receipt of SIGXCPU.)

       RLIMIT_DATA
              This is  the  maximum  size  of  the  process's  data  segment  (initialized  data,
              uninitialized  data,  and  heap).   The limit is specified in bytes, and is rounded
              down to the system page size.  This limit affects calls  to  brk(2),  sbrk(2),  and
              (since  Linux 4.7)  mmap(2), which fail with the error ENOMEM upon encountering the
              soft limit of this resource.

       RLIMIT_FSIZE
              これはプロセスが作成できるファイルサイズの最大値 (バイト単位) である。 このサイズを
              超えてファイルを拡張すると、  SIGXFSZ シグナルを送る。 デフォルトでは、このシグナル
              はプロセスを終了する。 プロセスをキャッチすることもできるが、  関連するシステムコー
              ル (write(2), truncate(2)  など) はエラー EFBIG で失敗する。

       RLIMIT_LOCKS (Linux 2.4.0 から 2.4.24 まで)
              このプロセスが実行できる  flock(2)  ロック数と fcntl(2)  リース数の合計値の上限であ
              る。

       RLIMIT_MEMLOCK
              This is the maximum number of bytes of memory that may be locked  into  RAM.   This
              limit  is  in  effect rounded down to the nearest multiple of the system page size.
              This limit affects mlock(2), mlockall(2), and the  mmap(2)   MAP_LOCKED  operation.
              Since Linux 2.6.9, it also affects the shmctl(2)  SHM_LOCK operation, where it sets
              a maximum on the total bytes in shared memory segments (see shmget(2))  that may be
              locked  by  the real user ID of the calling process.  The shmctl(2)  SHM_LOCK locks
              are accounted for separately from  the  per-process  memory  locks  established  by
              mlock(2), mlockall(2), and mmap(2)  MAP_LOCKED; a process can lock bytes up to this
              limit in each of these two categories.

              In Linux kernels before 2.6.9, this limit controlled  the  amount  of  memory  that
              could  be  locked by a privileged process.  Since Linux 2.6.9, no limits are placed
              on the amount of memory that a privileged process may lock, and this limit  instead
              governs the amount of memory that an unprivileged process may lock.

       RLIMIT_MSGQUEUE (Linux 2.6.8 以降)
              This  is  a  limit  on  the number of bytes that can be allocated for POSIX message
              queues for the real user ID of the calling process.  This  limit  is  enforced  for
              mq_open(3).   Each message queue that the user creates counts (until it is removed)
              against this limit according to the formula:

                  Since Linux 3.5:

                      bytes = attr.mq_maxmsg * sizeof(struct msg_msg) +
                              min(attr.mq_maxmsg, MQ_PRIO_MAX) *
                                    sizeof(struct posix_msg_tree_node)+
                                              /* オーバーヘッド分 */
                              attr.mq_maxmsg * attr.mq_msgsize;
                                              /* メッセージデータ分 */

                  Linux 3.4 and earlier:

                      bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) +
                                              /* オーバーヘッド分 */
                              attr.mq_maxmsg * attr.mq_msgsize;
                                              /* メッセージデータ分 */

              ここで attrmq_attr 構造体であり、 mq_open(3)  の第 4 引数として指定される。  ま
              た、構造体 msg_msgposix_msg_tree_node はカーネル内部の構造体である。

              上記の式での「オーバーヘッド」加算分は、実装において必要となるオーバーヘッドを考慮
              したものである。 また、これにより、ユーザーが長さ 0  のメッセージを無制限に作れない
              ことが保証される (このようなメッセージであっても、 記録のためのオーバーヘッドでシス
              テムメモリーを消費する)。

       RLIMIT_NICE (Linux 2.6.12 以降, 下記の「バグ」の節も参照)
              This specifies a ceiling to which the process's nice  value  can  be  raised  using
              setpriority(2)  or nice(2).  The actual ceiling for the nice value is calculated as
              20 - rlim_cur.  The useful range for this limit is thus from 1 (corresponding to  a
              nice  value  of  19)  to  40  (corresponding to a nice value of -20).  This unusual
              choice of range was necessary because  negative  numbers  cannot  be  specified  as
              resource  limit  values,  since they typically have special meanings.  For example,
              RLIM_INFINITY typically is the same as -1.  For more detail on the nice value,  see
              sched(7).

       RLIMIT_NOFILE
              このプロセスがオープンできるファイルディスクリプター数の最大値より 1 大きい値を指定
              する。 (open(2), pipe(2), dup(2)  などにより)  この上限を超えようとした場合、エラー
              EMFILE  が発生する  (歴史的に、BSD ではこの上限は RLIMIT_OFILE という名前となってい
              る)。

              Since Linux 4.5, this limit also defines the maximum  number  of  file  descriptors
              that an unprivileged process (one without the CAP_SYS_RESOURCE capability) may have
              "in flight" to other processes, by being passed across UNIX domain  sockets.   This
              limit applies to the sendmsg(2)  system call.  For further details, see unix(7).

       RLIMIT_NPROC
              This  is  a  limit  on  the  number of extant process (or, more precisely on Linux,
              threads)  for the real user ID of the calling process.   So  long  as  the  current
              number  of  processes  belonging  to this process's real user ID is greater than or
              equal to this limit, fork(2)  fails with the error EAGAIN.

              The RLIMIT_NPROC  limit  is  not  enforced  for  processes  that  have  either  the
              CAP_SYS_ADMIN or the CAP_SYS_RESOURCE capability.

       RLIMIT_RSS
              プロセスの  resident  set  (RAM 上に存在する仮想ページの数) の 上限である (バイト単
              位)。 この制限は 2.4.30 より前でしか影響がなく、 madvise(2)  に MADV_WILLNEED  を指
              定した関数コールにしか影響しない。

       RLIMIT_RTPRIO (Linux 2.6.12 以降, バグの節も参照)
              sched_setscheduler(2)   や sched_setparam(2) を使って設定できる、そのプロセスのリア
              ルタイム優先度の上限を指定する。

              For further details on real-time scheduling policies, see sched(7)

       RLIMIT_RTTIME (Linux 2.6.25 以降)
              リアルタイムスケジューリング方針でスケジューリングされるプロセスが ブロッキング型の
              システムコールを呼び出さずに消費することのできる CPU 時間の合計についての上限を (マ
              イクロ秒単位で) 指定する。 この上限の目的のため、プロセスがブロッキング型のシステム
              コールを  呼び出す度に、消費された CPU 時間のカウントは 0 にリセットされる。 プロセ
              スが CPU を使い続けようとしたが他のプロセスに置き換えられた (preempted)  場合や、そ
              のプロセスのタイムスライスが満了した場合、  そのプロセスが sched_yield(2)  を呼び出
              した場合は、CPU 時間のカウントはリセットされない。

              ソフトリミットに達すると、そのプロセスに SIGXCPU シグナルが送られる。そのプロセスが
              このシグナルを捕捉するか  無視して、CPU 時間を消費し続けた場合には、 ハードリミット
              に達するまで 1 秒に 1 回 SIGXCPU が生成され続けることになる。  ハードリミットに達し
              た時点で、そのプロセスには SIGKILL シグナルが送られる。

              この上限を意図的に使用するのは、暴走したリアルタイムプロセスを 停止して、システムが
              動かなくなるのを避ける場合である。

              For further details on real-time scheduling policies, see sched(7)

       RLIMIT_SIGPENDING (Linux 2.6.8 以降)
              呼び出し元プロセスの実ユーザー ID に対して キューに入れられるシグナルの  数の制限を
              指定する。この制限をチェックするため、標準シグナルとリアルタ イムシグナルの両方がカ
              ウントされる。しかし、この制限は sigqueue(3) に対してのみ適用され、 kill(2)  使うこ
              とで、そのプロセスに対してま   だキューに入れられていない  シグナルのインスタンスを
              キューに入れることが できる。

       RLIMIT_STACK
              プロセススタックの最大サイズをバイト単位で指定する。  この上限に達すると、  SIGSEGV
              シグナルが生成される。  このシグナルを扱うためには、 プロセスは代りのシグナルスタッ
              ク (sigaltstack(2))  を使用しなければならない。

              Linux 2.6.23 以降では、この制限はプロセスのコマンドライン引数と環境変数  に使用され
              る空間の合計サイズの上限の決定にも使用される。詳細については execve(2)  を参照。

   prlimit()
       Linux  固有の prlimit() システムコールは、 setrlimit() と getrlimit の機能を合わせて拡張し
       たものである。  このシステムコールを使って、任意のプロセスのリソース上限の設定と取得を行う
       ことができる。

       resource 引数は setrlimit() や getrlimit() と同じ意味である。

       new_limit  引数が NULL 以外の場合、 new_limit が指す rlimit 構造体を使って resource のソフ
       トリミットとハードリミットの新しい値が設定される。  old_limit  引数が  NULL   以外の場合、
       prlimit()   の呼び出しが成功すると、   resource   の直前のソフトリミットとハードリミットが
       old_limit が指す rlimit 構造体に格納される。

       The pid argument specifies the ID of the process on which the call is to operate.  If  pid
       is  0,  then  the  call  applies to the calling process.  To set or get the resources of a
       process other than itself, the caller must have the  CAP_SYS_RESOURCE  capability  in  the
       user  namespace  of  the  process  whose  resource  limits are being changed, or the real,
       effective, and saved set user IDs of the target process must match the real user ID of the
       caller  and  the real, effective, and saved set group IDs of the target process must match
       the real group ID of the caller.

返り値

       成功した場合、これらのシステムコールは 0 を返す。 エラーの場合は -1 が返され、 errno  が適
       切に設定される。

エラー

       EFAULT 場所を指すポインター引数がアクセス可能なアドレス空間外を指している。

       EINVAL resource   で指定された値が有効でない。  または、  setrlimit()  や  prlimit()  で、
              rlim->rlim_currlim->rlim_max よりも大きかった。

       EPERM  非特権プロセスがハードリミットを増やそうとした。 この操作には CAP_SYS_RESOURCE ケー
              パビリティが必要である。

       EPERM  呼び出し元がハードリミット  RLIMIT_NOFILE/proc/sys/fs/nr_open (proc(5) 参照) で
              定義される最大値より大きな値に増やそうとした。

       EPERM  (prlimit()) 呼び出し元のプロセスが  pid  で指定されたプロセスの上限を設定する許可を
              持っていなかった。

       ESRCH  pid で指定された ID のプロセスが見つからなかった。

バージョン

       prlimit()  システムコールは  Linux  2.6.36 以降で利用できる。 ライブラリのサポートは glibc
       2.13 以降で利用できる。

属性

       この節で使用されている用語の説明については、 attributes(7) を参照。

       ┌────────────────────────────────────┬───────────────┬─────────┐
       │インターフェース属性      │
       ├────────────────────────────────────┼───────────────┼─────────┤
       │getrlimit(), setrlimit(), prlimit() │ Thread safety │ MT-Safe │
       └────────────────────────────────────┴───────────────┴─────────┘

準拠

       getrlimit(), setrlimit(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

       prlimit(): Linux 固有。

       RLIMIT_MEMLOCKRLIMIT_NPROC は BSD から派生し、 POSIX.1  には指定されていない。これらは
       BSD 系と Linux に存在するが、他の実装は少ない。 RLIMIT_RSS は BSD から派生し、POSIX.1 には
       指定されていない。それにも関わらず多くの実装で存在する。   RLIMIT_MSGQUEUE,   RLIMIT_NICE,
       RLIMIT_RTPRIO, RLIMIT_RTTIME, RLIMIT_SIGPENDING は Linux 固有のものである。

注意

       fork(2)      で作成された作成された子プロセスは、     親プロセスのリソース制限を継承する。
       execve(2) の前後でリソース制限は保存される。

       Resource limits are per-process attributes that are shared by all  of  the  threads  in  a
       process.

       リソースのソフトリミットをそのプロセスが現在のリソース使用量より小さい値に設定することはで
       きる (但し、そのプロセスはそれ以降そのリソースの使用量を増やすことができなくなる)。

       シェルのリソース制限は、シェルの組み込みコマンドである ulimit (csh(1)  では limit ) を使っ
       て設定することができる。  このシェルのリソース制限は、コマンドを実行してシェルが生成するプ
       ロセス に引き継がれる。

       Linux 2.6.24 以降では、 プロセスのリソース上限は  /proc/[pid]/limits  で知ることができる。
       proc(5) 参照。

       古いシステムでは、 setrlimit()  と同様の目的を持つ関数 vlimit()  が提供されていた。 後方互
       換性のため、glibc  でも  vlimit()    を提供している。   全ての新しいアプリケーションでは、
       setrlimit()  を使用すべきである。

   C ライブラリとカーネル ABI の違い
       バージョン  2.13 以降では、 glibc の getrlimit() と setrlimit() のラッパー関数はもはや対応
       するシステムコールを呼び出さず、 代わりに「バグ」の節で説明されている理由から prlimit() を
       利用している。

       The  name  of  the  glibc  wrapper  function  is  prlimit(); the underlying system call is
       prlimit64().

バグ

       以前の Linux カーネルでは、プロセスがソフトまたはハード RLIMIT_CPU  リミットに達した場合に
       送られる  SIGXCPUSIGKILL シグナルが、本来送られるべき時点の 1 (CPU) 秒後に送られてしま
       う。 これはカーネル 2.6.8 で修正された。

       2.6.17 より前の 2.6.x カーネルでは、 RLIMIT_CPU リミットが 0 の場合、 (RLIM_INFINITY  と同
       じように)  「制限なし」と間違って解釈されていた。 Linux 2.6.17 以降では、リミットを 0 に設
       定した場合にも 効果を持つようになっているが、実際にはリミットの値は 1 秒となる。

       カーネル  2.6.12  には、  RLIMIT_RTPRIO   が動作しないというバグがある。この問題はカーネル
       2.6.13 で修正されている。

       カーネル  2.6.12  では、  getpriority(2)   と RLIMIT_NICE が返す優先度の範囲が一つずれてい
       た。このため、nice 値の実際の上限が 19 - rlim_cur になってしまうという影響があった。これは
       カーネル 2.6.13 で修正された。

       Linux  2.6.12 以降では、 プロセスがその RLIMIT_CPU ソフトリミットに達し、 SIGXCPU に対して
       シグナルハンドラーが設定されている場合、 シグナルハンドラーを起動するだけでなく、 カーネル
       は 1 秒間ソフトリミットを増やす。 そのプロセスが CPU 時間を消費し続けている限り、 ハードリ
       ミットに達するまで、この動作が繰り返される。  ハードリミットに達すると、その時点でプロセス
       は kill される。 他の実装では、上記のような RLIMIT_CPU ソフトリミットの変更は行われず、 お
       そらく Linux の動作は標準に準拠していない。  移植性が必要なアプリケーションではこの  Linux
       固有の動作を前提にするのは避けるべきである。  Linux 固有の上限 RLIMIT_RTTIME でも、 ソフト
       リミットに達した場合に同じ動作となる。

       2.4.22  より前のカーネルでは、  rlim->rlim_currlim->rlim_max   より大きかった場合、
       setrlimit()  での EINVAL エラーを検出できない。

       Linux  doesn't  return  an  error  when  an  attempt  to  set  RLIMIT_CPU  has failed, for
       compatibility reasons.

   32 ビットプラットフォームにおける「大きな」リソース上限値の表現
       glibc の getrlimit() と setrlimit() ラッパー関数は、32 ビットプラットフォームであっても 64
       ビットの  rlim_t データ型を使用する。 しかし、 getrlimit() と setrlimit() システムコールで
       使用される rlim_t データ型は (32 ビットの) unsigned long である。  さらに、  Linux  では、
       カーネルは  32 ビットプラットフォームではリソース上限を unsigned long として表現している。
       しかしながら、  32   ビットデータ型は十分な大きさではない。   ここで最も関係がある上限値は
       RLIMIT_FSIZE  である。 この上限はファイルサイズの最大値であり、実用性の面からは、 この上限
       をファイルオフセットを表現するのに使用されている型、    つまり    64    ビットの     off_t
       (_FILE_OFFSET_BITS=64 でコンパイルしたプログラムの場合)、 と同じ幅を持つ型、を使って表現す
       べきである。

       カーネルのこの制限に対する対策として、  プログラムがリソース上限を  32  ビットの  unsigned
       long  で表現できる値よりも大きな値に設定しようとした際には、 glibc の setrlimit() ラッパー
       関数はこの上限値を黙って RLIM_INFINITY に変換していた。 言い換えると、指定されたリソース上
       限値は黙って無視されていた。

       バージョン  2.13 以降の glibc では、 getrlimit() と setrlimit() システムコールの制限に対す
       る回避手段として、 setrlimit() と getrlimit() を prlimit()  を呼び出すラッパー関数として実
       装している。

       以下のプログラムに prlimit() の使用例を示す。

       #define _GNU_SOURCE
       #define _FILE_OFFSET_BITS 64
       #include <stdint.h>
       #include <stdio.h>
       #include <time.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <sys/resource.h>

       #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

       int
       main(int argc, char *argv[])
       {
           struct rlimit old, new;
           struct rlimit *newp;
           pid_t pid;

           if (!(argc == 2 || argc == 4)) {
               fprintf(stderr, "Usage: %s <pid> [<new-soft-limit> "
                       "<new-hard-limit>]\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           pid = atoi(argv[1]);        /* PID of target process */

           newp = NULL;
           if (argc == 4) {
               new.rlim_cur = atoi(argv[2]);
               new.rlim_max = atoi(argv[3]);
               newp = &new;
           }

           /* Set CPU time limit of target process; retrieve and display
              previous limit */

           if (prlimit(pid, RLIMIT_CPU, newp, &old) == -1)
               errExit("prlimit-1");
           printf("Previous limits: soft=%jd; hard=%jd\n",
                   (intmax_t) old.rlim_cur, (intmax_t) old.rlim_max);

           /* Retrieve and display new CPU time limit */

           if (prlimit(pid, RLIMIT_CPU, NULL, &old) == -1)
               errExit("prlimit-2");
           printf("New limits: soft=%jd; hard=%jd\n",
                   (intmax_t) old.rlim_cur, (intmax_t) old.rlim_max);

           exit(EXIT_SUCCESS);
       }

関連項目

       prlimit(1),   dup(2),   fcntl(2),   fork(2),  getrusage(2),  mlock(2),  mmap(2),  open(2),
       quotactl(2),   sbrk(2),   shmctl(2),   malloc(3),   sigqueue(3),    ulimit(3),    core(5),
       capabilities(7), cgroups(7), credentials(7), signal(7)

この文書について

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