内核文件句柄数量

涉及三个文件file-max,file-nr和nr-open。

file-max

file-max定义了Linux内核可分配的最大数量的文件句柄,当检测到文件句柄耗尽时,需要增加file-max值。

/ # cat /proc/sys/fs/file-max
1597700

内核函数files_maxfiles_init计算系统默认的最大文件数量,依据是每个文件及与其关联的inode和dcache结构,总的大小约为1K。默认文件占用的空间不超出内存的10%,file-max的最小值为NR_FILE,即8192个。

void __init files_maxfiles_init(void)
{
    unsigned long n;
    unsigned long memreserve = (totalram_pages - nr_free_pages()) * 3/2;

    memreserve = min(memreserve, totalram_pages - 1);
    n = ((totalram_pages - memreserve) * (PAGE_SIZE / 1024)) / 10;

    files_stat.max_files = max_t(unsigned long, n, NR_FILE);
}

#define NR_FILE  8192   /* this can well be larger on a larger system */

在内核的文件分配函数中,调用alloc_empty_file判断当前打开的文件数量是否已经超出限定的最大文件数量(files_stat.max_files),将会显示信息:“VFS: file-max limit %lu reached”。

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);

如下函数get_max_files用于获取内核设置的最大文件数量。

/* Return the maximum number of open files in the system
 */
unsigned long get_max_files(void)
{
    return files_stat.max_files;
}

file-nr

历史上,内核可以动态的分配文件句柄,但是不能进行释放。file-nr文件中的三个值分别表示:分配的文件句柄数量,已分配但是未使用的句柄数量,以及最大的文件句柄数量。在内核版本2.6之后,第二个值总是为零,意味着分配的文件句柄数量与使用的句柄数量完全相同。

/ # cat /proc/sys/fs/file-nr
20160   0       1597700

nr_open

nr_open表示单个进程可分配的文件句柄数量,默认值为:1024*1024 (1048576)。实际的数量还受到RLIMIT_NOFILE定义的资源项限制。

/ # cat /proc/sys/fs/nr_open
1048576

如下,将文件数量限制在1024。

$ ulimit -a
open files                      (-n) 1024

在内核文件fs/file.c中,将nr_open默认为:1024*1024。

unsigned int sysctl_nr_open __read_mostly = 1024*1024;

内核版本 5.0

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页