Provided by: manpages-ja-dev_0.5.0.0.20161015+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 && _FILE_OFFSET_BITS == 64

説明

       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
              プロセスの仮想メモリー  (アドレス空間)   の最大サイズ   (バイト単位)。   この制限は
              brk(2),   mmap(2),   mremap(2)   の呼び出しに影響し、この制限を超えた場合は  エラー
              ENOMEM で失敗する。 また自動的なスタック拡張にも失敗する (さらに sigaltstack(2)  を
              使った代替スタックを利用可能にしていなかった場合には、 SIGSEGV を生成してそのプロセ
              スを kill する)。 この値は long 型なので、32 ビットの long 型を持つマシンでは、  こ
              の制限は最大で 2 GiB になるか、この資源が無制限になる。

       RLIMIT_CORE
              core  ファイルの最大サイズ (core(5) 参照)。 0 の場合、core ファイルは生成されない。
              0 以外の場合、このサイズより大きいダンプは切り詰められる。

       RLIMIT_CPU
              CPU 時間の上限 (秒数)。プロセスがソフトリミットに達した場合に、 SIGXCPU  シグナルを
              送る。このシグナルに対するデフォルトの動作は、 プロセスの終了である。ただし、シグナ
              ルをキャッチして、ハンドラーがメイン プログラムに制御を返すこともできる。プロセスが
              CPU  時間を使い続けた 場合は、ハードリミットに達するまで 1 秒毎にプロセスに SIGXCPU
              を送り、 ハードリミットに達すると SIGKILL を送る。  (ソフトリミットを超過したときの
              動作は、 Linux における動作である。ソフ トリミットを超えて CPU 時間を使い続けるプロ
              セスの扱い方についての実装は 変化してきている。  このシグナルをキャッチする必要のあ
              る  移植性を考えた アプリケーションでは、 最初に SIGXCPU を受け取った時点で正しく終
              了 すべきである。)

       RLIMIT_DATA
              プロセスのデータセグメント   (初期化されたデータ・初期化されていないデータ・ヒープ)
              の最大値。  このリミットは  brk(2)  と sbrk(2)  の呼び出しに影響する。 これらの関数
              は、このリソースのソフトリミットに達すると、 エラー ENOMEM で失敗する。

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

       RLIMIT_LOCKS (初期の Linux 2.4 のみ)
              このプロセスが実行できる  flock(2)   ロック数と  fcntl(2)  リース数の合計値を制限す
              る。

       RLIMIT_MEMLOCK
              RAM 内にロックできるメモリーの最大バイト数。 実際には、この制限はシステムページサイ
              ズの最も近い倍数に 切り捨てて丸められる。 この制限は mlock(2), mlockall(2), mmap(2)
              の MAP_LOCKED 操作に影響する。 Linux 2.6.9 以降では shmctl(2)  SHM_LOCK  操作にも影
              響する。  この操作は呼び出し元プロセスの実 (real) ユーザー ID にロックされる 共有メ
              モリーセグメント (shmget(2)  を参照)  の合計バイト数の最大値を設定する。  shmctl(2)
              SHM_LOCK  によるロックは、 mlock(2), mlockall(2), mmap(2)  の MAP_LOCKED によって確
              立されるプロセス毎のメモリーロックとは分けて数える。 1 つのプロセスはこの制限までの
              バイトをロックできる。  この制限には 2 つの種類がある。 2.6.9 より前の Linux カーネ
              ル では、  この制限は特権プロセスによってロックされるメモリーの合計を制御していた。
              Linux 2.6.9 以降では、特権プロセスがロックするメモリーの合計に制限はなく、 代わりに
              この制限は非特権プロセスがロックするメモリーの合計に 適用されるようになった。

       RLIMIT_MSGQUEUE (Linux 2.6.8 以降)
              呼び出し元プロセスの実ユーザー ID に対して、 POSIX メッセージキューのために確保でき
              るバイト数の制限を指定する。 この制限は mq_open(3)  に対して適用される。 ユーザーが
              作成した各々のメッセージキューのバイト数は  以下の式により計算され、(そのキューが削
              除されるまでの間)  この制限の計算対象に含められる。

                  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 以前:
                      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 以降, 下記の「バグ」の節も参照)
              setpriority(2)   や nice(2)  を使って引き上げられるプロセスの nice 値の上限を指定す
              る。 nice 値の実際の上限は 20 - rlim_cur で計算される (このような変な状況は、リソー
              ス制限値として負の数を指定できないため 発生する。通常、負の値は特別な意味を持ってい
              るからである。 例えば、通常は RLIM_INFINITY の値は -1 である)。

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

       RLIMIT_NPROC
              呼び出したプロセスの実ユーザー ID で作成できる最大プロセス数 (より正確には Linux で
              はスレッド数)。 この上限に達すると、 fork(2)  はエラー EAGAIN で失敗する。 この上限
              値は、ケーパビリティ CAP_SYS_ADMINCAP_SYS_RESOURCE のどちらかを持つプロセスには
              適用されない。

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

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

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

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

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

       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 構造体に格納される。

       pid 引き数は呼び出しの操作対象となるプロセス ID を指定する。 pid が 0 の場合、呼び出しは呼
       び出し元プロセスに対して適用される。  自分以外のプロセスのリソースの設定と取得を行うために
       は、 呼び出し元プロセスが CAP_SYS_RESOURCE ケーパビリティを持っているか、 対象となるプロセ
       スの実ユーザー ID、 実効ユーザー ID、 保存 set-user-ID が呼び出し元プロセスの実ユーザー ID
       と一致し、  かつ、 対象となるプロセスの実グループ ID、 実効グループ ID、 保存 set-group-ID
       が呼び出し元プロセスの実グループ ID と一致していなければならない。

返り値

       成功した場合、これらのシステムコールは 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 以降で利用できる。

準拠

       getrlimit(), setrlimit(): SVr4, 4.3BSD, POSIX.1-2001.
       prlimit(): Linux 固有。

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

注意

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

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

       シェルのリソース制限は、シェルの組み込みコマンドである 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() を
       利用している。

バグ

       以前の  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 エラーを検出できない。

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

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

       この問題は Linux 2.6.36 での以下の主な変更により解決された。

       *  32 ビットプラットフォームであっても 64 ビットを使用するリソース上限の新しいカーネルでの
          表現方法の追加。

       *  リソース上限の引き数として 64 ビット値を取る prlimit() システムコールの追加。

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

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

       #define _GNU_SOURCE
       #define _FILE_OFFSET_BITS 64
       #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=%lld; hard=%lld\n",
                   (long long) old.rlim_cur, (long long) 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=%lld; hard=%lld\n",
                   (long long) old.rlim_cur, (long long) old.rlim_max);

           exit(EXIT_FAILURE);
       }

関連項目

       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), signal(7)

この文書について

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