一切皆文件
在 Linux 中,一切皆文件。许多操作,比如文件打开、进程创建、管道创建、新的网络连接创建,甚至计时器创建(timerfd _ create)和事件生成(eventfd) ,都会增加 nr_files
file-max
file-max定义了系统级别的、所有进程的打开文件限制
This file defines a system-wide limit on the number of
open files for all processes. System calls that fail when
encountering this limit fail with the error ENFILE. (See
also setrlimit(2), which can be used by a process to set
the per-process limit, RLIMIT_NOFILE, on the number of
files it may open.) If you get lots of error messages in
the kernel log about running out of file handles (open
file descriptions) (look for "VFS: file-max limit <number>
reached"), try increasing this value:
echo 100000 > /proc/sys/fs/file-max
Privileged processes (CAP_SYS_ADMIN) can override the
file-max limit.
查看目前的file-max限制:
$ cat /proc/sys/fs/file-max
394568
file-nr
/proc/sys/fs/file-nr是个只读文件,三个输出分别表示已经分配的文件描述符数、已经分配但未使用的文件描述符数、文件描述符数最大值
$ cat /proc/sys/fs/file-nr
11616 0 394568
/proc/sys/fs/file-nr
This (read-only) file contains three numbers: the number
of allocated file handles (i.e., the number of open file
descriptions; see open(2)); the number of free file
handles; and the maximum number of file handles (i.e., the
same value as /proc/sys/fs/file-max). If the number of
allocated file handles is close to the maximum, you should
consider increasing the maximum. Before Linux 2.6, the
kernel allocated file handles dynamically, but it didn't
free them again. Instead the free file handles were kept
in a list for reallocation; the "free file handles" value
indicates the size of that list. A large number of free
file handles indicates that there was a past peak in the
usage of open file handles. Since Linux 2.6, the kernel
does deallocate freed file handles, and the "free file
handles" value is always zero.
nr_open
单个进程打开文件数的最大值
/proc/sys/fs/nr_open (since Linux 2.6.25)
This file imposes a ceiling on the value to which the
RLIMIT_NOFILE resource limit can be raised (see
getrlimit(2)). This ceiling is enforced for both
unprivileged and privileged process. The default value in
this file is 1048576. (Before Linux 2.6.25, the ceiling
for RLIMIT_NOFILE was hard-coded to the same value.)
$ cat /proc/sys/fs/nr_open
1048576
函数调用链分析
- get_nr_files函数返回当前的nr_files值
- alloc_empty_file在分配file结构体之前,会进行检查,判断当前nr_file值是否大于最大值files_stat.max_files
- 如果已经超过了最大值,那么会输出:
"VFS: file-max limit %lu reached\n"
get_nr_files函数
static long get_nr_files(void)
{
return percpu_counter_read_positive(&nr_files);
}
alloc_empty_file函数
struct file *alloc_empty_file(int flags, const struct cred *cred)
{
static long old_max;
struct file *f;
/* Privileged users can go above max_files
*/
if (get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) {
/* percpu_counters are inaccurate. Do an expensive check before we go and fail. */
if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files)
goto over;
}
f = __alloc_file(flags, cred);
if (!IS_ERR(f)) percpu_counter_inc(&nr_files);
return f;
over:
/* Ran out of filps - report that */
if (get_nr_files() > old_max) {
pr_info("VFS: file-max limit %lu reached\n", get_max_files());
old_max = get_nr_files();
}
return ERR_PTR(-ENFILE);
}