Skip to content

Commit aa0c6fa

Browse files
committed
Fix update of ldcache on non-debian containers
This change ensures that the ldcache in a non-debian container includes libraries at /lib64 and /usr/lib64 when running on debian host. Signed-off-by: Evan Lezar <elezar@nvidia.com>
1 parent 3fe923d commit aa0c6fa

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

internal/ldconfig/ldconfig.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ const (
3838
)
3939

4040
type Ldconfig struct {
41-
ldconfigPath string
42-
inRoot string
43-
directories []string
41+
ldconfigPath string
42+
inRoot string
43+
isDebianLikeHost bool
44+
directories []string
4445
}
4546

4647
// NewRunner creates an exec.Cmd that can be used to run ldconfig.
@@ -50,6 +51,9 @@ func NewRunner(id string, ldconfigPath string, containerRoot string, additionala
5051
"--ldconfig-path", strings.TrimPrefix(config.NormalizeLDConfigPath("@"+ldconfigPath), "@"),
5152
"--container-root", containerRoot,
5253
}
54+
if isDebian() {
55+
args = append(args, "--is-debian-like-host")
56+
}
5357
args = append(args, additionalargs...)
5458

5559
return createReexecCommand(args)
@@ -66,6 +70,10 @@ func NewRunner(id string, ldconfigPath string, containerRoot string, additionala
6670
// --ldconfig-path=LDCONFIG_PATH the path to ldconfig on the host
6771
// --container-root=CONTAINER_ROOT the path in which ldconfig must be run
6872
//
73+
// The following flags are optional:
74+
//
75+
// --is-debian-like-host Indicates that the host system is debian-based.
76+
//
6977
// The remaining args are folders where soname symlinks need to be created.
7078
func NewFromArgs(args ...string) (*Ldconfig, error) {
7179
if len(args) < 1 {
@@ -74,6 +82,7 @@ func NewFromArgs(args ...string) (*Ldconfig, error) {
7482
fs := flag.NewFlagSet(args[1], flag.ExitOnError)
7583
ldconfigPath := fs.String("ldconfig-path", "", "the path to ldconfig on the host")
7684
containerRoot := fs.String("container-root", "", "the path in which ldconfig must be run")
85+
isDebianLikeHost := fs.Bool("is-debian-like-host", false, "the hook is running from a Debian-like host")
7786
if err := fs.Parse(args[1:]); err != nil {
7887
return nil, err
7988
}
@@ -86,9 +95,10 @@ func NewFromArgs(args ...string) (*Ldconfig, error) {
8695
}
8796

8897
l := &Ldconfig{
89-
ldconfigPath: *ldconfigPath,
90-
inRoot: *containerRoot,
91-
directories: fs.Args(),
98+
ldconfigPath: *ldconfigPath,
99+
inRoot: *containerRoot,
100+
isDebianLikeHost: *isDebianLikeHost,
101+
directories: fs.Args(),
92102
}
93103
return l, nil
94104
}
@@ -106,6 +116,12 @@ func (l *Ldconfig) UpdateLDCache() error {
106116
"-f", "/etc/ld.so.conf",
107117
"-C", "/etc/ld.so.cache",
108118
}
119+
// If we are running in a non-debian container on a debian host we also
120+
// need to add the system directories for non-debian hosts to the list of
121+
// folders processed by ldconfig.
122+
if l.isDebianLikeHost && !isDebian() {
123+
args = append(args, "/lib64", "/usr/lib64")
124+
}
109125

110126
if err := createLdsoconfdFile(ldsoconfdFilenamePattern, l.directories...); err != nil {
111127
return fmt.Errorf("failed to update ld.so.conf.d: %w", err)
@@ -114,6 +130,14 @@ func (l *Ldconfig) UpdateLDCache() error {
114130
return SafeExec(ldconfigPath, args, nil)
115131
}
116132

133+
func isDebian() bool {
134+
info, err := os.Stat("/etc/debian_version")
135+
if err != nil {
136+
return false
137+
}
138+
return !info.IsDir()
139+
}
140+
117141
func (l *Ldconfig) prepareRoot() (string, error) {
118142
// To prevent leaking the parent proc filesystem, we create a new proc mount
119143
// in the specified root.

tests/e2e/nvidia-container-toolkit_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,4 +533,29 @@ EOF`)
533533
Expect(err).ToNot(HaveOccurred())
534534
})
535535
})
536+
537+
When("running a container a ubi9 container", Ordered, func() {
538+
var (
539+
expectedOutput string
540+
)
541+
BeforeAll(func(ctx context.Context) {
542+
_, _, err := runner.Run(`docker pull redhat/ubi9`)
543+
Expect(err).ToNot(HaveOccurred())
544+
545+
expectedOutput, _, err = runner.Run(`docker run --rm --runtime=runc redhat/ubi9 bash -c "ldconfig -p | grep libc.so."`)
546+
Expect(err).ToNot(HaveOccurred())
547+
})
548+
549+
It("should include the system libraries when using the nvidia-container-runtime", func(ctx context.Context) {
550+
output, _, err := runner.Run(`docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all redhat/ubi9 bash -c "ldconfig -p | grep libc.so."`)
551+
Expect(err).ToNot(HaveOccurred())
552+
Expect(output).To(Equal(expectedOutput))
553+
})
554+
555+
It("should include the system libraries when using the nvidia-container-runtime-hook", Label("legacy"), func(ctx context.Context) {
556+
output, _, err := runner.Run(`docker run --rm --runtime=runc --gpus=all redhat/ubi9 bash -c "ldconfig -p | grep libc.so."`)
557+
Expect(err).ToNot(HaveOccurred())
558+
Expect(output).To(Equal(expectedOutput))
559+
})
560+
})
536561
})

0 commit comments

Comments
 (0)