NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/60600: ldconfig should not default to "YES", because the presence of a.out shlibs is vanishingly rare



>Number:         60600
>Category:       bin
>Synopsis:       ldconfig should not default to "YES", because the presence of a.out shlibs is vanishingly rare
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Aug 15 17:00:01 +0000 2026
>Originator:     Jason Thorpe
>Release:        NetBSD 11.99.7
>Organization:
Retrogrouches'R'Us
>Environment:
Any slow-ish historically a.out machine will suffice
>Description:
On platforms that previously had a.out shared libraries, ldconfig(8) is run at boot time i order to update the a.out shared library hints file.  While I'm sure this is well-intentioned, any system installed in the last 20 years almost certainly does not have a.out shared libraries lingering around, and so whatever work ldconfig(8) does is entirely frivilous and serves no purpose.

The assertion was made in passing that "it's supposed to be fast", and while that might be true on some machines, it's not necessarily true on others.  ldconfig(8) ends up doing a fair amount of I/O.  It scans directories for files matching the pattern "lib*.so.*" (this matching is open-coded, achieved by matching substrings), and then for each file matching that pattern, it opens it, and reads the first small bit of it looking for a ZMAGIC a.out header with the EX_DYNAMIC bit set.

On a fresh NetBSD/hb68k install, there are 408 files that match the "lib*.so.*" pattern in /usr/lib, which is a directory that is consulted by default by ldconfig(8).  So, for a fresh system with no a.out shared libraries, ldconfig(8) will open 408 files and read an a.out header from each, only to not find what it's looking for.

Exactly half of those files are symlinks, e.g. libskey.so.2 -> libskey.so.2.0.  So exactly half of these opens/reads are completely redundant.

Now let's consider the cost of the I/O.  Half of those 408 reads will hit the buffer cache (because of the symlinks), so it's not entirely all bad news.  And a small handful of them may also hit the buffer cache due to the (ELF) shared libraries already being in-use during boot.  However, there are a significant number of them that won't be in use during boot, and this means real I/O costs that have to be paid.

Even though the ldconfig(8) program only reads an a.out header, of course the file system is going to bring in more data than that.  It will, at mininum, bring in one PAGE_SIZE chunk of data, which in this example is going to be 4KB.

The wrap030 system has a PIO-only ATA disk interface, and it's not uncommon for these sorts of systems to be used with CompactFlash type devices.  CF devices often support only single-sector PIO transfers, so that 4KB page turns into 8 individual 512-byte PIO reads.

Assuming that 200 of the library checks result in a buffer cache miss, that's 1600 single-sector PIO reads in total.  This is, as you might imagine, not fast on a 25MHz 68030.

>How-To-Repeat:
Boot an I/O-constrained m68k system.
>Fix:
The "ldconfig" setting in /etc/defaults/rc.conf should default to NO.  People who want/need to pay this cost can do so by setting it to YES in /etc/rc.conf.




Home | Main Index | Thread Index | Old Index