Linux最大打开文件数

在做pcap文件根据四元组(src_ip、src_port、dst_ip、dst_port)拆分为多个包的小批量测试验证时,发现打出了很多的报错:pcap_dump_open error,一头黑线…

挖坑与填坑

OS: Ubuntu 16.04

man了一下,看了看pcap_dump_open()的使用方法和代码上下文,没发现有什么问题。

1
2
#include <pcap/pcap.h>
pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname);

pcap_dump_open() is called to open a ``savefile’’ for writing. fname specifies the name of the file to open. The file will have the same format as those used by tcpdump(1) and tcpslice(1). The name “-“ is a synonym for stdout.

那么,看一下报错时的四元组是哪些,在pcap_dump_open报错前增加一行代码,Wireshark观察了一下,保存失败的四元组,和已经拆分并保存成功的pcap文件没什么不同。再次执行了一遍代码,仍然出现了pcap_dump_open error,但是,和上一次运行报错信息中显示的四元组信息不完全一致👀,这神奇的现象…

静下来思考了一下,保存失败,两次结果不同,是不是因为文件操作上的问题,想到了在读APUE时,有讲过最大打开文件数,难道是达到了最大打开文件数限制导致的?
于是:

1
2
$ ulimit -n
1024

临时将值修改一下:

1
2
3
$ ulimit -n 10000
$ ulimit -n
10000

此时,再次运行代码,没有报错,拆分后的文件数目与Wireshark中Conversations中计数和一致。

最大打开文件数

使用ulimit命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ 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) 15512
max locked memory (kbytes, -l) 16384
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) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 15512
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

其中的open files值就是Linux操作系统在用户级别对一个进程打开的文件句柄数量的限制, 在代码中可以通过sysconf()函数获取,比如最大打开文件数,使用sysconf(_SC_OPEN_MAX)即可。

如果想永久修改ulimit的值,需要进行如下操作,重启机器后生效:

1
2
3
4
echo "* soft nofile 65535"  >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf
echo "root soft nofile 65535" >> /etc/security/limits.conf
echo "root hard nofile 65535" >> /etc/security/limits.conf

当通过GUI登录并调整open files的值时,会遇到如下问题,因为limit.conf的配置没有应用到图形界面中:

1
2
$ ulimit -n 10000
bash: ulimit: open files: cannot modify limit: Operation not permitted

此时需要在/etc/systemd/user.conf/etc/systemd/system.conf中增加一行:

1
DefaultLimitNOFILE=65535

问题到此完全解决,看似神奇的现象其实并不神奇😝

CentOS7上的问题

在Centos7系统中使用Systemd替代了之前的SysV。/etc/security/limits.conf文件的配置作用域缩小了,只适用于通过PAM认证登录用户的资源限制,它对systemd的service的资源限制不生效。因此登录用户的限制,通过/etc/security/limits.conf/etc/security/limits.d下的文件设置即可。对于systemd service的资源设置,则需修改全局配置,全局配置文件放在/etc/systemd/system.conf/etc/systemd/user.conf,同时也会加载两个对应目录中的所有.conf文件/etc/systemd/system.conf.d/*.conf/etc/systemd/user.conf.d/*.conf。修改了system.conf后,需要重启系统才会生效。

1
2
3
$ vim /etc/systemd/system.conf
DefaultLimitNOFILE=100000
DefaultLimitNPROC=65535

参考

1、https://superuser.com/questions/1200539/cannot-increase-open-file-limit-past-4096-ubuntu
2、http://smilejay.com/2016/06/centos-7-systemd-conf-limits/

0%