setrlimitシステムコール(オープンファイル数)
Rev.1を表示中。最新版はこちら。
プロセスの取得できるファイルIDはtsk->signal->rlim[RLIMIT_NOFILE]->rlim_curまでで、setrlimitシステムコールで最大tsk->signal->rlim[RLIMIT_NOFILE]->rlim_maxまでの範囲で設定できます。、CAP_SYS_RESOURCEを有してないならtsk->signal->rlim[RLIMIT_NOFILE]->rlim_max超えるrlim_maxを設定できません。子プロセスは親のtsk->signal->rlimを継承しrootプロセスのrlim_maxがシステムとしてデフォルト値となります。sysctl_nr_openは全プロセスに反映され、rlim_max<sysctl_nr_openとされ、全プロセスに対しての取得ファイルID制限値となります。
#define RLIMIT_CPU 0 /* CPU time in sec */ #define RLIMIT_FSIZE 1 /* Maximum filesize */ #define RLIMIT_DATA 2 /* max data size */ #define RLIMIT_STACK 3 /* max stack size */ #define RLIMIT_CORE 4 /* max core file size */ #ifndef RLIMIT_RSS # define RLIMIT_RSS 5 /* max resident set size */ #endif #ifndef RLIMIT_NPROC # define RLIMIT_NPROC 6 /* max number of processes */ #endif #ifndef RLIMIT_NOFILE # define RLIMIT_NOFILE 7 /* max number of open files */ #endif #ifndef RLIMIT_MEMLOCK # define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #endif #ifndef RLIMIT_AS # define RLIMIT_AS 9 /* address space limit */ #endif #define RLIMIT_LOCKS 10 /* maximum file locks held */ #define RLIMIT_SIGPENDING 11 /* max number of pending signals */ #define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */ #define RLIMIT_NICE 13 /* max nice prio allowed to raise to 0-39 for nice level 19 .. -20 */ #define RLIMIT_RTPRIO 14 /* maximum realtime priority */ #define RLIMIT_RTTIME 15 /* timeout for RT tasks in us */ #define RLIM_NLIMITS 16 struct rlimit { unsigned long rlim_cur; unsigned long rlim_max; }; SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) { struct rlimit new_rlim; if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) return -EFAULT; return do_prlimit(current, resource, &new_rlim, NULL); } int do_prlimit(struct task_struct *tsk, unsigned int resource, struct rlimit *new_rlim, struct rlimit *old_rlim) { struct rlimit *rlim; int retval = 0; if (resource >= RLIM_NLIMITS) return -EINVAL; if (new_rlim) { if (new_rlim->rlim_cur > new_rlim->rlim_max) return -EINVAL; if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open) return -EPERM; } read_lock(&tasklist_lock); if (!tsk->sighand) { retval = -ESRCH; goto out; } rlim = tsk->signal->rlim + resource; task_lock(tsk->group_leader); if (new_rlim) { if (new_rlim->rlim_max > rlim->rlim_max && !capable(CAP_SYS_RESOURCE)) retval = -EPERM; if (!retval) retval = security_task_setrlimit(tsk->group_leader, resource, new_rlim); if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) { new_rlim->rlim_cur = 1; } } if (!retval) { if (old_rlim) *old_rlim = *rlim; if (new_rlim) *rlim = *new_rlim; } task_unlock(tsk->group_leader); if (!retval && new_rlim && resource == RLIMIT_CPU && new_rlim->rlim_cur != RLIM_INFINITY) update_rlimit_cpu(tsk, new_rlim->rlim_cur); out: read_unlock(&tasklist_lock); return retval; }
補足
[root@localhost ~]# cat /proc/self/limits | grep files Max open files 1024 4096 files #define INR_OPEN_CUR 1024 /* Initial setting for nfile rlimits */ #define INR_OPEN_MAX 4096 /* Hard limit for nfile rlimits */ init_task.signal->rlim[RLIMIT_NOFILE]->rlim_cur=1024/init_task.signal->rlim[RLIMIT_NOFILE]->rlim_cur=4096
[root@localhost ~]# cat /proc/sys/fs/nr_open 1048576 int sysctl_nr_open __read_mostly = 1024*1024; int sysctl_nr_open_min = BITS_PER_LONG; int sysctl_nr_open_max = 1024 * 1024; static struct ctl_table fs_table[] = { : { .procname = "nr_open", .data = &sysctl_nr_open, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = &sysctl_nr_open_min, .extra2 = &sysctl_nr_open_max, }, : }