Skip to content

Commit 19482da

Browse files
authored
Merge pull request #715 from elezar/add-libcuda-so-symlink
Align driver symlinks with libnvidia-container
2 parents 78c4ca8 + 82ae2e6 commit 19482da

File tree

7 files changed

+464
-70
lines changed

7 files changed

+464
-70
lines changed

internal/discover/none.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ var _ Discover = (*None)(nil)
2424

2525
// Devices returns an empty list of devices
2626
func (e None) Devices() ([]Device, error) {
27-
return []Device{}, nil
27+
return nil, nil
2828
}
2929

3030
// Mounts returns an empty list of mounts
3131
func (e None) Mounts() ([]Mount, error) {
32-
return []Mount{}, nil
32+
return nil, nil
3333
}
3434

3535
// Hooks returns an empty list of hooks
3636
func (e None) Hooks() ([]Hook, error) {
37-
return []Hook{}, nil
37+
return nil, nil
3838
}

internal/discover/symlinks.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
# Copyright 2024 NVIDIA CORPORATION
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
**/
16+
17+
package discover
18+
19+
import (
20+
"fmt"
21+
"path/filepath"
22+
)
23+
24+
type additionalSymlinks struct {
25+
Discover
26+
version string
27+
nvidiaCDIHookPath string
28+
}
29+
30+
// WithDriverDotSoSymlinks decorates the provided discoverer.
31+
// A hook is added that checks for specific driver symlinks that need to be created.
32+
func WithDriverDotSoSymlinks(mounts Discover, version string, nvidiaCDIHookPath string) Discover {
33+
if version == "" {
34+
version = "*.*"
35+
}
36+
return &additionalSymlinks{
37+
Discover: mounts,
38+
nvidiaCDIHookPath: nvidiaCDIHookPath,
39+
version: version,
40+
}
41+
}
42+
43+
// Hooks returns a hook to create the additional symlinks based on the mounts.
44+
func (d *additionalSymlinks) Hooks() ([]Hook, error) {
45+
mounts, err := d.Discover.Mounts()
46+
if err != nil {
47+
return nil, fmt.Errorf("failed to get library mounts: %v", err)
48+
}
49+
hooks, err := d.Discover.Hooks()
50+
if err != nil {
51+
return nil, fmt.Errorf("failed to get hooks: %v", err)
52+
}
53+
54+
var links []string
55+
processedPaths := make(map[string]bool)
56+
processedLinks := make(map[string]bool)
57+
for _, mount := range mounts {
58+
if processedPaths[mount.Path] {
59+
continue
60+
}
61+
processedPaths[mount.Path] = true
62+
63+
for _, link := range d.getLinksForMount(mount.Path) {
64+
if processedLinks[link] {
65+
continue
66+
}
67+
processedLinks[link] = true
68+
links = append(links, link)
69+
}
70+
}
71+
72+
if len(links) == 0 {
73+
return hooks, nil
74+
}
75+
76+
hook := CreateCreateSymlinkHook(d.nvidiaCDIHookPath, links).(Hook)
77+
return append(hooks, hook), nil
78+
}
79+
80+
// getLinksForMount maps the path to created links if any.
81+
func (d additionalSymlinks) getLinksForMount(path string) []string {
82+
dir, filename := filepath.Split(path)
83+
switch {
84+
case d.isDriverLibrary("libcuda.so", filename):
85+
// XXX Many applications wrongly assume that libcuda.so exists (e.g. with dlopen).
86+
// create libcuda.so -> libcuda.so.1 symlink
87+
link := fmt.Sprintf("%s::%s", "libcuda.so.1", filepath.Join(dir, "libcuda.so"))
88+
return []string{link}
89+
case d.isDriverLibrary("libGLX_nvidia.so", filename):
90+
// XXX GLVND requires this symlink for indirect GLX support.
91+
// create libGLX_indirect.so.0 -> libGLX_nvidia.so.VERSION symlink
92+
link := fmt.Sprintf("%s::%s", filename, filepath.Join(dir, "libGLX_indirect.so.0"))
93+
return []string{link}
94+
case d.isDriverLibrary("libnvidia-opticalflow.so", filename):
95+
// XXX Fix missing symlink for libnvidia-opticalflow.so.
96+
// create libnvidia-opticalflow.so -> libnvidia-opticalflow.so.1 symlink
97+
link := fmt.Sprintf("%s::%s", "libnvidia-opticalflow.so.1", filepath.Join(dir, "libnvidia-opticalflow.so"))
98+
return []string{link}
99+
}
100+
return nil
101+
}
102+
103+
// isDriverLibrary checks whether the specified filename is a specific driver library.
104+
func (d additionalSymlinks) isDriverLibrary(libraryName string, filename string) bool {
105+
pattern := libraryName + "." + d.version
106+
match, _ := filepath.Match(pattern, filename)
107+
return match
108+
}

0 commit comments

Comments
 (0)