While compiling glibc in a 32-bit environment (hppa architecture, 32-bit userspace, but 64-bit kernel, glibc target is 32-bit as well) I see lots of failures with iconv like this one: /build/glibc/glibc-2.34/build-tree/hppa-libc/iconv/iconv_prog: failed to start conversion processing I traced it with strace: 3438821 openat(AT_FDCWD,"/build/glibc/glibc-2.34/build-tree/hppa-libc/iconvdata/gconv-modules",O_RDONLY|O_CLOEXEC) = 3 3438821 statx(3,"",AT_EMPTY_PATH|AT_NO_AUTOMOUNT,STATX_BASIC_STATS,0xf50013c8) = 0 3438821 read(3,0xfa034678,4096) = 3808 3438821 read(3,0xfa034678,4096) = 0 3438821 close(3) = 0 3438821 openat(AT_FDCWD,"/build/glibc/glibc-2.34/build-tree/hppa-libc/iconvdata/gconv-modules.d",O_RDONLY|O_DIRECTORY|O_LARGEFILE|O_NONBLOCK|O_CLOEXEC) = 3 3438821 statx(3,"",AT_EMPTY_PATH|AT_NO_AUTOMOUNT,STATX_BASIC_STATS,0xf5001148) = 0 3438821 getdents64(3,-100439584,32768,99,8,0) = 96 3438821 close(3) = 0 This part comes from gconv_parseconfdir() in conv/gconv_parseconfdir.h: /* Read the gconv-modules configuration file first. */ found = read_conf_file (buf, dir, dir_len); /* Next, see if there is a gconv-modules.d directory containing configuration files and if it is non-empty. */ cp--; cp[0] = '.'; cp[1] = 'd'; cp[2] = '\0'; DIR *confdir = opendir (buf); if (confdir != NULL) { struct dirent *ent; while ((ent = readdir (confdir)) != NULL) as can be seen, readdir() is called and the syscall returns 96 bytes for getdents64(), but the "ent" variable nevertheless gets NULL and returns without reading the "gconv-modules-extra.conf" file. Finally it turns out, that this is a problem of missing large file support while scanning the contents of the gconv-modules.d/ directory. In my build environment the /build/glibc/glibc-2.34/build-tree/hppa-libc/iconvdata/gconv-modules.d/gconv-modules-extra.conf file is located on-disk on a high inode, thus the readdir() function returns NULL. I manually changed the code above to use the 64-bit variants to become: struct dirent64 *ent; while ((ent = readdir64 (confdir)) != NULL) which then worked. So finally, I'd suggest to enable 64-bit file-support for this specific function. Either by manually using the 64-bit variants, or by compiling with -D_LARGE_FILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 (whatever is possible and makes sense).
Patch posted: [PATCH] gconv: Use 64-bit interfaces in gconv_parseconfdir (bug 29583) <https://sourceware.org/pipermail/libc-alpha/2022-September/142060.html>
Fixed for 2.37 via: commit f97905f24631097af325d6a231093071c3077a5f Author: Florian Weimer <fweimer@redhat.com> Date: Tue Sep 20 12:12:43 2022 +0200 gconv: Use 64-bit interfaces in gconv_parseconfdir (bug 29583) It's possible that inode numbers are outside the 32-bit range. The existing code only handles the in-libc case correctly, and still uses the legacy interfaces when building iconv. Suggested-by: Helge Deller <deller@gmx.de> Please let us know if we should backport this anywhere.
On 9/20/22 12:13, fweimer at redhat dot com wrote: > https://sourceware.org/bugzilla/show_bug.cgi?id=29583 > > Florian Weimer <fweimer at redhat dot com> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > Resolution|--- |FIXED > Target Milestone|--- |2.37 > Status|ASSIGNED |RESOLVED > > --- Comment #2 from Florian Weimer <fweimer at redhat dot com> --- > Fixed for 2.37 via: > > commit f97905f24631097af325d6a231093071c3077a5f > Author: Florian Weimer <fweimer@redhat.com> > Date: Tue Sep 20 12:12:43 2022 +0200 > > gconv: Use 64-bit interfaces in gconv_parseconfdir (bug 29583) > > It's possible that inode numbers are outside the 32-bit range. > The existing code only handles the in-libc case correctly, and > still uses the legacy interfaces when building iconv. > > Suggested-by: Helge Deller <deller@gmx.de> > > Please let us know if we should backport this anywhere. Yes, could you please backport it to 2.34+ ? I'm running on Debian/unstable and it has 2.34. Thanks, Helge
(In reply to Helge Deller from comment #3) > Yes, could you please backport it to 2.34+ ? > I'm running on Debian/unstable and it has 2.34. Fair enough, backported to 2.34 and later.