|
17 | 17 | package root
|
18 | 18 |
|
19 | 19 | import (
|
| 20 | + "fmt" |
20 | 21 | "os"
|
21 | 22 | "path/filepath"
|
22 | 23 | "strings"
|
| 24 | + "sync" |
23 | 25 |
|
24 | 26 | "github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
25 | 27 | "github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
|
26 | 28 | )
|
27 | 29 |
|
28 | 30 | // Driver represents a filesystem in which a set of drivers or devices is defined.
|
29 | 31 | type Driver struct {
|
| 32 | + sync.Mutex |
30 | 33 | logger logger.Interface
|
31 | 34 | // Root represents the root from the perspective of the driver libraries and binaries.
|
32 | 35 | Root string
|
33 | 36 | // librarySearchPaths specifies explicit search paths for discovering libraries.
|
34 | 37 | librarySearchPaths []string
|
35 | 38 | // configSearchPaths specified explicit search paths for discovering driver config files.
|
36 | 39 | configSearchPaths []string
|
| 40 | + // version stores the driver version. This can be specified at construction or cached on subsequent calls. |
| 41 | + version string |
| 42 | + // libraryRoot stores the absolute path where the driver libraries (libcuda.so.<VERSION>) can be found. |
| 43 | + libraryRoot string |
37 | 44 | }
|
38 | 45 |
|
39 | 46 | // New creates a new Driver root using the specified options.
|
@@ -103,6 +110,62 @@ func (r *Driver) configSearchOptions() []lookup.Option {
|
103 | 110 | }
|
104 | 111 | }
|
105 | 112 |
|
| 113 | +// Version returns the driver version as a string. |
| 114 | +func (r *Driver) Version() (string, error) { |
| 115 | + r.Lock() |
| 116 | + defer r.Unlock() |
| 117 | + if r.version != "" { |
| 118 | + return r.version, nil |
| 119 | + } |
| 120 | + |
| 121 | + libcudaPath, err := r.libcudaPath() |
| 122 | + if err != nil { |
| 123 | + return "", fmt.Errorf("failed to locate libcuda.so: %v", err) |
| 124 | + } |
| 125 | + |
| 126 | + version := strings.TrimPrefix(filepath.Base(libcudaPath), "libcuda.so.") |
| 127 | + if version == "" { |
| 128 | + return "", fmt.Errorf("failed to determine libcuda.so version from path: %q", libcudaPath) |
| 129 | + } |
| 130 | + |
| 131 | + r.version = version |
| 132 | + return r.version, nil |
| 133 | +} |
| 134 | + |
| 135 | +// LibraryRoot returns the folder in which the driver libraries can be found. |
| 136 | +func (r *Driver) LibraryRoot() (string, error) { |
| 137 | + r.Lock() |
| 138 | + defer r.Unlock() |
| 139 | + if r.libraryRoot != "" { |
| 140 | + return r.libraryRoot, nil |
| 141 | + } |
| 142 | + |
| 143 | + libcudaPath, err := r.libcudaPath() |
| 144 | + if err != nil { |
| 145 | + return "", fmt.Errorf("failed to locate libcuda.so: %v", err) |
| 146 | + } |
| 147 | + |
| 148 | + r.libraryRoot = filepath.Dir(libcudaPath) |
| 149 | + return r.libraryRoot, nil |
| 150 | +} |
| 151 | + |
| 152 | +// libcudaPath returns the path to libcuda.so.*.* in the driver root. |
| 153 | +func (r *Driver) libcudaPath() (string, error) { |
| 154 | + pattern := "libcuda.so.*.*" |
| 155 | + |
| 156 | + locator := r.Libraries() |
| 157 | + paths, err := locator.Locate(pattern) |
| 158 | + if err != nil { |
| 159 | + return "", fmt.Errorf("failed to locate %v: %v", pattern, err) |
| 160 | + } |
| 161 | + |
| 162 | + libcudaPath := paths[0] |
| 163 | + if len(paths) > 1 { |
| 164 | + r.logger.Warningf("Selecting %v out of multiple libcuda.so paths.", libcudaPath, paths) |
| 165 | + } |
| 166 | + return libcudaPath, nil |
| 167 | +} |
| 168 | + |
106 | 169 | // normalizeSearchPaths takes a list of paths and normalized these.
|
107 | 170 | // Each of the elements in the list is expanded if it is a path list and the
|
108 | 171 | // resultant list is returned.
|
|
0 commit comments