Provided by: manpages-ja-dev_0.5.0.0.20131015+dfsg-2_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  ファイルの最大サイズ。  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)  に対して適用される。 ユーザが作
              成した各々のメッセージキューのバイト数は  以下の式により計算され、(そのキューが削除
              されるまでの間)  この制限の計算対象に含められる。

                  bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) +
                          attr.mq_maxmsg * attr.mq_msgsize

              ここで attrmq_attr 構造体であり、 mq_open(3)  の第 4 引き数として指定される。

              sizeof(struct msg_msg *) (Linux/i386 では 4 バイト) を含む最初の加数は、 ユーザーが
              長さ 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 で失敗する。

       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      ケーパビリティが必要である。     または、特権のないプロセスが
              RLIMIT_NOFILE ハードリミットを 現在のカーネルの最大値 (NR_OPEN)  以上に増やそうとし
              た。 または、呼び出したプロセスが 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()  を使用すべきである。

バグ

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

       以下のプログラムに 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.54 の一部  である。プロジェクト
       の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。