Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 36 additions & 15 deletions internal/ldconfig/ldconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ func NewRunner(id string, ldconfigPath string, containerRoot string, additionala
// This struct is used to perform operations on the ldcache and libraries in a
// particular root (e.g. a container).
//
// args[0] is the reexec initializer function name
// args[0] is the reexec initializer function name and is required.
//
// The following flags are required:
//
// --ldconfig-path=LDCONFIG_PATH the path to ldconfig on the host
Expand All @@ -76,16 +77,20 @@ func NewRunner(id string, ldconfigPath string, containerRoot string, additionala
// The following flags are optional:
//
// --is-debian-like-host Indicates that the host system is debian-based.
// See https://github.com/NVIDIA/nvidia-container-toolkit/pull/1444
//
// The remaining args are folders where soname symlinks need to be created.
func NewFromArgs(args ...string) (*Ldconfig, error) {
if len(args) < 1 {
return nil, fmt.Errorf("incorrect arguments: %v", args)
}
fs := flag.NewFlagSet(args[1], flag.ExitOnError)
fs := flag.NewFlagSet("ldconfig-options", flag.ExitOnError)
ldconfigPath := fs.String("ldconfig-path", "", "the path to ldconfig on the host")
containerRoot := fs.String("container-root", "", "the path in which ldconfig must be run")
isDebianLikeHost := fs.Bool("is-debian-like-host", false, "the hook is running from a Debian-like host")
isDebianLikeHost := fs.Bool("is-debian-like-host", false, `indicates that the host system is debian-based.
This allows us to handle the case where there are differences in behavior
between the ldconfig from the host (as executed from an update-ldcache hook) and
ldconfig in the container. Such differences include system search paths.`)
if err := fs.Parse(args[1:]); err != nil {
return nil, err
}
Expand All @@ -98,11 +103,10 @@ func NewFromArgs(args ...string) (*Ldconfig, error) {
}

l := &Ldconfig{
ldconfigPath: *ldconfigPath,
inRoot: *containerRoot,
isDebianLikeHost: *isDebianLikeHost,
isDebianLikeContainer: isDebian(),
directories: fs.Args(),
ldconfigPath: *ldconfigPath,
inRoot: *containerRoot,
isDebianLikeHost: *isDebianLikeHost,
directories: fs.Args(),
}
return l, nil
}
Expand All @@ -113,10 +117,13 @@ func (l *Ldconfig) UpdateLDCache() error {
return err
}

// `prepareRoot` pivots to the container root, so can now set the container "debian-ness".
l.isDebianLikeContainer = isDebian()

// Explicitly specify using /etc/ld.so.conf since the host's ldconfig may
// be configured to use a different config file by default.
const topLevelLdsoconfFilePath = "/etc/ld.so.conf"
filteredDirectories, err := l.filterDirectories(topLevelLdsoconfFilePath, l.directories...)
filteredDirectories, ldconfigDirs, err := l.filterDirectories(topLevelLdsoconfFilePath, l.directories...)
if err != nil {
return err
}
Expand All @@ -126,6 +133,19 @@ func (l *Ldconfig) UpdateLDCache() error {
"-f", topLevelLdsoconfFilePath,
"-C", "/etc/ld.so.cache",
}
// If we are running in a non-debian container on a debian host we also
// need to add the system directories for non-debian hosts to the list of
// folders processed by ldconfig.
// We only do this if they are not already tracked, since the folders on
// on the command line have a higher priority than folders in ld.so.conf.
if l.isDebianLikeHost && !l.isDebianLikeContainer {
for _, systemSearchPath := range l.getSystemSearchPaths() {
if _, ok := ldconfigDirs[systemSearchPath]; ok {
continue
}
args = append(args, systemSearchPath)
}
}

if err := createLdsoconfdFile(ldsoconfdFilenamePattern, filteredDirectories...); err != nil {
return fmt.Errorf("failed to update ld.so.conf.d: %w", err)
Expand Down Expand Up @@ -163,10 +183,10 @@ func (l *Ldconfig) prepareRoot() (string, error) {
return ldconfigPath, nil
}

func (l *Ldconfig) filterDirectories(configFilePath string, directories ...string) ([]string, error) {
func (l *Ldconfig) filterDirectories(configFilePath string, directories ...string) ([]string, map[string]struct{}, error) {
ldconfigDirs, err := l.getLdsoconfDirectories(configFilePath)
if err != nil {
return nil, err
return nil, nil, err
}

var filtered []string
Expand All @@ -175,8 +195,9 @@ func (l *Ldconfig) filterDirectories(configFilePath string, directories ...strin
continue
}
filtered = append(filtered, d)
ldconfigDirs[d] = struct{}{}
}
return filtered, nil
return filtered, ldconfigDirs, nil
}

// createLdsoconfdFile creates a file at /etc/ld.so.conf.d/.
Expand Down Expand Up @@ -224,7 +245,7 @@ func createLdsoconfdFile(pattern string, dirs ...string) error {
// files that refer to the directory.
func (l *Ldconfig) getLdsoconfDirectories(configFilePath string) (map[string]struct{}, error) {
ldconfigDirs := make(map[string]struct{})
for _, d := range l.getSystemSerachPaths() {
for _, d := range l.getSystemSearchPaths() {
ldconfigDirs[d] = struct{}{}
}

Expand Down Expand Up @@ -253,9 +274,9 @@ func (l *Ldconfig) getLdsoconfDirectories(configFilePath string) (map[string]str
return ldconfigDirs, nil
}

func (l *Ldconfig) getSystemSerachPaths() []string {
func (l *Ldconfig) getSystemSearchPaths() []string {
if l.isDebianLikeContainer {
debianSystemSearchPaths()
return debianSystemSearchPaths()
}
return nonDebianSystemSearchPaths()
}
Expand Down
2 changes: 1 addition & 1 deletion internal/ldconfig/ldconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ include INCLUDED_PATTERN*
l := &Ldconfig{
isDebianLikeContainer: true,
}
filtered, err := l.filterDirectories(topLevelConfPath, tc.input...)
filtered, _, err := l.filterDirectories(topLevelConfPath, tc.input...)

require.NoError(t, err)
require.Equal(t, tc.expected, filtered)
Expand Down
19 changes: 19 additions & 0 deletions tests/e2e/nvidia-container-toolkit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -570,4 +570,23 @@ EOF`)
Expect(output).To(Equal(expectedOutput))
})
})

When("running a ubi9 container", Ordered, func() {
var (
expectedOutput string
)
BeforeAll(func(ctx context.Context) {
_, _, err := runner.Run(`docker pull redhat/ubi9`)
Expect(err).ToNot(HaveOccurred())

expectedOutput, _, err = runner.Run(`docker run --rm --runtime=runc redhat/ubi9 bash -c "ldconfig -p | grep libc.so."`)
Expect(err).ToNot(HaveOccurred())
})

It("should include the system libraries when using the nvidia-container-runtime", func(ctx context.Context) {
output, _, err := runner.Run(`docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all redhat/ubi9 bash -c "ldconfig -p | grep libc.so."`)
Expect(err).ToNot(HaveOccurred())
Expect(output).To(Equal(expectedOutput))
})
})
})
Loading