ulimit について
リソースの制限値は、まず /etc/login.conf により設定される。
ulimit は B系シェルの組み込みコマンド。C系シェルでは limit, unlimit を使う。
FreeBSD には /usr/bin/limits というコマンドもある。
ソフトリミット=一般ユーザが変更できる
ハードリミット=一般ユーザは上げることができない。下げることはできる。
ulimit の -S/-H オプションを指定しないとハード・ソフト両方変更される。
ssh で Linux に接続した場合、
bash: ulimit: cannot modify limit: Operation not permitted
というエラーが出るという FAQ がある。
これは ssh 経由で接続したプロセスに対し、/etc/security/limits.conf の設定が反映されないため。
sshd_config で特権分離をオフにすれば /etc/security/limits.conf が読まれるようになる。
UsePrivilegeSeparation no
http://www.miraclelinux.com/technet/faq/data/00073.html
特権分離について
http://www.citi.umich.edu/u/provos/ssh/privsep-j.html
ulimit のソースはこんな感じ。
max user proc 取得。
long getmaxchild () { static long maxchild = -1L; if (maxchild > 0) return maxchild; #if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX) maxchild = sysconf (_SC_CHILD_MAX); #else # if defined (CHILD_MAX) maxchild = CHILD_MAX; # else # if defined (MAXUPRC) maxchild = MAXUPRC; # endif /* MAXUPRC */ # endif /* CHILD_MAX */ #endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */ return (maxchild); }
set。ulimit(3) を使ったり setrlimit(2) を使ったり、いろいろ。
static int set_limit (ind, newlim, mode) int ind; RLIMTYPE newlim; int mode; { #if defined (HAVE_RESOURCE) struct rlimit limit; RLIMTYPE val; #endif if (limits[ind].parameter >= 256) switch (limits[ind].parameter) { case RLIMIT_FILESIZE: #if !defined (HAVE_RESOURCE) return (ulimit (2, newlim / 512L)); #else errno = EINVAL; return -1; #endif case RLIMIT_OPENFILES: #if defined (HAVE_SETDTABLESIZE) # if defined (__CYGWIN__) /* Grrr... Cygwin declares setdtablesize as void. */ setdtablesize (newlim); return 0; # else return (setdtablesize (newlim)); # endif #endif case RLIMIT_PIPESIZE: case RLIMIT_VIRTMEM: case RLIMIT_MAXUPROC: default: errno = EINVAL; return -1; } else { #if defined (HAVE_RESOURCE) if (getrlimit (limits[ind].parameter, &limit) < 0) return -1; # if defined (HPUX9) if (limits[ind].parameter == RLIMIT_FILESIZE) newlim /= 512; /* Ugh. */ # endif /* HPUX9 */ val = (current_user.euid != 0 && newlim == RLIM_INFINITY && (mode & LIMIT_HARD) == 0 && /* XXX -- test */ (limit.rlim_cur <= limit.rlim_max)) ? limit.rlim_max : newlim; if (mode & LIMIT_SOFT) limit.rlim_cur = val; if (mode & LIMIT_HARD) limit.rlim_max = val; return (setrlimit (limits[ind].parameter, &limit)); #else errno = EINVAL; return -1; #endif } }
非常に素朴な疑問なのだが、なぜ ulimit はシェル組み込みコマンドなのだろう?
ulimitについて(2)
http://d.hatena.ne.jp/parasporospa/20070414
bash の ulimit と getrlimit のシンボルの対応
static RESOURCE_LIMITS limits[] = { #ifdef RLIMIT_PTHREAD { 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL }, #endif #ifdef RLIMIT_SBSIZE { 'b', RLIMIT_SBSIZE, 1, "socket buffer size", "bytes" }, #endif #ifdef RLIMIT_CORE { 'c', RLIMIT_CORE, POSIXBLK, "core file size", "blocks" }, #endif #ifdef RLIMIT_DATA { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" }, #endif #ifdef RLIMIT_NICE { 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL }, #endif { 'f', RLIMIT_FILESIZE, POSIXBLK, "file size", "blocks" }, #ifdef RLIMIT_SIGPENDING { 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL }, #endif #ifdef RLIMIT_MEMLOCK { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" }, #endif #ifdef RLIMIT_RSS { 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" }, #endif /* RLIMIT_RSS */ { 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL}, { 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" }, #ifdef RLIMIT_MSGQUEUE { 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" }, #endif #ifdef RLIMIT_RTPRIO { 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL }, #endif #ifdef RLIMIT_STACK { 's', RLIMIT_STACK, 1024, "stack size", "kbytes" }, #endif #ifdef RLIMIT_CPU { 't', RLIMIT_CPU, 1, "cpu time", "seconds" }, #endif /* RLIMIT_CPU */ { 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL }, #if defined (HAVE_RESOURCE) { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" }, #endif #ifdef RLIMIT_SWAP { 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" }, #endif #ifdef RLIMIT_LOCKS { 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL }, #endif { -1, -1, -1, (char *)NULL, (char *)NULL } };
#if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE) # define RLIMIT_NOFILE RLIMIT_OFILE #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */ /* Some systems have these, some do not. */ #ifdef RLIMIT_FSIZE # define RLIMIT_FILESIZE RLIMIT_FSIZE #else # define RLIMIT_FILESIZE 256 #endif #define RLIMIT_PIPESIZE 257 #ifdef RLIMIT_NOFILE # define RLIMIT_OPENFILES RLIMIT_NOFILE #else # define RLIMIT_OPENFILES 258 #endif #ifdef RLIMIT_VMEM # define RLIMIT_VIRTMEM RLIMIT_VMEM # define RLIMIT_VMBLKSZ 1024 #else # ifdef RLIMIT_AS # define RLIMIT_VIRTMEM RLIMIT_AS # define RLIMIT_VMBLKSZ 1024 # else # define RLIMIT_VIRTMEM 259 # define RLIMIT_VMBLKSZ 1 # endif #endif #ifdef RLIMIT_NPROC # define RLIMIT_MAXUPROC RLIMIT_NPROC #else # define RLIMIT_MAXUPROC 260 #endif #if !defined (RLIM_INFINITY) # define RLIM_INFINITY 0x7fffffff #endif #if !defined (RLIM_SAVED_CUR) # define RLIM_SAVED_CUR RLIM_INFINITY #endif #if !defined (RLIM_SAVED_MAX) # define RLIM_SAVED_MAX RLIM_INFINITY #endif