I always thought that RLIMIT_NOFILE limits the number of open files, but when I read the code for alloc_fd(), I found that RLIMIT_NOFILE is the largest fd index? Is this a mistake in my understanding, or is it a code implementation error? ----- alloc_fd code: diff --git a/fs/file.c b/fs/file.c index fb1011c..e47ddac 100644 --- a/fs/file.c +++ b/fs/file.c @@ -561,6 +561,7 @@ static int alloc_fd(unsigned start, unsigned end, unsigned flags) */ error = -EMFILE; if (unlikely(fd >= end)) + // There may be unclosed fd between [end, max]. the number of open files can be greater than RLIMIT_NOFILE. goto out; if (unlikely(fd >= fdt->max_fds)) { ----- Test Procedure 1. ulimit -n 1024. 2. Create 1000 FDs. 3. ulimit -n 100. 4. Close all FDs less than 100 and continue to hold FDs greater than 100. 5. Open() and check whether the FD is successfully created, If RLIMIT_NOFILE is the upper limit of the number of opened files, step 5 should fail, but step 5 returns success. ----- test code: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/resource.h> #include <errno.h> int main(int argc, char *argv[]) { int fd, i; struct rlimit rl; rl.rlim_cur = 1024; rl.rlim_max = 1024; if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { perror("setrlimit"); exit(EXIT_FAILURE); } for (i = 0; i < 1000; i++) { fd = open("/dev/null", O_RDWR | O_CLOEXEC); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } } rl.rlim_cur = 100; rl.rlim_max = 100; if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { perror("setrlimit"); exit(EXIT_FAILURE); } for (i = 3; i < 100; i++) { close(i); } fd = open("/dev/null", O_RDWR | O_CLOEXEC); if (fd == -1) { if (errno == EMFILE) { printf("ok\n"); return 0; } else { perror("open"); exit(EXIT_FAILURE); } } else { printf("fail: {OPEN_MAX} file descriptors are currently open in the calling process, but open() still returns a success\n"); return -1; } return 0; } ---- Best regards, Xiaoming Ni