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