ulimit 下的 limits.conf

ulimit 是用来控制 shell 启动进程所占的资源的工具。

常见的参数有如下的:

-a 显示当前所有的资源限制
-H 硬件资源限制,一但设置不能增加
-S 软件资源限制,可以增加,但不能超过 -H
-u 用户可使用的最大进程
-c core 文件的最大值
-d 数据段的最大值
-n 内核可以同时打开的文件描述符的最大值
-s 堆栈的最大值
-v 虚拟内存的最大值
-m 最大内存使用

通过 -a 就可以查看所有支持的资源数以及他们对应的参数:

# ulimit -a
core file size       (blocks, -c) 0
data seg size        (kbytes, -d) unlimited
scheduling priority          (-e) 0
file size            (blocks, -f) unlimited
pending signals              (-i) 4095
max locked memory    (kbytes, -l) 32
max memory size      (kbytes, -m) unlimited
open files                   (-n) 1024
pipe size         (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority           (-r) 0
stack size           (kbytes, -s) 10240
cpu time            (seconds, -t) unlimited
max user processes           (-u) 4095
virtual memory       (kbytes, -v) unlimited
file locks                   (-x) unlimited

而上面描述的参数在使用 -a 参数之后都可以找到。

ulimit 作用在当前 shell 的进程及其子进程下,也是说即使同一个用户,在一个 shell 上执行了 ulimit,新开的一个 shell 是不受影响的。可以在 /etc/security/limits.conf 下做修改来控制某一个具体的用户资源。比如下面这个就是可以让 jaseywang 这个用户创建的最大文件数为 100:

* hard nofile 100

在进行网络服务的时候,如果遇到大量并发的情况,比如使用 webbench 进行测试时,很多的 error log 里面就会显示出 can't open so many files 的信息。这样的情况同样可以通过设置 ulimit 解决。这个其实就是 -n 也就是可以打开的最大文件数的限制,默认只有 1024 个文件,可以将其写进上面的 limits.conf 文件中。

注意:上面两个将配置写到 limits.conf 的例子我验证下来并没有取得预期的效果,不管是对于 root 还是普通用户。所以最保险的做法还是将其写到 .bashrc 或者 rc.local。

对于 -n 这个 open files 选项,经过实践发现,在 limits.conf 里面必须将 hard 以及 soft 形式的写全,也就是像下面这样:

* soft nofile 10000
* hard nofile 20000

上面的 soft/hard 缺少任何一个都不会使 limits.conf 下的这对值生效。

而将 ulimit -n 11111 的写进到 /etc/bashrc 文件下对于 root 是可以生效的,但是对于普通用户登陆时会产生 “Operation not permitted” 的权限文件,写进 .bashrc 会产生同样的问题。而将其写到 /etc/rc.local 下重启后没有任何作用!

验证 ulimit 生效的最佳方法是看 /proc/ 目录下也就是内核中相应进程的 limits:

# for pid in `ps aux | grep nginx | grep -v grep  | awk '{print $2}'`; do cat /proc/${pid}/limits | grep 'open files';done

上面是针对 nginx 这个用户来看的,如果验证本用户可以打开的最大文件数,可以执行:

# w
获得当前的 tty 值

# ps axu  |grep pts/0
获取对应 pts/0 的 pid

# cat /proc/pid/limits

这里有一篇限制用户进程数的文章,可以防止 fork 炸弹的攻击,修改方法同上,只不过将 nofile 修改为 nproc;或者通过 ulimit -u 32 之类的直接修改。

在 -a 显示出来的信息中,有一个 file size 的信息,默认是 unlimited,也就是不受限制,如果将其设置为 100,那么允许创建的最大文件就变成了 51B。   

还有几个开发中可能用到的,开启 core dump

# ulimit -c unlimited

使用 -a 或者我上面提到的方法确认:

# ulimit -c
unlimited

在Linux下写程序的时候,如果程序比较大,经常会遇到“段错误”(segmentation fault)这样的问题,这主要就是由于系统初始的堆栈大小(stack size)太小的缘故,通过 -s 参数修改:

# ulimit   -s 262140

上述的所有命令在当前会话下有效,会话结束就失效。如果要长期使用,可以将其加到 limits.conf 文件中。

至于 /proc/sys/fs/file-max 以及 file-nr 跟上面的没有必然的关系。

参考:
http://www.ibm.com/developerworks/cn/linux/l-cn-ulimit/