プロセスのオープンファイル数
Rev.2を表示中。最新版はこちら。
プロセスのオープンできるファイル数は、標準入力/出力/エラーを含めて、デフォルトで1024で、setrlimit(RLIMIT_NOFILE)でtask limitのrlim_curを設定することで増減できます。設定できる値は、rlim_max以下で、またrlim_maxは/proc/sys/fs/nr_open以下でなければいけません。検証サンプル
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <sys/resource.h> void opens() { long fd, fd1; long i = 0; while (1) { fd = open("tmp", O_CREAT | O_RDWR); if (fd > 0) { i++; fd1 = fd; } else { printf("file CNT=%4ld file ID=%4ld\n", --i, fd1); break; } } } void show_no_file() { struct rlimit rl; getrlimit(RLIMIT_NOFILE, &rl); printf("cred cur=%4d max=%4d\n", rl.rlim_cur, rl.rlim_max); } void set_no_file(long nofile) { struct rlimit rl; int ret; getrlimit(RLIMIT_NOFILE, &rl); rl.rlim_cur = nofile; ret = setrlimit(RLIMIT_NOFILE, &rl); if (ret) { printf("setrlimit:%s\n", strerror(errno)); } } void main(int argc, char *argv[]) { if (argc == 2) { set_no_file(atol(argv[1])); show_no_file(); opens(); } else { show_no_file(); opens(); } }検証結果
[root@localhost test]# cat /proc/sys/fs/nr_open 1048576 [root@localhost test]# ./open_max cred cur=1024 max=4096 file CNT=1020 file ID=1023 [root@localhost test]# ./open_max 2000 cred cur=2000 max=4096 file CNT=1996 file ID=1999 [root@localhost test]# ./open_max 4097 setrlimit:Invalid argument cred cur=1024 max=4096 file CNT=1020 file ID=1023rlim_max=4096、/proc/sys/fs/nr_open=2048故、setrlimit()はエラーになります。
[root@localhost test]# echo 2048 > /proc/sys/fs/nr_open [root@localhost test]# ./open_max 100 setrlimit:Operation not permitted cred cur=1024 max=4096 file CNT=1020 file ID=1023
補足
/proc/sys/fs/nr_openはsetrlimit(RLIMIT_CPU)の設定条件と言うのでなく、FILE IDを設定する動的な拡張領域の上限値として機能します。この設定する領域の拡張は、2のべき乗単位で丸められ、設定値は2のべき乗値とするのが、無駄なメモリ割り当てを回避できます。ファイルIDはstruct file * current->files->fdt->fd[]のインデックスで、取得したIDは、unsigned long *current->files->fdt->open_fds->fds_bits[]でビット単位で管理されます。その最大値がcurrent->files->fdt->max_fdsで、初期値のinit taskはBITS_PER_LONG、プロセスはBITS_PER_LONG*8となっています。
task limitは以下の通りです。
#define RLIM_NLIMITS 16 #define RLIMIT_NOFILE 7 struct rlimit { unsigned long rlim_cur; unsigned long rlim_max; }; struct rlimit current->signal->rlim[RLIM_NLIMITS];