@@ -37,6 +37,15 @@ const (
3737 // higher precedence than other libraries on the system, but lower than
3838 // the 00-cuda-compat that is included in some containers.
3939 ldsoconfdFilenamePattern = "00-nvcr-*.conf"
40+ // defaultTopLevelLdsoconfFilePath is the standard location of the top-level ld.so.conf file.
41+ // Most container images based on a distro will have this file, but distroless container images
42+ // may not.
43+ defaultTopLevelLdsoconfFilePath = "/etc/ld.so.conf"
44+ // defaultLdsoconfdDir is the standard location for the ld.so.conf.d drop-in directory. Most
45+ // container images based on a distro will have this directory included by the top-level
46+ // ld.so.conf file, but some may not. And some container images may not have a top-level
47+ // ld.so.conf file at all.
48+ defaultLdsoconfdDir = "/etc/ld.so.conf.d"
4049)
4150
4251type Ldconfig struct {
@@ -117,20 +126,22 @@ func (l *Ldconfig) UpdateLDCache() error {
117126
118127 // Explicitly specify using /etc/ld.so.conf since the host's ldconfig may
119128 // be configured to use a different config file by default.
120- const topLevelLdsoconfFilePath = "/etc/ld.so.conf"
121- filteredDirectories , err := l .filterDirectories (topLevelLdsoconfFilePath , l .directories ... )
129+ filteredDirectories , err := l .filterDirectories (defaultTopLevelLdsoconfFilePath , l .directories ... )
122130 if err != nil {
123131 return err
124132 }
125133
126134 args := []string {
127135 filepath .Base (ldconfigPath ),
128- "-f" , topLevelLdsoconfFilePath ,
136+ "-f" , defaultTopLevelLdsoconfFilePath ,
129137 "-C" , "/etc/ld.so.cache" ,
130138 }
131139
132- if err := createLdsoconfdFile (ldsoconfdFilenamePattern , filteredDirectories ... ); err != nil {
133- return fmt .Errorf ("failed to update ld.so.conf.d: %w" , err )
140+ if err := ensureLdsoconfFile (defaultTopLevelLdsoconfFilePath , defaultLdsoconfdDir ); err != nil {
141+ return fmt .Errorf ("failed to ensure ld.so.conf file: %w" , err )
142+ }
143+ if err := createLdsoconfdFile (defaultLdsoconfdDir , ldsoconfdFilenamePattern , filteredDirectories ... ); err != nil {
144+ return fmt .Errorf ("failed to create ld.so.conf.d drop-in file: %w" , err )
134145 }
135146
136147 return SafeExec (ldconfigPath , args , nil )
@@ -181,19 +192,15 @@ func (l *Ldconfig) filterDirectories(configFilePath string, directories ...strin
181192 return filtered , nil
182193}
183194
184- // createLdsoconfdFile creates a file at /etc/ld.so.conf.d/.
185- // The file is created at /etc/ld.so.conf.d/{{ .pattern }} using `CreateTemp` and
186- // contains the specified directories on each line.
187- func createLdsoconfdFile (pattern string , dirs ... string ) error {
195+ // createLdsoconfdFile creates a ld.so.conf.d drop-in file with the specified directories on each
196+ // line. The file is created at `ldsoconfdDir`/{{ .pattern }} using `CreateTemp`.
197+ func createLdsoconfdFile (ldsoconfdDir , pattern string , dirs ... string ) error {
188198 if len (dirs ) == 0 {
189199 return nil
190200 }
191-
192- ldsoconfdDir := "/etc/ld.so.conf.d"
193201 if err := os .MkdirAll (ldsoconfdDir , 0755 ); err != nil {
194202 return fmt .Errorf ("failed to create ld.so.conf.d: %w" , err )
195203 }
196-
197204 configFile , err := os .CreateTemp (ldsoconfdDir , pattern )
198205 if err != nil {
199206 return fmt .Errorf ("failed to create config file: %w" , err )
@@ -207,7 +214,7 @@ func createLdsoconfdFile(pattern string, dirs ...string) error {
207214 if added [dir ] {
208215 continue
209216 }
210- _ , err = fmt .Fprintf (configFile , "%s\n " , dir )
217+ _ , err : = fmt .Fprintf (configFile , "%s\n " , dir )
211218 if err != nil {
212219 return fmt .Errorf ("failed to update config file: %w" , err )
213220 }
@@ -222,6 +229,25 @@ func createLdsoconfdFile(pattern string, dirs ...string) error {
222229 return nil
223230}
224231
232+ // ensureLdsoconfFile creates a "standard" top-level ld.so.conf file if none exists.
233+ //
234+ // The created file will contain a single include statement for "`ldsoconfdDir`/*.conf".
235+ func ensureLdsoconfFile (topLevelLdsoconfFilePath , ldsoconfdDir string ) error {
236+ configFile , err := os .OpenFile (topLevelLdsoconfFilePath , os .O_RDWR | os .O_CREATE | os .O_EXCL , 0644 )
237+ if err != nil {
238+ if os .IsExist (err ) {
239+ return nil
240+ }
241+ return fmt .Errorf ("failed to create top-level ld.so.conf file: %w" , err )
242+ }
243+ defer configFile .Close ()
244+ _ , err = configFile .WriteString ("include " + ldsoconfdDir + "/*.conf\n " )
245+ if err != nil {
246+ return fmt .Errorf ("failed to write to top-level ld.so.conf file: %w" , err )
247+ }
248+ return nil
249+ }
250+
225251// getLdsoconfDirectories returns a map of ldsoconf directories to the conf
226252// files that refer to the directory.
227253func (l * Ldconfig ) getLdsoconfDirectories (configFilePath string ) (map [string ]struct {}, error ) {
0 commit comments