Skip to content

Commit d7a4ca9

Browse files
committed
ldconfig: Create top-level conf file is none exists instead of a drop-in
1 parent 07f71f1 commit d7a4ca9

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

internal/ldconfig/ldconfig.go

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4251
type Ldconfig struct {
@@ -115,19 +124,18 @@ 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 {
138+
if err := createLdsoconfdFile(defaultTopLevelLdsoconfFilePath, defaultLdsoconfdDir, ldsoconfdFilenamePattern, filteredDirectories...); err != nil {
131139
return fmt.Errorf("failed to update ld.so.conf.d: %w", err)
132140
}
133141

@@ -179,22 +187,30 @@ func (l *Ldconfig) filterDirectories(configFilePath string, directories ...strin
179187
return filtered, nil
180188
}
181189

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 {
190+
// createLdsoconfdFile creates a ldso conf file containing the specified directories on each line.
191+
//
192+
// The file is either created at `topLevelLdsoconfFilePath` if no file exists there, or as a
193+
// drop-in in `ldsoconfdDir` using `CreateTemp` and `pattern`. The function assumes that an
194+
// existing top-level ldso conf file includes `ldsoconfdDir`.
195+
func createLdsoconfdFile(topLevelLdsoconfFilePath, ldsoconfdDir, pattern string, dirs ...string) error {
186196
if len(dirs) == 0 {
187197
return nil
188198
}
189199

190-
ldsoconfdDir := "/etc/ld.so.conf.d"
191-
if err := os.MkdirAll(ldsoconfdDir, 0755); err != nil {
192-
return fmt.Errorf("failed to create ld.so.conf.d: %w", err)
193-
}
194-
195-
configFile, err := os.CreateTemp(ldsoconfdDir, pattern)
196-
if err != nil {
197-
return fmt.Errorf("failed to create config file: %w", err)
200+
var configFile *os.File
201+
if _, err := os.Stat(topLevelLdsoconfFilePath); os.IsNotExist(err) {
202+
configFile, err = os.OpenFile(topLevelLdsoconfFilePath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0644)
203+
if err != nil {
204+
return fmt.Errorf("failed to open top-level ld.so.conf file: %w", err)
205+
}
206+
} else {
207+
if err := os.MkdirAll(ldsoconfdDir, 0755); err != nil {
208+
return fmt.Errorf("failed to create ld.so.conf.d: %w", err)
209+
}
210+
configFile, err = os.CreateTemp(ldsoconfdDir, pattern)
211+
if err != nil {
212+
return fmt.Errorf("failed to create config file: %w", err)
213+
}
198214
}
199215
defer func() {
200216
_ = configFile.Close()
@@ -205,7 +221,7 @@ func createLdsoconfdFile(pattern string, dirs ...string) error {
205221
if added[dir] {
206222
continue
207223
}
208-
_, err = fmt.Fprintf(configFile, "%s\n", dir)
224+
_, err := fmt.Fprintf(configFile, "%s\n", dir)
209225
if err != nil {
210226
return fmt.Errorf("failed to update config file: %w", err)
211227
}

0 commit comments

Comments
 (0)