Roland Mainz wrote:
> Hi!
> 
> ----
> 
> Why is |resolvepath()| called in the "truss" sample below:
> -- snip --
> stat64("/usr/lib/libast.so.1", 0xFFBFEF80)      = 0
> resolvepath("/usr/lib/libast.so.1", "/usr/lib/libast.so.1", 1023) = 20
> open("/usr/lib/libast.so.1", O_RDONLY)          = 3
> mmapobj(3, 0x00020000, 0xFF3F7A48, 0xFFBFF014, 0x00000000) = 0
> close(3)
> -- snip --
> 
> Wouldn't it be easier to just call |open()| directly ?
> 
> ----
> 
> Bye,
> Roland
> 
> P.S.: Why doesn't the code just do an |open()| for each library
> _directory_ and then do a |statat()| and |openat()| using the returned
> file descriptor ? AFAIK this would save some directory lookup time...
> 


I'm just speculating here --- the deeper answer lies in the source.

I think that there are there are some assumptions underlying this,
that the kernel caches recently accessed inodes, that open() is notably
more expensive than stat and resolvepath, and that ld.so does not end
up needing to open most of the files it stats.

ld.so can encounter the same file under more than one name, via symlinks
in the path or file, and via relative paths vs. fully qualified ones.
Since it only wants to map each such object once, and because it needs
to refer to it using a single fully qualified path, resolvepath() is
used to canonify the path and compare it to what's already loaded before
opening it.

I don't know whether openat() would be faster, I suppose it depends on
level of "recently accessed inode" caching the kernel does. As the ld.so code
predates openat(), I suspect that this is an experiment that simply hasn't
been done, probably because this hasn't been seen as a hot spot.

- Ali


Reply via email to