GETRLIMIT(2) | Linux Programmer's Manual | GETRLIMIT(2) |
名前¶
getrlimit, setrlimit - 資源の制限を取得/設定する
書式¶
#include <sys/time.h>
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit
*rlim);
int setrlimit(int resource, const struct rlimit
*rlim);
説明¶
getrlimit() と setrlimit() はそれぞれ資源 (resource) の制限 (limit) の設定と取得を行う。 各リソースには、それに対応するソフト・リミットとハード・リミットがある。 リミットは (getrlimit() と setrlimit() の rlim 引き数である) 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 2.2 から 2.6 のものである。 ソフト・リミットを超えて 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)
に対して適用される。
ユーザが作成した各々のメッセージキューのバイト数は
以下の式により計算され、(そのキューが削除されるまでの間)
この制限の計算対象に含められる。
ここで attr は mq_attr 構造体であり、 mq_open(3) の第 4 引き数として指定される。
bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) +
attr.mq_maxmsg * attr.mq_msgsizesizeof(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(2) に対してしか強制されず、 kill(2) 使うことで、そのプロセスに対してまだキューに入れられていない シグナルのインスタンスをキューに入れることができる。
- RLIMIT_STACK
- プロセス・スタックの最大サイズをバイト単位で指定する。
この上限に達すると、
SIGSEGV
シグナルが生成される。
このシグナルを扱うためには、
プロセスは代りのシグナルスタック
(sigaltstack(2))
を使用しなければならない。
Linux 2.6.23 以降では、この制限はプロセスのコマンドライン引き数と環境変数 に使用される空間の合計サイズの上限の決定にも使用される。詳細については execve(2) を参照。
返り値¶
成功した場合は 0 が返される。エラーの場合は -1 が返され、 errno に適切な値が設定される。
エラー¶
- EFAULT
- rlim がアクセス可能なアドレス空間の外を指している。
- EINVAL
- resource が有効でない。 または、 setrlimit() で、 rlim->rlim_cur が rlim->rlim_max よりも大きかった。
- EPERM
- 特権のないプロセスが setrlimit() を使用して ソフト・リミットまたはハード・リミットを 現在のハード・リミットより大きくしようと試みた。 これを行うためには CAP_SYS_RESOURCE ケーパビリティが必要である。 または特権のないプロセスが setrlimit() を使用して ソフトまたはハード RLIMIT_NOFILE リミットを現在のカーネルの最大値 (NR_OPEN) 以上に増加させようとした。
準拠¶
SVr4, 4.3BSD, POSIX.1-2001. RLIMIT_MEMLOCK と RLIMIT_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 カーネルでは、プロセスがソフトまたはハード RLIMIT_CPU リミットに達した場合に送られる SIGXCPU と SIGKILL シグナルが、本来送られるべき時点の 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 で修正された。
2.4.22 より前のカーネルでは、 rlim->rlim_cur が rlim->rlim_max より大きかった場合、 setrlimit() での EINVAL エラーを検出できない。
関連項目¶
dup(2), fcntl(2), fork(2), getrusage(2), mlock(2), mmap(2), open(2), quotactl(2), sbrk(2), shmctl(2), sigqueue(2), malloc(3), ulimit(3), core(5), capabilities(7), signal(7)
2008-10-06 | Linux |