Provided by: manpages-ja-dev_0.5.0.0.20140515+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.65 の一部 である。プロジェクトの説明とバグ報告
       に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。