In an arm32 image-based container, readdir returns EOVERFLOW when directory is empty

Viewed 165

Upon calling readdir function in a C program within an arm32-based container executing on x64-based Ubuntu 19.10 host, the call returns EOVERFLOW for empty directories (e.g., /mnt, /media) instead of returning 0.

Have others observed this issue? Is this a configuration issue? If so, how can it be fixed?

Versions:

  • Guest: debian:buster- backports@sha256:8f27850df2144df1598b5c76b213616ecaab08e804a6d84ddace1455d8cbd9f0
  • Host: Ubuntu 19.10, amd64, Docker version: 19.03.6-0ubuntu1~19.10.1
  • Qemu version: 1:4.0+dfsg-0ubuntu9.6

Repro steps:

  • Build an image named crystal-for-buster-armhf:v1 based on Debian Buster for arm32 using the Dockerfile and build.sh script available here.
  • Start a container based on this image.
  • Compile and build the below program.
  • Execute the resulting executable with a directory name as a command line argument.
#define _POSIX_SOURCE
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#undef _POSIX_SOURCE
#include <stdio.h>

main(int argc, char* argv[]) {
  DIR *dir;
  struct dirent *entry;

  if ((dir = opendir(argv[1])) == NULL)
    perror("opendir() error");
  else {
    puts("contents:");
    while (1) {
      errno = 0;
      entry = readdir(dir);
      if (entry == NULL) {
        printf("Errno: %d   EOVERFLOW: %d\n", errno, EOVERFLOW);
        break;
      }
      printf("  %s\n", entry->d_name);
    }
    closedir(dir);
  }
}
1 Answers

If you're using glibc (most Linux-based systems), you need to compile with -D_FILE_OFFSET_BITS=64. The default is still 32-bit off_t, and with it 32-bit ino_t, and in such a configuration, readdir, stat, etc. will fail with EOVERFLOW if the inode number does not fit in 32 bits. Many modern filesystems always have inode numbers that don't fit in 32 bits.

Related