GETRLIMIT(2) | Linux Programmer's Manual | GETRLIMIT(2) |
名前
getrlimit, setrlimit, prlimit -資源の制限を取得/設定する書式
#include <sys/time.h>glibc 向けの機能検査マクロの要件 ( feature_test_macros(7) 参照):
説明
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
ここで attr は mq_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 時間のカウントはリセットされない。
- RLIMIT_SIGPENDING (Linux 2.6.8 以降)
- 呼び出し元プロセスの実ユーザー ID に対してキューに入れられるシグナルの数の制限を指定する。この制限をチェックするため、標準シグナルとリアルタイムシグナルの両方がカウントされる。しかし、この制限は sigqueue(3) に対してのみ適用され、 kill(2) 使うことで、そのプロセスに対してまだキューに入れられていないシグナルのインスタンスをキューに入れることができる。
- RLIMIT_STACK
-
プロセススタックの最大サイズをバイト単位で指定する。この上限に達すると、
SIGSEGV シグナルが生成される。このシグナルを扱うためには、プロセスは代りのシグナルスタック (
sigaltstack(2)) を使用しなければならない。
prlimit()
The Linux-specific prlimit() system call combines and extends the functionality of setrlimit() and getrlimit(). It can be used to both set and get the resource limits of an arbitrary process.返り値
成功した場合、これらのシステムコールは 0 を返す。エラーの場合は-1 が返され、 errno が適切に設定される。エラー
- EFAULT
- 場所を指すポインタ引き数がアクセス可能なアドレス空間外を指している。
- EINVAL
- resource で指定された値が有効でない。または、 setrlimit() や prlimit() で、 rlim->rlim_cur が rlim->rlim_max よりも大きかった。
- EPERM
- 特権のないプロセスがハードリミットを上げようとした。これを行うためには CAP_SYS_RESOURCE ケーパビリティが必要である。または、特権のないプロセスが RLIMIT_NOFILE ハードリミットを現在のカーネルの最大値 ( NR_OPEN) 以上に増やそうとした。または、呼び出したプロセスが pid で指定されたプロセスのリミットを設定する許可を持っていなかった。
- ESRCH
- Could not find a process with the ID specified in pid.
バージョン
The prlimit() system call is available since Linux 2.6.36. Library support is available since glibc 2.13.準拠
getrlimit(), setrlimit(): SVr4, 4.3BSD, POSIX.1-2001.注意
fork(2) で作成された作成された子プロセスは、親プロセスのリソース制限を継承する。 execve(2) の前後でリソース制限は保存される。バグ
以前の Linux カーネルでは、プロセスがソフトまたはハード RLIMIT_CPU リミットに達した場合に送られる SIGXCPU と SIGKILL シグナルが、本来送られるべき時点の 1 (CPU) 秒後に送られてしまう。これはカーネル 2.6.8 で修正された。例
The program below demonstrates the use of 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.51 の一部である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2013-02-11 | Linux |