@@ -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 {
@@ -115,20 +124,22 @@ func (l *Ldconfig) UpdateLDCache() error {
115124
116125 // Explicitly specify using /etc/ld.so.conf since the host's ldconfig may
117126 // be configured to use a different config file by default.
118- const topLevelLdsoconfFilePath = "/etc/ld.so.conf"
119- filteredDirectories , err := l .filterDirectories (topLevelLdsoconfFilePath , l .directories ... )
127+ filteredDirectories , err := l .filterDirectories (defaultTopLevelLdsoconfFilePath , l .directories ... )
120128 if err != nil {
121129 return err
122130 }
123131
124132 args := []string {
125133 filepath .Base (ldconfigPath ),
126- "-f" , topLevelLdsoconfFilePath ,
134+ "-f" , defaultTopLevelLdsoconfFilePath ,
127135 "-C" , "/etc/ld.so.cache" ,
128136 }
129137
130- if err := createLdsoconfdFile (ldsoconfdFilenamePattern , filteredDirectories ... ); err != nil {
131- return fmt .Errorf ("failed to update ld.so.conf.d: %w" , err )
138+ if err := l .ensureLdsoconfFile (defaultTopLevelLdsoconfFilePath , defaultLdsoconfdDir ); err != nil {
139+ return fmt .Errorf ("failed to ensure ld.so.conf file: %w" , err )
140+ }
141+ if err := createLdsoconfdFile (defaultLdsoconfdDir , ldsoconfdFilenamePattern , filteredDirectories ... ); err != nil {
142+ return fmt .Errorf ("failed to create ld.so.conf.d drop-in file: %w" , err )
132143 }
133144
134145 return SafeExec (ldconfigPath , args , nil )
@@ -179,19 +190,15 @@ func (l *Ldconfig) filterDirectories(configFilePath string, directories ...strin
179190 return filtered , nil
180191}
181192
182- // createLdsoconfdFile creates a file at /etc/ld.so.conf.d/.
183- // The file is created at /etc/ld.so.conf.d/{{ .pattern }} using `CreateTemp` and
184- // contains the specified directories on each line.
185- func createLdsoconfdFile (pattern string , dirs ... string ) error {
193+ // createLdsoconfdFile creates a ld.so.conf.d drop-in file with the specified directories on each
194+ // line. The file is created at `ldsoconfdDir`/{{ .pattern }} using `CreateTemp`.
195+ func createLdsoconfdFile (ldsoconfdDir , pattern string , dirs ... string ) error {
186196 if len (dirs ) == 0 {
187197 return nil
188198 }
189-
190- ldsoconfdDir := "/etc/ld.so.conf.d"
191199 if err := os .MkdirAll (ldsoconfdDir , 0755 ); err != nil {
192200 return fmt .Errorf ("failed to create ld.so.conf.d: %w" , err )
193201 }
194-
195202 configFile , err := os .CreateTemp (ldsoconfdDir , pattern )
196203 if err != nil {
197204 return fmt .Errorf ("failed to create config file: %w" , err )
@@ -205,7 +212,7 @@ func createLdsoconfdFile(pattern string, dirs ...string) error {
205212 if added [dir ] {
206213 continue
207214 }
208- _ , err = fmt .Fprintf (configFile , "%s\n " , dir )
215+ _ , err : = fmt .Fprintf (configFile , "%s\n " , dir )
209216 if err != nil {
210217 return fmt .Errorf ("failed to update config file: %w" , err )
211218 }
@@ -220,6 +227,19 @@ func createLdsoconfdFile(pattern string, dirs ...string) error {
220227 return nil
221228}
222229
230+ // ensureLdsoconfFile creates a "standard" top-level ld.so.conf file if none exists.
231+ //
232+ // The created file will contain a single include statement for "`ldsoconfdDir`/*.conf".
233+ func (l * Ldconfig ) ensureLdsoconfFile (topLevelLdsoconfFilePath , ldsoconfdDir string ) error {
234+ configFile , err := os .OpenFile (topLevelLdsoconfFilePath , os .O_RDWR | os .O_CREATE | os .O_EXCL , 0644 )
235+ if err != nil && ! os .IsExist (err ) {
236+ return fmt .Errorf ("failed to create top-level ld.so.conf file: %w" , err )
237+ }
238+ defer configFile .Close ()
239+ configFile .WriteString ("include " + ldsoconfdDir + "/*.conf\n " )
240+ return nil
241+ }
242+
223243// getLdsoconfDirectories returns a map of ldsoconf directories to the conf
224244// files that refer to the directory.
225245func (l * Ldconfig ) getLdsoconfDirectories (configFilePath string ) (map [string ]struct {}, error ) {
0 commit comments