Home > database >  Calculate max open files in Linux
Calculate max open files in Linux

Time:02-22

I wrote a simple program to test the max open files per process in Linux. Here it is.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main() {

    FILE* fp = NULL;
    int count = 0;
    
    while (1) {
        fp = fopen("tmp", "w");
        if (fp == NULL) {
            perror("fopen()");
            break;
        }
        count  ;
    }
    printf("count:%d\n", count);
    return 0;    
}

The output of the program on my computer is

$ ./maxfopen
fopen(): Too many open files
count:1020

I used ulimit -a to check the max open files on my computer, and the result is 1024. As expected, apart from stdio, stdout, stderr, there should have been 1021 files, which are available to open, but the result is 1020 on my computer. What is wrong? Is there a fourth default open file stream? How can I detect it?

CodePudding user response:

you can check the opened files with strace:

$ strace ./maxfopen 2>&1 | grep AT_FDCWD | wc -l
1024
$ strace ./maxfopen 2>&1 | grep AT_FDCWD                                                                                                                                                                              
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3                                                                                                                                                      
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3                                                                                                                                       
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3                                                                                                                                                       
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4                                                                                                                                                       
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 5    
...
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1018
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1019
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1020
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1021
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1022
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1023
openat(AT_FDCWD, "tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 EMFILE (Too many open files)

The sum of all files should be (1021 stdin stdout stderr). If it is not is because other file is being opened before main function which can be checked with strace as well.

Other files opened (and closed) are /etc/ld.so.cache and /lib/x86_64-linux-gnu/libc.so.6 (the dynamic linker to run the program)

you can verify it looking the file descriptors in: /proc/<pid>/fd

CodePudding user response:

It could be used by your shell or the program for some other purpose. To find out exactly what's the "missing" fd is being used for, you can simply wait before exit and inspect /proc/<pid>/fd.

For example, add a getchar() and check /proc/<pid>/fd in another terminal.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main() {

    FILE* fp = NULL;
    int count = 0;
    
    while (1) {
        fp = fopen("tmp", "w");
        if (fp == NULL) {
            perror("fopen()");
            break;
        }
        printf("%d\n", fileno(fp)); // shows each fd number
        count  ;
    }
    getchar(); // just to keep it running
    printf("count:%d\n", count);
    return 0;    
}

Since the fd's aren't closed, they should be pointing to the files/devices they refer to.

fileno(fp) (see the code above) will also give the fd number of the file descriptor. So you can check what's the "missing" fd using that too.

  • Related