diff --git a/go.mod b/go.mod index f062fc24..7c762c08 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/Masterminds/semver v1.5.0 github.com/NVIDIA/go-nvlib v0.7.0 github.com/NVIDIA/go-nvml v0.12.4-0 - github.com/NVIDIA/nvidia-container-toolkit v1.16.1 + github.com/NVIDIA/nvidia-container-toolkit v1.17.0 github.com/prometheus/client_golang v1.19.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index 034c6e91..b393435c 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/NVIDIA/go-nvlib v0.7.0 h1:Z/J7skMdLbTiHvomKVsGYsttfQMZj5FwNYIFXhZ4i/c github.com/NVIDIA/go-nvlib v0.7.0/go.mod h1:9UrsLGx/q1OrENygXjOuM5Ey5KCtiZhbvBlbUIxtGWY= github.com/NVIDIA/go-nvml v0.12.4-0 h1:4tkbB3pT1O77JGr0gQ6uD8FrsUPqP1A/EOEm2wI1TUg= github.com/NVIDIA/go-nvml v0.12.4-0/go.mod h1:8Llmj+1Rr+9VGGwZuRer5N/aCjxGuR5nPb/9ebBiIEQ= -github.com/NVIDIA/nvidia-container-toolkit v1.16.1 h1:PkY6RqYD1wIt1izCvYZ7kr7IitxK8e9+k/prO6b3vD0= -github.com/NVIDIA/nvidia-container-toolkit v1.16.1/go.mod h1:jJXYvHEdqqpDcRXvolaiFCBsgLxvCwmJWSBZM3zQPY8= +github.com/NVIDIA/nvidia-container-toolkit v1.17.0 h1:L1kRJmoV5o42Ehnuh9lg959UxviTh2g2aneBOxjN7u0= +github.com/NVIDIA/nvidia-container-toolkit v1.17.0/go.mod h1:R6bNf6ca0IjjACa0ncKGvsrx6zSjsgz8QkFyBDk5szU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/builder.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/builder.go index da9025f0..332d017a 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/builder.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/builder.go @@ -47,7 +47,7 @@ func New(opt ...Option) (CUDA, error) { // build creates a CUDA image from the builder. func (b builder) build() (CUDA, error) { if b.disableRequire { - b.env[envNVDisableRequire] = "true" + b.env[EnvVarNvidiaDisableRequire] = "true" } c := CUDA{ diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/cuda_image.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/cuda_image.go index d285dea2..4298e634 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/cuda_image.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/cuda_image.go @@ -28,12 +28,10 @@ import ( ) const ( - envCUDAVersion = "CUDA_VERSION" - envNVRequirePrefix = "NVIDIA_REQUIRE_" - envNVRequireCUDA = envNVRequirePrefix + "CUDA" - envNVRequireJetpack = envNVRequirePrefix + "JETPACK" - envNVDisableRequire = "NVIDIA_DISABLE_REQUIRE" - envNVDriverCapabilities = "NVIDIA_DRIVER_CAPABILITIES" + DeviceListAsVolumeMountsRoot = "/var/run/nvidia-container-devices" + + volumeMountDevicePrefixCDI = "cdi/" + volumeMountDevicePrefixImex = "imex/" ) // CUDA represents a CUDA image that can be used for GPU computing. This wraps @@ -80,8 +78,8 @@ func (i CUDA) HasEnvvar(key string) bool { // image is considered legacy if it has a CUDA_VERSION environment variable defined // and no NVIDIA_REQUIRE_CUDA environment variable defined. func (i CUDA) IsLegacy() bool { - legacyCudaVersion := i.env[envCUDAVersion] - cudaRequire := i.env[envNVRequireCUDA] + legacyCudaVersion := i.env[EnvVarCudaVersion] + cudaRequire := i.env[EnvVarNvidiaRequireCuda] return len(legacyCudaVersion) > 0 && len(cudaRequire) == 0 } @@ -95,7 +93,7 @@ func (i CUDA) GetRequirements() ([]string, error) { // All variables with the "NVIDIA_REQUIRE_" prefix are passed to nvidia-container-cli var requirements []string for name, value := range i.env { - if strings.HasPrefix(name, envNVRequirePrefix) && !strings.HasPrefix(name, envNVRequireJetpack) { + if strings.HasPrefix(name, NvidiaRequirePrefix) && !strings.HasPrefix(name, EnvVarNvidiaRequireJetpack) { requirements = append(requirements, value) } } @@ -113,7 +111,7 @@ func (i CUDA) GetRequirements() ([]string, error) { // HasDisableRequire checks for the value of the NVIDIA_DISABLE_REQUIRE. If set // to a valid (true) boolean value this can be used to disable the requirement checks func (i CUDA) HasDisableRequire() bool { - if disable, exists := i.env[envNVDisableRequire]; exists { + if disable, exists := i.env[EnvVarNvidiaDisableRequire]; exists { // i.logger.Debugf("NVIDIA_DISABLE_REQUIRE=%v; skipping requirement checks", disable) d, _ := strconv.ParseBool(disable) return d @@ -157,7 +155,7 @@ func (i CUDA) DevicesFromEnvvars(envVars ...string) VisibleDevices { // GetDriverCapabilities returns the requested driver capabilities. func (i CUDA) GetDriverCapabilities() DriverCapabilities { - env := i.env[envNVDriverCapabilities] + env := i.env[EnvVarNvidiaDriverCapabilities] capabilities := make(DriverCapabilities) for _, c := range strings.Split(env, ",") { @@ -168,7 +166,7 @@ func (i CUDA) GetDriverCapabilities() DriverCapabilities { } func (i CUDA) legacyVersion() (string, error) { - cudaVersion := i.env[envCUDAVersion] + cudaVersion := i.env[EnvVarCudaVersion] majorMinor, err := parseMajorMinorVersion(cudaVersion) if err != nil { return "", fmt.Errorf("invalid CUDA version %v: %v", cudaVersion, err) @@ -202,7 +200,7 @@ func parseMajorMinorVersion(version string) (string, error) { // OnlyFullyQualifiedCDIDevices returns true if all devices requested in the image are requested as CDI devices/ func (i CUDA) OnlyFullyQualifiedCDIDevices() bool { var hasCDIdevice bool - for _, device := range i.DevicesFromEnvvars("NVIDIA_VISIBLE_DEVICES").List() { + for _, device := range i.VisibleDevicesFromEnvVar() { if !parser.IsQualifiedName(device) { return false } @@ -218,14 +216,31 @@ func (i CUDA) OnlyFullyQualifiedCDIDevices() bool { return hasCDIdevice } -const ( - deviceListAsVolumeMountsRoot = "/var/run/nvidia-container-devices" -) +// VisibleDevicesFromEnvVar returns the set of visible devices requested through +// the NVIDIA_VISIBLE_DEVICES environment variable. +func (i CUDA) VisibleDevicesFromEnvVar() []string { + return i.DevicesFromEnvvars(EnvVarNvidiaVisibleDevices).List() +} + +// VisibleDevicesFromMounts returns the set of visible devices requested as mounts. +func (i CUDA) VisibleDevicesFromMounts() []string { + var devices []string + for _, device := range i.DevicesFromMounts() { + switch { + case strings.HasPrefix(device, volumeMountDevicePrefixCDI): + continue + case strings.HasPrefix(device, volumeMountDevicePrefixImex): + continue + } + devices = append(devices, device) + } + return devices +} // DevicesFromMounts returns a list of device specified as mounts. // TODO: This should be merged with getDevicesFromMounts used in the NVIDIA Container Runtime func (i CUDA) DevicesFromMounts() []string { - root := filepath.Clean(deviceListAsVolumeMountsRoot) + root := filepath.Clean(DeviceListAsVolumeMountsRoot) seen := make(map[string]bool) var devices []string for _, m := range i.mounts { @@ -260,10 +275,10 @@ func (i CUDA) DevicesFromMounts() []string { func (i CUDA) CDIDevicesFromMounts() []string { var devices []string for _, mountDevice := range i.DevicesFromMounts() { - if !strings.HasPrefix(mountDevice, "cdi/") { + if !strings.HasPrefix(mountDevice, volumeMountDevicePrefixCDI) { continue } - parts := strings.SplitN(strings.TrimPrefix(mountDevice, "cdi/"), "/", 3) + parts := strings.SplitN(strings.TrimPrefix(mountDevice, volumeMountDevicePrefixCDI), "/", 3) if len(parts) != 3 { continue } @@ -274,3 +289,20 @@ func (i CUDA) CDIDevicesFromMounts() []string { } return devices } + +// ImexChannelsFromEnvVar returns the list of IMEX channels requested for the image. +func (i CUDA) ImexChannelsFromEnvVar() []string { + return i.DevicesFromEnvvars(EnvVarNvidiaImexChannels).List() +} + +// ImexChannelsFromMounts returns the list of IMEX channels requested for the image. +func (i CUDA) ImexChannelsFromMounts() []string { + var channels []string + for _, mountDevice := range i.DevicesFromMounts() { + if !strings.HasPrefix(mountDevice, volumeMountDevicePrefixImex) { + continue + } + channels = append(channels, strings.TrimPrefix(mountDevice, volumeMountDevicePrefixImex)) + } + return channels +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/envvars.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/envvars.go new file mode 100644 index 00000000..0789f22f --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/config/image/envvars.go @@ -0,0 +1,31 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package image + +const ( + EnvVarCudaVersion = "CUDA_VERSION" + EnvVarNvidiaDisableRequire = "NVIDIA_DISABLE_REQUIRE" + EnvVarNvidiaDriverCapabilities = "NVIDIA_DRIVER_CAPABILITIES" + EnvVarNvidiaImexChannels = "NVIDIA_IMEX_CHANNELS" + EnvVarNvidiaMigConfigDevices = "NVIDIA_MIG_CONFIG_DEVICES" + EnvVarNvidiaMigMonitorDevices = "NVIDIA_MIG_MONITOR_DEVICES" + EnvVarNvidiaRequireCuda = NvidiaRequirePrefix + "CUDA" + EnvVarNvidiaRequireJetpack = NvidiaRequirePrefix + "JETPACK" + EnvVarNvidiaVisibleDevices = "NVIDIA_VISIBLE_DEVICES" + + NvidiaRequirePrefix = "NVIDIA_REQUIRE_" +) diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/cache.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/cache.go new file mode 100644 index 00000000..e9e4b615 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/cache.go @@ -0,0 +1,80 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package discover + +import "sync" + +type cache struct { + d Discover + + sync.Mutex + devices []Device + hooks []Hook + mounts []Mount +} + +var _ Discover = (*cache)(nil) + +// WithCache decorates the specified disoverer with a cache. +func WithCache(d Discover) Discover { + if d == nil { + return None{} + } + return &cache{d: d} +} + +func (c *cache) Devices() ([]Device, error) { + c.Lock() + defer c.Unlock() + + if c.devices == nil { + devices, err := c.d.Devices() + if err != nil { + return nil, err + } + c.devices = devices + } + return c.devices, nil +} + +func (c *cache) Hooks() ([]Hook, error) { + c.Lock() + defer c.Unlock() + + if c.hooks == nil { + hooks, err := c.d.Hooks() + if err != nil { + return nil, err + } + c.hooks = hooks + } + return c.hooks, nil +} + +func (c *cache) Mounts() ([]Mount, error) { + c.Lock() + defer c.Unlock() + + if c.mounts == nil { + mounts, err := c.d.Mounts() + if err != nil { + return nil, err + } + c.mounts = mounts + } + return c.mounts, nil +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/first-valid.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/first-valid.go new file mode 100644 index 00000000..36de9204 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/first-valid.go @@ -0,0 +1,72 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package discover + +import "errors" + +type firstOf []Discover + +// FirstValid returns a discoverer that returns the first non-error result from a list of discoverers. +func FirstValid(discoverers ...Discover) Discover { + var f firstOf + for _, d := range discoverers { + if d == nil { + continue + } + f = append(f, d) + } + return f +} + +func (f firstOf) Devices() ([]Device, error) { + var errs error + for _, d := range f { + devices, err := d.Devices() + if err != nil { + errs = errors.Join(errs, err) + continue + } + return devices, nil + } + return nil, errs +} + +func (f firstOf) Hooks() ([]Hook, error) { + var errs error + for _, d := range f { + hooks, err := d.Hooks() + if err != nil { + errs = errors.Join(errs, err) + continue + } + return hooks, nil + } + return nil, errs +} + +func (f firstOf) Mounts() ([]Mount, error) { + var errs error + for _, d := range f { + mounts, err := d.Mounts() + if err != nil { + errs = errors.Join(errs, err) + continue + } + return mounts, nil + } + return nil, nil +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/graphics.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/graphics.go index b5c248d4..e80dd0be 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/graphics.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/graphics.go @@ -146,6 +146,27 @@ func newGraphicsLibrariesDiscoverer(logger logger.Interface, driver *root.Driver } } +// Mounts discovers the required libraries and filters out libnvidia-allocator.so. +// The library libnvidia-allocator.so is already handled by either the *.RM_VERSION +// injection or by libnvidia-container. We therefore filter it out here as a +// workaround for the case where libnvidia-container will re-mount this in the +// container, which causes issues with shared mount propagation. +func (d graphicsDriverLibraries) Mounts() ([]Mount, error) { + mounts, err := d.Discover.Mounts() + if err != nil { + return nil, fmt.Errorf("failed to get library mounts: %v", err) + } + + var filtered []Mount + for _, mount := range mounts { + if d.isDriverLibrary(filepath.Base(mount.Path), "libnvidia-allocator.so") { + continue + } + filtered = append(filtered, mount) + } + return filtered, nil +} + // Create necessary library symlinks for graphics drivers func (d graphicsDriverLibraries) Hooks() ([]Hook, error) { mounts, err := d.Discover.Mounts() @@ -159,10 +180,10 @@ func (d graphicsDriverLibraries) Hooks() ([]Hook, error) { switch { case d.isDriverLibrary(filename, "libnvidia-allocator.so"): // gbm/nvidia-drm_gbm.so is a symlink to ../libnvidia-allocator.so.1 which - // in turn symlinks to libnvidia-allocator.so.RM_VERSION and is created - // when ldconfig is run in the container. - // create libnvidia-allocate.so.1 -> libnvidia-allocate.so.RM_VERSION symlink - links = append(links, fmt.Sprintf("%s::%s", filename, filepath.Join(dir, "libnvidia-allocator.so.1"))) + // in turn symlinks to libnvidia-allocator.so.RM_VERSION. + // The libnvidia-allocator.so.1 -> libnvidia-allocator.so.RM_VERSION symlink + // is created when ldconfig is run against the container and there + // is no explicit need to create it. // create gbm/nvidia-drm_gbm.so -> ../libnvidia-allocate.so.1 symlink linkPath := filepath.Join(dir, "gbm", "nvidia-drm_gbm.so") links = append(links, fmt.Sprintf("%s::%s", "../libnvidia-allocator.so.1", linkPath)) diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/none.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/none.go index 2a1d2c57..554e7eab 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/none.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/none.go @@ -24,15 +24,15 @@ var _ Discover = (*None)(nil) // Devices returns an empty list of devices func (e None) Devices() ([]Device, error) { - return []Device{}, nil + return nil, nil } // Mounts returns an empty list of mounts func (e None) Mounts() ([]Mount, error) { - return []Mount{}, nil + return nil, nil } // Hooks returns an empty list of hooks func (e None) Hooks() ([]Hook, error) { - return []Hook{}, nil + return nil, nil } diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/symlinks.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/symlinks.go new file mode 100644 index 00000000..0119de0d --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/discover/symlinks.go @@ -0,0 +1,108 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package discover + +import ( + "fmt" + "path/filepath" +) + +type additionalSymlinks struct { + Discover + version string + nvidiaCDIHookPath string +} + +// WithDriverDotSoSymlinks decorates the provided discoverer. +// A hook is added that checks for specific driver symlinks that need to be created. +func WithDriverDotSoSymlinks(mounts Discover, version string, nvidiaCDIHookPath string) Discover { + if version == "" { + version = "*.*" + } + return &additionalSymlinks{ + Discover: mounts, + nvidiaCDIHookPath: nvidiaCDIHookPath, + version: version, + } +} + +// Hooks returns a hook to create the additional symlinks based on the mounts. +func (d *additionalSymlinks) Hooks() ([]Hook, error) { + mounts, err := d.Discover.Mounts() + if err != nil { + return nil, fmt.Errorf("failed to get library mounts: %v", err) + } + hooks, err := d.Discover.Hooks() + if err != nil { + return nil, fmt.Errorf("failed to get hooks: %v", err) + } + + var links []string + processedPaths := make(map[string]bool) + processedLinks := make(map[string]bool) + for _, mount := range mounts { + if processedPaths[mount.Path] { + continue + } + processedPaths[mount.Path] = true + + for _, link := range d.getLinksForMount(mount.Path) { + if processedLinks[link] { + continue + } + processedLinks[link] = true + links = append(links, link) + } + } + + if len(links) == 0 { + return hooks, nil + } + + hook := CreateCreateSymlinkHook(d.nvidiaCDIHookPath, links).(Hook) + return append(hooks, hook), nil +} + +// getLinksForMount maps the path to created links if any. +func (d additionalSymlinks) getLinksForMount(path string) []string { + dir, filename := filepath.Split(path) + switch { + case d.isDriverLibrary("libcuda.so", filename): + // XXX Many applications wrongly assume that libcuda.so exists (e.g. with dlopen). + // create libcuda.so -> libcuda.so.1 symlink + link := fmt.Sprintf("%s::%s", "libcuda.so.1", filepath.Join(dir, "libcuda.so")) + return []string{link} + case d.isDriverLibrary("libGLX_nvidia.so", filename): + // XXX GLVND requires this symlink for indirect GLX support. + // create libGLX_indirect.so.0 -> libGLX_nvidia.so.VERSION symlink + link := fmt.Sprintf("%s::%s", filename, filepath.Join(dir, "libGLX_indirect.so.0")) + return []string{link} + case d.isDriverLibrary("libnvidia-opticalflow.so", filename): + // XXX Fix missing symlink for libnvidia-opticalflow.so. + // create libnvidia-opticalflow.so -> libnvidia-opticalflow.so.1 symlink + link := fmt.Sprintf("%s::%s", "libnvidia-opticalflow.so.1", filepath.Join(dir, "libnvidia-opticalflow.so")) + return []string{link} + } + return nil +} + +// isDriverLibrary checks whether the specified filename is a specific driver library. +func (d additionalSymlinks) isDriverLibrary(libraryName string, filename string) bool { + pattern := libraryName + "." + d.version + match, _ := filepath.Match(pattern, filename) + return match +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/ldcache.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/ldcache.go index 2f6de2fe..4daf95bc 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/ldcache.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/ldcache.go @@ -22,15 +22,12 @@ import ( "bytes" "encoding/binary" "errors" - "fmt" "os" "path/filepath" - "strings" "syscall" "unsafe" "github.com/NVIDIA/nvidia-container-toolkit/internal/logger" - "github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks" ) const ldcachePath = "/etc/ld.so.cache" @@ -82,10 +79,9 @@ type entry2 struct { // LDCache represents the interface for performing lookups into the LDCache // -//go:generate moq -out ldcache_mock.go . LDCache +//go:generate moq -rm -out ldcache_mock.go . LDCache type LDCache interface { List() ([]string, []string) - Lookup(...string) ([]string, []string) } type ldcache struct { @@ -105,14 +101,7 @@ func New(logger logger.Interface, root string) (LDCache, error) { logger.Debugf("Opening ld.conf at %v", path) f, err := os.Open(path) - if os.IsNotExist(err) { - logger.Warningf("Could not find ld.so.cache at %v; creating empty cache", path) - e := &empty{ - logger: logger, - path: path, - } - return e, nil - } else if err != nil { + if err != nil { return nil, err } defer f.Close() @@ -196,7 +185,7 @@ type entry struct { } // getEntries returns the entires of the ldcache in a go-friendly struct. -func (c *ldcache) getEntries(selected func(string) bool) []entry { +func (c *ldcache) getEntries() []entry { var entries []entry for _, e := range c.entries { bits := 0 @@ -223,9 +212,6 @@ func (c *ldcache) getEntries(selected func(string) bool) []entry { c.logger.Debugf("Skipping invalid lib") continue } - if !selected(lib) { - continue - } value := bytesToString(c.libs[e.Value:]) if value == "" { c.logger.Debugf("Skipping invalid value for lib %v", lib) @@ -236,51 +222,19 @@ func (c *ldcache) getEntries(selected func(string) bool) []entry { bits: bits, value: value, } - entries = append(entries, e) } - return entries } // List creates a list of libraries in the ldcache. // The 32-bit and 64-bit libraries are returned separately. func (c *ldcache) List() ([]string, []string) { - all := func(s string) bool { return true } - - return c.resolveSelected(all) -} - -// Lookup searches the ldcache for the specified prefixes. -// The 32-bit and 64-bit libraries matching the prefixes are returned. -func (c *ldcache) Lookup(libPrefixes ...string) ([]string, []string) { - c.logger.Debugf("Looking up %v in cache", libPrefixes) - - // We define a functor to check whether a given library name matches any of the prefixes - matchesAnyPrefix := func(s string) bool { - for _, p := range libPrefixes { - if strings.HasPrefix(s, p) { - return true - } - } - return false - } - - return c.resolveSelected(matchesAnyPrefix) -} - -// resolveSelected process the entries in the LDCach based on the supplied filter and returns the resolved paths. -// The paths are separated by bittage. -func (c *ldcache) resolveSelected(selected func(string) bool) ([]string, []string) { paths := make(map[int][]string) processed := make(map[string]bool) - for _, e := range c.getEntries(selected) { - path, err := c.resolve(e.value) - if err != nil { - c.logger.Debugf("Could not resolve entry: %v", err) - continue - } + for _, e := range c.getEntries() { + path := filepath.Join(c.root, e.value) if processed[path] { continue } @@ -291,29 +245,6 @@ func (c *ldcache) resolveSelected(selected func(string) bool) ([]string, []strin return paths[32], paths[64] } -// resolve resolves the specified ldcache entry based on the value being processed. -// The input is the name of the entry in the cache. -func (c *ldcache) resolve(target string) (string, error) { - name := filepath.Join(c.root, target) - - c.logger.Debugf("checking %v", name) - - link, err := symlinks.Resolve(name) - if err != nil { - return "", fmt.Errorf("failed to resolve symlink: %v", err) - } - if link == name { - return name, nil - } - - // We return absolute paths for all targets - if !filepath.IsAbs(link) || strings.HasPrefix(link, ".") { - link = filepath.Join(filepath.Dir(target), link) - } - - return c.resolve(link) -} - // bytesToString converts a byte slice to a string. // This assumes that the byte slice is null-terminated func bytesToString(value []byte) string { diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/ldcache_mock.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/ldcache_mock.go index 092a3766..5aa53235 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/ldcache_mock.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/ldcache_mock.go @@ -20,9 +20,6 @@ var _ LDCache = &LDCacheMock{} // ListFunc: func() ([]string, []string) { // panic("mock out the List method") // }, -// LookupFunc: func(strings ...string) ([]string, []string) { -// panic("mock out the Lookup method") -// }, // } // // // use mockedLDCache in code that requires LDCache @@ -33,22 +30,13 @@ type LDCacheMock struct { // ListFunc mocks the List method. ListFunc func() ([]string, []string) - // LookupFunc mocks the Lookup method. - LookupFunc func(strings ...string) ([]string, []string) - // calls tracks calls to the methods. calls struct { // List holds details about calls to the List method. List []struct { } - // Lookup holds details about calls to the Lookup method. - Lookup []struct { - // Strings is the strings argument value. - Strings []string - } } - lockList sync.RWMutex - lockLookup sync.RWMutex + lockList sync.RWMutex } // List calls ListFunc. @@ -77,35 +65,3 @@ func (mock *LDCacheMock) ListCalls() []struct { mock.lockList.RUnlock() return calls } - -// Lookup calls LookupFunc. -func (mock *LDCacheMock) Lookup(strings ...string) ([]string, []string) { - if mock.LookupFunc == nil { - panic("LDCacheMock.LookupFunc: method is nil but LDCache.Lookup was just called") - } - callInfo := struct { - Strings []string - }{ - Strings: strings, - } - mock.lockLookup.Lock() - mock.calls.Lookup = append(mock.calls.Lookup, callInfo) - mock.lockLookup.Unlock() - return mock.LookupFunc(strings...) -} - -// LookupCalls gets all the calls that were made to Lookup. -// Check the length with: -// -// len(mockedLDCache.LookupCalls()) -func (mock *LDCacheMock) LookupCalls() []struct { - Strings []string -} { - var calls []struct { - Strings []string - } - mock.lockLookup.RLock() - calls = mock.calls.Lookup - mock.lockLookup.RUnlock() - return calls -} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/ldcache.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/ldcache.go new file mode 100644 index 00000000..677dafaa --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/ldcache.go @@ -0,0 +1,118 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package lookup + +import ( + "fmt" + "path/filepath" + "slices" + + "github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache" +) + +type ldcacheLocator struct { + *builder + resolvesTo map[string]string +} + +var _ Locator = (*ldcacheLocator)(nil) + +func NewLdcacheLocator(opts ...Option) Locator { + b := newBuilder(opts...) + + cache, err := ldcache.New(b.logger, b.root) + if err != nil { + b.logger.Warningf("Failed to load ldcache: %v", err) + if b.isOptional { + return &null{} + } + return ¬Found{} + } + + chain := NewSymlinkChainLocator(WithOptional(true)) + + resolvesTo := make(map[string]string) + _, libs64 := cache.List() + for _, library := range libs64 { + if _, processed := resolvesTo[library]; processed { + continue + } + candidates, err := chain.Locate(library) + if err != nil { + b.logger.Errorf("error processing library %s from ldcache: %v", library, err) + continue + } + + if len(candidates) == 0 { + resolvesTo[library] = library + continue + } + + // candidates represents a symlink chain. + // The first element represents the start of the chain and the last + // element the final target. + target := candidates[len(candidates)-1] + for _, candidate := range candidates { + resolvesTo[candidate] = target + } + } + + return &ldcacheLocator{ + builder: b, + resolvesTo: resolvesTo, + } +} + +// Locate finds the specified libraryname. +// If the input is a library name, the ldcache is searched otherwise the +// provided path is resolved as a symlink. +func (l ldcacheLocator) Locate(libname string) ([]string, error) { + var matcher func(string, string) bool + + if filepath.IsAbs(libname) { + matcher = func(p string, c string) bool { + m, _ := filepath.Match(filepath.Join(l.root, p), c) + return m + } + } else { + matcher = func(p string, c string) bool { + m, _ := filepath.Match(p, filepath.Base(c)) + return m + } + } + + var matches []string + seen := make(map[string]bool) + for name, target := range l.resolvesTo { + if !matcher(libname, name) { + continue + } + if seen[target] { + continue + } + seen[target] = true + matches = append(matches, target) + } + + slices.Sort(matches) + + if len(matches) == 0 && !l.isOptional { + return nil, fmt.Errorf("%s: %w", libname, ErrNotFound) + } + + return matches, nil +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/library.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/library.go index 7f5cf7c8..6c403d08 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/library.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/library.go @@ -16,20 +16,6 @@ package lookup -import ( - "fmt" - - "github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache" - "github.com/NVIDIA/nvidia-container-toolkit/internal/logger" -) - -type ldcacheLocator struct { - logger logger.Interface - cache ldcache.LDCache -} - -var _ Locator = (*ldcacheLocator)(nil) - // NewLibraryLocator creates a library locator using the specified options. func NewLibraryLocator(opts ...Option) Locator { b := newBuilder(opts...) @@ -63,39 +49,7 @@ func NewLibraryLocator(opts ...Option) Locator { l := First( symlinkLocator, - newLdcacheLocator(opts...), + NewLdcacheLocator(opts...), ) return l } - -func newLdcacheLocator(opts ...Option) Locator { - b := newBuilder(opts...) - - cache, err := ldcache.New(b.logger, b.root) - if err != nil { - // If we failed to open the LDCache, we default to a symlink locator. - b.logger.Warningf("Failed to load ldcache: %v", err) - return nil - } - - return &ldcacheLocator{ - logger: b.logger, - cache: cache, - } -} - -// Locate finds the specified libraryname. -// If the input is a library name, the ldcache is searched otherwise the -// provided path is resolved as a symlink. -func (l ldcacheLocator) Locate(libname string) ([]string, error) { - paths32, paths64 := l.cache.Lookup(libname) - if len(paths32) > 0 { - l.logger.Warningf("Ignoring 32-bit libraries for %v: %v", libname, paths32) - } - - if len(paths64) == 0 { - return nil, fmt.Errorf("64-bit library %v: %w", libname, ErrNotFound) - } - - return paths64, nil -} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/empty.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/null.go similarity index 51% rename from vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/empty.go rename to vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/null.go index 30d3f4c8..938e481b 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache/empty.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/null.go @@ -1,5 +1,5 @@ /** -# Copyright (c) NVIDIA CORPORATION. All rights reserved. +# Copyright 2024 NVIDIA CORPORATION # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,24 +14,23 @@ # limitations under the License. **/ -package ldcache +package lookup -import "github.com/NVIDIA/nvidia-container-toolkit/internal/logger" +import "fmt" -type empty struct { - logger logger.Interface - path string +// A null locator always returns an empty response. +type null struct { } -var _ LDCache = (*empty)(nil) - -// List always returns nil for an empty ldcache -func (e *empty) List() ([]string, []string) { +// Locate always returns empty for a null locator. +func (l *null) Locate(string) ([]string, error) { return nil, nil } -// Lookup logs a debug message and returns nil for an empty ldcache -func (e *empty) Lookup(prefixes ...string) ([]string, []string) { - e.logger.Debugf("Calling Lookup(%v) on empty ldcache: %v", prefixes, e.path) - return nil, nil +// A notFound locator always returns an ErrNotFound error. +type notFound struct { +} + +func (l *notFound) Locate(s string) ([]string, error) { + return nil, fmt.Errorf("%s: %w", s, ErrNotFound) } diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks.go index aa4c147e..c9bab069 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks.go @@ -62,6 +62,7 @@ func (p symlinkChain) Locate(pattern string) ([]string, error) { return candidates, nil } + var filenames []string found := make(map[string]bool) for len(candidates) > 0 { candidate := candidates[0] @@ -70,6 +71,7 @@ func (p symlinkChain) Locate(pattern string) ([]string, error) { continue } found[candidate] = true + filenames = append(filenames, candidate) target, err := symlinks.Resolve(candidate) if err != nil { @@ -88,11 +90,6 @@ func (p symlinkChain) Locate(pattern string) ([]string, error) { candidates = append(candidates, target) } } - - var filenames []string - for f := range found { - filenames = append(filenames, f) - } return filenames, nil } diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks/symlink.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks/symlink.go index 991d47cb..1929aaa9 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks/symlink.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks/symlink.go @@ -25,7 +25,7 @@ import ( func Resolve(filename string) (string, error) { info, err := os.Lstat(filename) if err != nil { - return filename, fmt.Errorf("failed to get file info: %v", info) + return filename, fmt.Errorf("failed to get file info: %w", err) } if info.Mode()&os.ModeSymlink == 0 { return filename, nil diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/api.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/api.go new file mode 100644 index 00000000..6275a5c2 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/api.go @@ -0,0 +1,45 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package nvsandboxutils + +// libraryOptions hold the parameters than can be set by a LibraryOption +type libraryOptions struct { + path string + flags int +} + +// LibraryOption represents a functional option to configure the underlying nvsandboxutils library +type LibraryOption func(*libraryOptions) + +// WithLibraryPath provides an option to set the library name to be used by the nvsandboxutils library. +func WithLibraryPath(path string) LibraryOption { + return func(o *libraryOptions) { + o.path = path + } +} + +// SetLibraryOptions applies the specified options to the nvsandboxutils library. +// If this is called when a library is already loaded, an error is raised. +func SetLibraryOptions(opts ...LibraryOption) error { + libnvsandboxutils.Lock() + defer libnvsandboxutils.Unlock() + if libnvsandboxutils.refcount != 0 { + return errLibraryAlreadyLoaded + } + libnvsandboxutils.init(opts...) + return nil +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/cgo_helpers.h b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/cgo_helpers.h new file mode 100644 index 00000000..23b3c256 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/cgo_helpers.h @@ -0,0 +1,25 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +// WARNING: THIS FILE WAS AUTOMATICALLY GENERATED. +// Code generated by https://git.io/c-for-go. DO NOT EDIT. + +#include "nvsandboxutils.h" +#include +#pragma once + +#define __CGOGEN 1 + diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/cgo_helpers_static.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/cgo_helpers_static.go new file mode 100644 index 00000000..5924d622 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/cgo_helpers_static.go @@ -0,0 +1,38 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package nvsandboxutils + +var cgoAllocsUnknown = new(struct{}) + +func clen(n []byte) int { + for i := 0; i < len(n); i++ { + if n[i] == 0 { + return i + } + } + return len(n) +} + +// Creates an int8 array of fixed input length to store the Go string. +// TODO: Add error check if input string has a length greater than INPUT_LENGTH +func convertStringToFixedArray(str string) [INPUT_LENGTH]int8 { + var output [INPUT_LENGTH]int8 + for i, s := range str { + output[i] = int8(s) + } + return output +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/const.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/const.go new file mode 100644 index 00000000..9e8cdf3f --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/const.go @@ -0,0 +1,156 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +// WARNING: THIS FILE WAS AUTOMATICALLY GENERATED. +// Code generated by https://git.io/c-for-go. DO NOT EDIT. + +package nvsandboxutils + +/* +#cgo linux LDFLAGS: -Wl,--export-dynamic -Wl,--unresolved-symbols=ignore-in-object-files +#cgo darwin LDFLAGS: -Wl,-undefined,dynamic_lookup +#include "nvsandboxutils.h" +#include +#include "cgo_helpers.h" +*/ +import "C" + +const ( + // INPUT_LENGTH as defined in nvsandboxutils/nvsandboxutils.h + INPUT_LENGTH = 256 + // MAX_FILE_PATH as defined in nvsandboxutils/nvsandboxutils.h + MAX_FILE_PATH = 256 + // MAX_NAME_LENGTH as defined in nvsandboxutils/nvsandboxutils.h + MAX_NAME_LENGTH = 256 +) + +// Ret as declared in nvsandboxutils/nvsandboxutils.h +type Ret int32 + +// Ret enumeration from nvsandboxutils/nvsandboxutils.h +const ( + SUCCESS Ret = iota + ERROR_UNINITIALIZED Ret = 1 + ERROR_NOT_SUPPORTED Ret = 2 + ERROR_INVALID_ARG Ret = 3 + ERROR_INSUFFICIENT_SIZE Ret = 4 + ERROR_VERSION_NOT_SUPPORTED Ret = 5 + ERROR_LIBRARY_LOAD Ret = 6 + ERROR_FUNCTION_NOT_FOUND Ret = 7 + ERROR_DEVICE_NOT_FOUND Ret = 8 + ERROR_NVML_LIB_CALL Ret = 9 + ERROR_OUT_OF_MEMORY Ret = 10 + ERROR_FILEPATH_NOT_FOUND Ret = 11 + ERROR_UNKNOWN Ret = 65535 +) + +// LogLevel as declared in nvsandboxutils/nvsandboxutils.h +type LogLevel int32 + +// LogLevel enumeration from nvsandboxutils/nvsandboxutils.h +const ( + LOG_LEVEL_FATAL LogLevel = iota + LOG_LEVEL_ERROR LogLevel = 1 + LOG_LEVEL_WARN LogLevel = 2 + LOG_LEVEL_DEBUG LogLevel = 3 + LOG_LEVEL_INFO LogLevel = 4 + LOG_LEVEL_NONE LogLevel = 65535 +) + +// RootfsInputType as declared in nvsandboxutils/nvsandboxutils.h +type RootfsInputType int32 + +// RootfsInputType enumeration from nvsandboxutils/nvsandboxutils.h +const ( + NV_ROOTFS_DEFAULT RootfsInputType = iota + NV_ROOTFS_PATH RootfsInputType = 1 + NV_ROOTFS_PID RootfsInputType = 2 +) + +// FileType as declared in nvsandboxutils/nvsandboxutils.h +type FileType int32 + +// FileType enumeration from nvsandboxutils/nvsandboxutils.h +const ( + NV_DEV FileType = iota + NV_PROC FileType = 1 + NV_SYS FileType = 2 +) + +// FileSystemSubType as declared in nvsandboxutils/nvsandboxutils.h +type FileSystemSubType int32 + +// FileSystemSubType enumeration from nvsandboxutils/nvsandboxutils.h +const ( + NV_DEV_NVIDIA FileSystemSubType = iota + NV_DEV_DRI_CARD FileSystemSubType = 1 + NV_DEV_DRI_RENDERD FileSystemSubType = 2 + NV_DEV_DRI_CARD_SYMLINK FileSystemSubType = 3 + NV_DEV_DRI_RENDERD_SYMLINK FileSystemSubType = 4 + NV_DEV_NVIDIA_UVM FileSystemSubType = 5 + NV_DEV_NVIDIA_UVM_TOOLS FileSystemSubType = 6 + NV_DEV_NVIDIA_MODESET FileSystemSubType = 7 + NV_DEV_NVIDIA_CTL FileSystemSubType = 8 + NV_DEV_GDRDRV FileSystemSubType = 9 + NV_DEV_NVIDIA_CAPS_NVIDIA_CAP FileSystemSubType = 10 + NV_PROC_DRIVER_NVIDIA_GPUS_PCIBUSID FileSystemSubType = 11 + NV_PROC_DRIVER_NVIDIA_GPUS FileSystemSubType = 12 + NV_PROC_NVIDIA_PARAMS FileSystemSubType = 13 + NV_PROC_NVIDIA_CAPS_MIG_MINORS FileSystemSubType = 14 + NV_PROC_DRIVER_NVIDIA_CAPABILITIES_GPU FileSystemSubType = 15 + NV_PROC_DRIVER_NVIDIA_CAPABILITIES FileSystemSubType = 16 + NV_PROC_DRIVER_NVIDIA_CAPABILITIIES_GPU_MIG_CI_ACCESS FileSystemSubType = 17 + NV_SYS_MODULE_NVIDIA_DRIVER_PCIBUSID FileSystemSubType = 18 + NV_SYS_MODULE_NVIDIA_DRIVER FileSystemSubType = 19 + NV_NUM_SUBTYPE FileSystemSubType = 20 +) + +// FileModule as declared in nvsandboxutils/nvsandboxutils.h +type FileModule int32 + +// FileModule enumeration from nvsandboxutils/nvsandboxutils.h +const ( + NV_GPU FileModule = iota + NV_MIG FileModule = 1 + NV_DRIVER_NVIDIA FileModule = 2 + NV_DRIVER_NVIDIA_UVM FileModule = 3 + NV_DRIVER_NVIDIA_MODESET FileModule = 4 + NV_DRIVER_GDRDRV FileModule = 5 + NV_SYSTEM FileModule = 6 +) + +// FileFlag as declared in nvsandboxutils/nvsandboxutils.h +type FileFlag int32 + +// FileFlag enumeration from nvsandboxutils/nvsandboxutils.h +const ( + NV_FILE_FLAG_HINT FileFlag = 1 + NV_FILE_FLAG_MASKOUT FileFlag = 2 + NV_FILE_FLAG_CONTENT FileFlag = 4 + NV_FILE_FLAG_DEPRECTATED FileFlag = 8 + NV_FILE_FLAG_CANDIDATES FileFlag = 16 +) + +// GpuInputType as declared in nvsandboxutils/nvsandboxutils.h +type GpuInputType int32 + +// GpuInputType enumeration from nvsandboxutils/nvsandboxutils.h +const ( + NV_GPU_INPUT_GPU_UUID GpuInputType = iota + NV_GPU_INPUT_MIG_UUID GpuInputType = 1 + NV_GPU_INPUT_PCI_ID GpuInputType = 2 + NV_GPU_INPUT_PCI_INDEX GpuInputType = 3 +) diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/doc.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/doc.go new file mode 100644 index 00000000..231c68c2 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/doc.go @@ -0,0 +1,23 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +// WARNING: THIS FILE WAS AUTOMATICALLY GENERATED. +// Code generated by https://git.io/c-for-go. DO NOT EDIT. + +/* +Package NVSANDBOXUTILS bindings +*/ +package nvsandboxutils diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/dynamicLibrary_mock.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/dynamicLibrary_mock.go new file mode 100644 index 00000000..a22e5669 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/dynamicLibrary_mock.go @@ -0,0 +1,157 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package nvsandboxutils + +import ( + "sync" +) + +// Ensure, that dynamicLibraryMock does implement dynamicLibrary. +// If this is not the case, regenerate this file with moq. +var _ dynamicLibrary = &dynamicLibraryMock{} + +// dynamicLibraryMock is a mock implementation of dynamicLibrary. +// +// func TestSomethingThatUsesdynamicLibrary(t *testing.T) { +// +// // make and configure a mocked dynamicLibrary +// mockeddynamicLibrary := &dynamicLibraryMock{ +// CloseFunc: func() error { +// panic("mock out the Close method") +// }, +// LookupFunc: func(s string) error { +// panic("mock out the Lookup method") +// }, +// OpenFunc: func() error { +// panic("mock out the Open method") +// }, +// } +// +// // use mockeddynamicLibrary in code that requires dynamicLibrary +// // and then make assertions. +// +// } +type dynamicLibraryMock struct { + // CloseFunc mocks the Close method. + CloseFunc func() error + + // LookupFunc mocks the Lookup method. + LookupFunc func(s string) error + + // OpenFunc mocks the Open method. + OpenFunc func() error + + // calls tracks calls to the methods. + calls struct { + // Close holds details about calls to the Close method. + Close []struct { + } + // Lookup holds details about calls to the Lookup method. + Lookup []struct { + // S is the s argument value. + S string + } + // Open holds details about calls to the Open method. + Open []struct { + } + } + lockClose sync.RWMutex + lockLookup sync.RWMutex + lockOpen sync.RWMutex +} + +// Close calls CloseFunc. +func (mock *dynamicLibraryMock) Close() error { + callInfo := struct { + }{} + mock.lockClose.Lock() + mock.calls.Close = append(mock.calls.Close, callInfo) + mock.lockClose.Unlock() + if mock.CloseFunc == nil { + var ( + errOut error + ) + return errOut + } + return mock.CloseFunc() +} + +// CloseCalls gets all the calls that were made to Close. +// Check the length with: +// +// len(mockeddynamicLibrary.CloseCalls()) +func (mock *dynamicLibraryMock) CloseCalls() []struct { +} { + var calls []struct { + } + mock.lockClose.RLock() + calls = mock.calls.Close + mock.lockClose.RUnlock() + return calls +} + +// Lookup calls LookupFunc. +func (mock *dynamicLibraryMock) Lookup(s string) error { + callInfo := struct { + S string + }{ + S: s, + } + mock.lockLookup.Lock() + mock.calls.Lookup = append(mock.calls.Lookup, callInfo) + mock.lockLookup.Unlock() + if mock.LookupFunc == nil { + var ( + errOut error + ) + return errOut + } + return mock.LookupFunc(s) +} + +// LookupCalls gets all the calls that were made to Lookup. +// Check the length with: +// +// len(mockeddynamicLibrary.LookupCalls()) +func (mock *dynamicLibraryMock) LookupCalls() []struct { + S string +} { + var calls []struct { + S string + } + mock.lockLookup.RLock() + calls = mock.calls.Lookup + mock.lockLookup.RUnlock() + return calls +} + +// Open calls OpenFunc. +func (mock *dynamicLibraryMock) Open() error { + callInfo := struct { + }{} + mock.lockOpen.Lock() + mock.calls.Open = append(mock.calls.Open, callInfo) + mock.lockOpen.Unlock() + if mock.OpenFunc == nil { + var ( + errOut error + ) + return errOut + } + return mock.OpenFunc() +} + +// OpenCalls gets all the calls that were made to Open. +// Check the length with: +// +// len(mockeddynamicLibrary.OpenCalls()) +func (mock *dynamicLibraryMock) OpenCalls() []struct { +} { + var calls []struct { + } + mock.lockOpen.RLock() + calls = mock.calls.Open + mock.lockOpen.RUnlock() + return calls +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/gpu-resources.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/gpu-resources.go new file mode 100644 index 00000000..19dec07e --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/gpu-resources.go @@ -0,0 +1,67 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package nvsandboxutils + +import ( + "strings" + "unsafe" +) + +import "C" + +type GpuResource struct { + Version uint32 +} + +type GpuFileInfo struct { + Path string + Type FileType + SubType FileSystemSubType + Module FileModule + Flags FileFlag +} + +func (l *library) GetGpuResource(uuid string) ([]GpuFileInfo, Ret) { + deviceType := NV_GPU_INPUT_GPU_UUID + if strings.HasPrefix(uuid, "MIG-") { + deviceType = NV_GPU_INPUT_MIG_UUID + } + + request := GpuRes{ + Version: 1, + InputType: uint32(deviceType), + Input: convertStringToFixedArray(uuid), + } + + ret := nvSandboxUtilsGetGpuResource(&request) + if ret != SUCCESS { + return nil, ret + } + + var fileInfos []GpuFileInfo + for fileInfo := request.Files; fileInfo != nil; fileInfo = fileInfo.Next { + fi := GpuFileInfo{ + Path: C.GoString((*C.char)(unsafe.Pointer(fileInfo.FilePath))), + Type: FileType(fileInfo.FileType), + SubType: FileSystemSubType(fileInfo.FileSubType), + Module: FileModule(fileInfo.Module), + Flags: FileFlag(fileInfo.Flags), + } + fileInfos = append(fileInfos, fi) + } + return fileInfos, SUCCESS +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/impl.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/impl.go new file mode 100644 index 00000000..0f6948a2 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/impl.go @@ -0,0 +1,64 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package nvsandboxutils + +import "C" + +func (l *library) Init(path string) Ret { + if err := l.load(); err != nil { + return ERROR_LIBRARY_LOAD + } + + input := InitInput{ + Version: 1, + Type: uint32(NV_ROOTFS_PATH), + Value: convertStringToFixedArray(path), + } + + return nvSandboxUtilsInit(&input) +} + +func (l *library) Shutdown() Ret { + ret := nvSandboxUtilsShutdown() + if ret != SUCCESS { + return ret + } + + err := l.close() + if err != nil { + return ERROR_UNKNOWN + } + + return ret +} + +// TODO: Is this length specified in the header file? +const VERSION_LENGTH = 100 + +func (l *library) GetDriverVersion() (string, Ret) { + Version := make([]byte, VERSION_LENGTH) + ret := nvSandboxUtilsGetDriverVersion(&Version[0], VERSION_LENGTH) + return string(Version[:clen(Version)]), ret +} + +func (l *library) GetFileContent(path string) (string, Ret) { + Content := make([]byte, MAX_FILE_PATH) + FilePath := []byte(path + string(byte(0))) + Size := uint32(MAX_FILE_PATH) + ret := nvSandboxUtilsGetFileContent(&FilePath[0], &Content[0], &Size) + return string(Content[:clen(Content)]), ret +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/lib.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/lib.go new file mode 100644 index 00000000..3a85ef89 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/lib.go @@ -0,0 +1,156 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package nvsandboxutils + +import ( + "errors" + "fmt" + "sync" + + "github.com/NVIDIA/go-nvml/pkg/dl" +) + +const ( + defaultNvSandboxUtilsLibraryName = "libnvidia-sandboxutils.so.1" + defaultNvSandboxUtilsLibraryLoadFlags = dl.RTLD_LAZY | dl.RTLD_GLOBAL +) + +var errLibraryNotLoaded = errors.New("library not loaded") +var errLibraryAlreadyLoaded = errors.New("library already loaded") + +// dynamicLibrary is an interface for abstacting the underlying library. +// This also allows for mocking and testing. + +//go:generate moq -rm -stub -out dynamicLibrary_mock.go . dynamicLibrary +type dynamicLibrary interface { + Lookup(string) error + Open() error + Close() error +} + +// library represents an nvsandboxutils library. +// This includes a reference to the underlying DynamicLibrary +type library struct { + sync.Mutex + path string + refcount refcount + dl dynamicLibrary +} + +// libnvsandboxutils is a global instance of the nvsandboxutils library. +var libnvsandboxutils = newLibrary() + +func New(opts ...LibraryOption) Interface { + return newLibrary(opts...) +} + +func newLibrary(opts ...LibraryOption) *library { + l := &library{} + l.init(opts...) + return l +} + +func (l *library) init(opts ...LibraryOption) { + o := libraryOptions{} + for _, opt := range opts { + opt(&o) + } + + if o.path == "" { + o.path = defaultNvSandboxUtilsLibraryName + } + if o.flags == 0 { + o.flags = defaultNvSandboxUtilsLibraryLoadFlags + } + + l.path = o.path + l.dl = dl.New(o.path, o.flags) +} + +// LookupSymbol checks whether the specified library symbol exists in the library. +// Note that this requires that the library be loaded. +func (l *library) LookupSymbol(name string) error { + if l == nil || l.refcount == 0 { + return fmt.Errorf("error looking up %s: %w", name, errLibraryNotLoaded) + } + return l.dl.Lookup(name) +} + +// load initializes the library and updates the versioned symbols. +// Multiple calls to an already loaded library will return without error. +func (l *library) load() (rerr error) { + l.Lock() + defer l.Unlock() + + defer func() { l.refcount.IncOnNoError(rerr) }() + if l.refcount > 0 { + return nil + } + + if err := l.dl.Open(); err != nil { + return fmt.Errorf("error opening %s: %w", l.path, err) + } + + // Update the errorStringFunc to point to nvsandboxutils.ErrorString + errorStringFunc = nvsanboxutilsErrorString + + // Update all versioned symbols + l.updateVersionedSymbols() + + return nil +} + +// close the underlying library and ensure that the global pointer to the +// library is set to nil to ensure that subsequent calls to open will reinitialize it. +// Multiple calls to an already closed nvsandboxutils library will return without error. +func (l *library) close() (rerr error) { + l.Lock() + defer l.Unlock() + + defer func() { l.refcount.DecOnNoError(rerr) }() + if l.refcount != 1 { + return nil + } + + if err := l.dl.Close(); err != nil { + return fmt.Errorf("error closing %s: %w", l.path, err) + } + + // Update the errorStringFunc to point to defaultErrorStringFunc + errorStringFunc = defaultErrorStringFunc + + return nil +} + +// Default all versioned APIs to v1 (to infer the types) +var ( +// Insert default versions for APIs here. +// Example: +// nvsandboxUtilsFunction = nvsandboxUtilsFunction_v1 +) + +// updateVersionedSymbols checks for versioned symbols in the loaded dynamic library. +// If newer versioned symbols exist, these replace the default `v1` symbols initialized above. +// When new versioned symbols are added, these would have to be initialized above and have +// corresponding checks and subsequent assignments added below. +func (l *library) updateVersionedSymbols() { + // Example: + // err := l.dl.Lookup("nvsandboxUtilsFunction_v2") + // if err == nil { + // nvsandboxUtilsFunction = nvsandboxUtilsFunction_v2 + // } +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/nvsandboxutils.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/nvsandboxutils.go new file mode 100644 index 00000000..29544bc9 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/nvsandboxutils.go @@ -0,0 +1,72 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +// WARNING: THIS FILE WAS AUTOMATICALLY GENERATED. +// Code generated by https://git.io/c-for-go. DO NOT EDIT. + +package nvsandboxutils + +/* +#cgo linux LDFLAGS: -Wl,--export-dynamic -Wl,--unresolved-symbols=ignore-in-object-files +#cgo darwin LDFLAGS: -Wl,-undefined,dynamic_lookup +#include "nvsandboxutils.h" +#include +#include "cgo_helpers.h" +*/ +import "C" +import "unsafe" + +// nvSandboxUtilsInit function as declared in nvsandboxutils/nvsandboxutils.h +func nvSandboxUtilsInit(Input *InitInput) Ret { + cInput, _ := (*C.nvSandboxUtilsInitInput_t)(unsafe.Pointer(Input)), cgoAllocsUnknown + __ret := C.nvSandboxUtilsInit(cInput) + __v := (Ret)(__ret) + return __v +} + +// nvSandboxUtilsShutdown function as declared in nvsandboxutils/nvsandboxutils.h +func nvSandboxUtilsShutdown() Ret { + __ret := C.nvSandboxUtilsShutdown() + __v := (Ret)(__ret) + return __v +} + +// nvSandboxUtilsGetDriverVersion function as declared in nvsandboxutils/nvsandboxutils.h +func nvSandboxUtilsGetDriverVersion(Version *byte, Length uint32) Ret { + cVersion, _ := (*C.char)(unsafe.Pointer(Version)), cgoAllocsUnknown + cLength, _ := (C.uint)(Length), cgoAllocsUnknown + __ret := C.nvSandboxUtilsGetDriverVersion(cVersion, cLength) + __v := (Ret)(__ret) + return __v +} + +// nvSandboxUtilsGetGpuResource function as declared in nvsandboxutils/nvsandboxutils.h +func nvSandboxUtilsGetGpuResource(Request *GpuRes) Ret { + cRequest, _ := (*C.nvSandboxUtilsGpuRes_t)(unsafe.Pointer(Request)), cgoAllocsUnknown + __ret := C.nvSandboxUtilsGetGpuResource(cRequest) + __v := (Ret)(__ret) + return __v +} + +// nvSandboxUtilsGetFileContent function as declared in nvsandboxutils/nvsandboxutils.h +func nvSandboxUtilsGetFileContent(FilePath *byte, Content *byte, ContentSize *uint32) Ret { + cFilePath, _ := (*C.char)(unsafe.Pointer(FilePath)), cgoAllocsUnknown + cContent, _ := (*C.char)(unsafe.Pointer(Content)), cgoAllocsUnknown + cContentSize, _ := (*C.uint)(unsafe.Pointer(ContentSize)), cgoAllocsUnknown + __ret := C.nvSandboxUtilsGetFileContent(cFilePath, cContent, cContentSize) + __v := (Ret)(__ret) + return __v +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/nvsandboxutils.h b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/nvsandboxutils.h new file mode 100644 index 00000000..3c66e159 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/nvsandboxutils.h @@ -0,0 +1,298 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NVSANDBOXUTILS_H__ +#define __NVSANDBOXUTILS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define INPUT_LENGTH 256 +#define MAX_FILE_PATH 256 +#define MAX_NAME_LENGTH 256 + +/***************************************************************************************************/ +/** @defgroup enums Enumerations + * @{ + */ +/***************************************************************************************************/ + +/** + * Return types + */ +typedef enum +{ + NVSANDBOXUTILS_SUCCESS = 0, //!< The operation was successful + NVSANDBOXUTILS_ERROR_UNINITIALIZED = 1, //!< The library wasn't successfully initialized + NVSANDBOXUTILS_ERROR_NOT_SUPPORTED = 2, //!< The requested operation is not supported on target device + NVSANDBOXUTILS_ERROR_INVALID_ARG = 3, //!< A supplied argument is invalid + NVSANDBOXUTILS_ERROR_INSUFFICIENT_SIZE = 4, //!< A supplied argument is not large enough + NVSANDBOXUTILS_ERROR_VERSION_NOT_SUPPORTED = 5, //!< Requested library version is not supported + NVSANDBOXUTILS_ERROR_LIBRARY_LOAD = 6, //!< The library load failed + NVSANDBOXUTILS_ERROR_FUNCTION_NOT_FOUND = 7, //!< Called function was not found + NVSANDBOXUTILS_ERROR_DEVICE_NOT_FOUND = 8, //!< Target device was not found + NVSANDBOXUTILS_ERROR_NVML_LIB_CALL = 9, //!< NVML library call failed + NVSANDBOXUTILS_ERROR_OUT_OF_MEMORY = 10, //!< There is insufficient memory + NVSANDBOXUTILS_ERROR_FILEPATH_NOT_FOUND = 11, //!< A supplied file path was not found + NVSANDBOXUTILS_ERROR_UNKNOWN = 0xFFFF, //!< Unknown error occurred +} nvSandboxUtilsRet_t; + +/** + * Return if there is an error + */ +#define RETURN_ON_SANDBOX_ERROR(result) \ + if ((result) != NVSANDBOXUTILS_SUCCESS) { \ + NVSANDBOXUTILS_ERROR_MSG("%s %d result=%d", __func__, __LINE__, result); \ + return result; \ + } + +/** + * Log levels + */ +typedef enum +{ + NVSANDBOXUTILS_LOG_LEVEL_FATAL = 0, //!< Log fatal errors + NVSANDBOXUTILS_LOG_LEVEL_ERROR = 1, //!< Log all errors + NVSANDBOXUTILS_LOG_LEVEL_WARN = 2, //!< Log all warnings + NVSANDBOXUTILS_LOG_LEVEL_DEBUG = 3, //!< Log all debug messages + NVSANDBOXUTILS_LOG_LEVEL_INFO = 4, //!< Log all info messages + NVSANDBOXUTILS_LOG_LEVEL_NONE = 0xFFFF, //!< Log none +} nvSandboxUtilsLogLevel_t; + +/** + * Input rootfs to help access files inside the driver container + */ +typedef enum +{ + NV_ROOTFS_DEFAULT, //!< Default no rootfs + NV_ROOTFS_PATH, //!< /run/nvidia/driver + NV_ROOTFS_PID, //!< /proc/PID/mountinfo +} nvSandboxUtilsRootfsInputType_t; + +/** + * File type + */ +typedef enum +{ + NV_DEV, //!< /dev file system + NV_PROC, //!< /proc file system + NV_SYS, //!< /sys file system +} nvSandboxUtilsFileType_t; + +/** + * File subtype + */ +typedef enum +{ + NV_DEV_NVIDIA, //!< /dev/nvidia0 + NV_DEV_DRI_CARD, //!< /dev/dri/card1 + NV_DEV_DRI_RENDERD, //!< /dev/dri/renderD128 + NV_DEV_DRI_CARD_SYMLINK, //!< /dev/dri/by-path/pci-0000:41:00.0-card + NV_DEV_DRI_RENDERD_SYMLINK, //!< /dev/dri/by-path/pci-0000:41:00.0-render + NV_DEV_NVIDIA_UVM, //!< /dev/nvidia-uvm + NV_DEV_NVIDIA_UVM_TOOLS, //!< /dev/nvidia-uvm-tools + NV_DEV_NVIDIA_MODESET, //!< /dev/nvidia-uvm-modeset + NV_DEV_NVIDIA_CTL, //!< /dev/nvidiactl + NV_DEV_GDRDRV, //!< /dev/gdrdrv + NV_DEV_NVIDIA_CAPS_NVIDIA_CAP, //!< /dev/nvidia-caps/nvidia-cap22 + NV_PROC_DRIVER_NVIDIA_GPUS_PCIBUSID, //!< /proc/driver/nvidia/gpus/0000:2d:00.0 + NV_PROC_DRIVER_NVIDIA_GPUS, //!< /proc/driver/nvidia/gpus (for mask out) + NV_PROC_NVIDIA_PARAMS, //!< /proc/driver/nvidia/params + NV_PROC_NVIDIA_CAPS_MIG_MINORS, //!< /proc/driver/nvidia-caps/mig-minors + NV_PROC_DRIVER_NVIDIA_CAPABILITIES_GPU, //!< /proc/driver/nvidia/capabilities/gpu0 + NV_PROC_DRIVER_NVIDIA_CAPABILITIES, //!< /proc/driver/nvidia/capabilities (for mask out) + NV_PROC_DRIVER_NVIDIA_CAPABILITIIES_GPU_MIG_CI_ACCESS, //!< proc/driver/nvidia/capabilities/gpu0/mig/gi2/ci0/access + NV_SYS_MODULE_NVIDIA_DRIVER_PCIBUSID, //!< /sys/module/nvidia/drivers/pci:nvidia/0000:2d:00.0 + NV_SYS_MODULE_NVIDIA_DRIVER, //!< /sys/module/nvidia/drivers/pci:nvidia (for mask out) + NV_NUM_SUBTYPE, // always at the end. +} nvSandboxUtilsFileSystemSubType_t; + +/** + * File module + */ +typedef enum +{ + NV_GPU, //!< Target device + NV_MIG, //!< Target device- MIG + NV_DRIVER_NVIDIA, //!< NVIDIA kernel driver + NV_DRIVER_NVIDIA_UVM, //!< NVIDIA kernel driver-UVM + NV_DRIVER_NVIDIA_MODESET, //!< NVIDIA kernel driver-modeset + NV_DRIVER_GDRDRV, //!< GDRDRV driver + NV_SYSTEM, //!< System module +} nvSandboxUtilsFileModule_t; + +/** + * Flag to provide additional details about the file + */ +typedef enum +{ + NV_FILE_FLAG_HINT = (1 << 0), //!< Default no hint + NV_FILE_FLAG_MASKOUT = (1 << 1), //!< For /proc/driver/nvidia/gpus + NV_FILE_FLAG_CONTENT = (1 << 2), //!< For /proc/driver/nvidia/params + //!< For SYMLINK + //!< Use \p nvSandboxUtilsGetFileContent to get name of the linked file + NV_FILE_FLAG_DEPRECTATED = (1 << 3), //!< For all the FIRMWARE GSP file + NV_FILE_FLAG_CANDIDATES = (1 << 4), //!< For libcuda.so +} nvSandboxUtilsFileFlag_t; + +/** + * Input type of the target device + */ +typedef enum +{ + NV_GPU_INPUT_GPU_UUID, //!< GPU UUID + NV_GPU_INPUT_MIG_UUID, //!< MIG UUID + NV_GPU_INPUT_PCI_ID, //!< PCIe DBDF ID + NV_GPU_INPUT_PCI_INDEX, //!< PCIe bus order (0 points to the GPU that has lowest PCIe BDF) +} nvSandboxUtilsGpuInputType_t; + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup dataTypes Structures and Unions + * @{ + */ +/***************************************************************************************************/ + +/** + * Initalization input v1 + */ +typedef struct +{ + unsigned int version; //!< Version for the structure + nvSandboxUtilsRootfsInputType_t type; //!< One of \p nvSandboxUtilsRootfsInputType_t + char value[INPUT_LENGTH]; //!< String representation of input +} nvSandboxUtilsInitInput_v1_t; + +typedef nvSandboxUtilsInitInput_v1_t nvSandboxUtilsInitInput_t; + +/** + * File system information + */ +typedef struct nvSandboxUtilsGpuFileInfo_v1_t +{ + struct nvSandboxUtilsGpuFileInfo_v1_t *next; //!< Pointer to the next node in the linked list + nvSandboxUtilsFileType_t fileType; //!< One of \p nvSandboxUtilsFileType_t + nvSandboxUtilsFileSystemSubType_t fileSubType; //!< One of \p nvSandboxUtilsFileSystemSubType_t + nvSandboxUtilsFileModule_t module; //!< One of \p nvSandboxUtilsFileModule_t + nvSandboxUtilsFileFlag_t flags; //!< One of \p nvSandboxUtilsFileFlag_t + char *filePath; //!< Relative file path to rootfs +}nvSandboxUtilsGpuFileInfo_v1_t; + +/** + * GPU resource request v1 + */ +typedef struct +{ + unsigned int version; //!< Version for the structure + nvSandboxUtilsGpuInputType_t inputType; //!< One of \p nvSandboxUtilsGpuInputType_t + char input[INPUT_LENGTH]; //!< String representation of input + nvSandboxUtilsGpuFileInfo_v1_t *files; //!< Linked list of \ref nvSandboxUtilsGpuFileInfo_v1_t +} nvSandboxUtilsGpuRes_v1_t; + +typedef nvSandboxUtilsGpuRes_v1_t nvSandboxUtilsGpuRes_t; + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup funcs Functions + * @{ + */ +/***************************************************************************************************/ + +/* ************************************************* + * Initialize library + * ************************************************* + */ +/** + * Prepare library resources before library API can be used. + * This initialization will not fail if one of the initialization prerequisites fails. + * @param input Reference to the called-supplied input struct that has initialization fields + * + * @returns @ref NVSANDBOXUTILS_SUCCESS on success + * @returns @ref NVSANDBOXUTILS_ERROR_INVALID_ARG if \p input->value isn't a valid rootfs path + * @returns @ref NVSANDBOXUTILS_ERROR_VERSION_NOT_SUPPORTED if \p input->version isn't supported by the library + * @returns @ref NVSANDBOXUTILS_ERROR_FILEPATH_NOT_FOUND if any of the required file paths are not found during initialization + * @returns @ref NVSANDBOXUTILS_ERROR_OUT_OF_MEMORY if there is insufficient system memory during initialization + * @returns @ref NVSANDBOXUTILS_ERROR_LIBRARY_LOAD on any error during loading the library + */ +nvSandboxUtilsRet_t nvSandboxUtilsInit(nvSandboxUtilsInitInput_t *input); + +/* ************************************************* + * Shutdown library + * ************************************************* + */ +/** + * Clean up library resources created by init call + * + * @returns @ref NVSANDBOXUTILS_SUCCESS on success + */ +nvSandboxUtilsRet_t nvSandboxUtilsShutdown(void); + +/* ************************************************* + * Get NVIDIA RM driver version + * ************************************************* + */ +/** + * Get NVIDIA RM driver version + * @param version Reference to caller-supplied buffer to return driver version string + * @param length The maximum allowed length of the string returned in \p version + * + * @returns @ref NVSANDBOXUTILS_SUCCESS on success + * @returns @ref NVSANDBOXUTILS_ERROR_INVALID_ARG if \p version is NULL + * @returns @ref NVSANDBOXUTILS_ERROR_NVML_LIB_CALL on any error during driver version query from NVML + */ +nvSandboxUtilsRet_t nvSandboxUtilsGetDriverVersion(char *version, unsigned int length); + +/* ************************************************* + * Get /dev, /proc, /sys file system information + * ************************************************* + */ +/** + * Get /dev, /proc, /sys file system information + * @param request Reference to caller-supplied request struct to return the file system information + * + * @returns @ref NVSANDBOXUTILS_SUCCESS on success + * @returns @ref NVSANDBOXUTILS_ERROR_INVALID_ARG if \p request->input doesn't match any device + * @returns @ref NVSANDBOXUTILS_ERROR_VERSION_NOT_SUPPORTED if \p request->version isn't supported by the library + */ +nvSandboxUtilsRet_t nvSandboxUtilsGetGpuResource(nvSandboxUtilsGpuRes_t *request); + +/* ************************************************* + * Get content of given file path + * ************************************************* + */ +/** + * Get file content of input file path + * @param filePath Reference to the file path + * @param content Reference to the caller-supplied buffer to return the file content + * @param contentSize Reference to the maximum allowed size of content. It is updated to the actual size of the content on return + * + * @returns @ref NVSANDBOXUTILS_SUCCESS on success + * @returns @ref NVSANDBOXUTILS_ERROR_INVALID_ARG if \p filePath or \p content is NULL + * @returns @ref NVSANDBOXUTILS_ERROR_INSUFFICIENT_SIZE if \p contentSize is too small + * @returns @ref NVSANDBOXUTILS_ERROR_FILEPATH_NOT_FOUND on an error while obtaining the content for the file path + */ +nvSandboxUtilsRet_t nvSandboxUtilsGetFileContent(char *filePath, char *content, unsigned int *contentSize); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // __NVSANDBOXUTILS_H__ diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/refcount.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/refcount.go new file mode 100644 index 00000000..f93107b0 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/refcount.go @@ -0,0 +1,31 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package nvsandboxutils + +type refcount int + +func (r *refcount) IncOnNoError(err error) { + if err == nil { + (*r)++ + } +} + +func (r *refcount) DecOnNoError(err error) { + if err == nil && (*r) > 0 { + (*r)-- + } +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/return.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/return.go new file mode 100644 index 00000000..90d4ed84 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/return.go @@ -0,0 +1,74 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package nvsandboxutils + +import ( + "fmt" +) + +// nvsandboxutils.ErrorString() +func (l *library) ErrorString(r Ret) string { + return r.Error() +} + +// String returns the string representation of a Ret. +func (r Ret) String() string { + return r.Error() +} + +// Error returns the string representation of a Ret. +func (r Ret) Error() string { + return errorStringFunc(r) +} + +// Assigned to nvsandboxutils.ErrorString if the system nvsandboxutils library is in use. +var errorStringFunc = defaultErrorStringFunc + +// nvsanboxutilsErrorString is an alias for the default error string function. +var nvsanboxutilsErrorString = defaultErrorStringFunc + +// defaultErrorStringFunc provides a basic nvsandboxutils.ErrorString implementation. +// This allows the nvsandboxutils.ErrorString function to be used even if the nvsandboxutils library +// is not loaded. +var defaultErrorStringFunc = func(r Ret) string { + switch r { + case SUCCESS: + return "SUCCESS" + case ERROR_UNINITIALIZED: + return "ERROR_UNINITIALIZED" + case ERROR_NOT_SUPPORTED: + return "ERROR_NOT_SUPPORTED" + case ERROR_INVALID_ARG: + return "ERROR_INVALID_ARG" + case ERROR_INSUFFICIENT_SIZE: + return "ERROR_INSUFFICIENT_SIZE" + case ERROR_VERSION_NOT_SUPPORTED: + return "ERROR_VERSION_NOT_SUPPORTED" + case ERROR_LIBRARY_LOAD: + return "ERROR_LIBRARY_LOAD" + case ERROR_FUNCTION_NOT_FOUND: + return "ERROR_FUNCTION_NOT_FOUND" + case ERROR_DEVICE_NOT_FOUND: + return "ERROR_DEVICE_NOT_FOUND" + case ERROR_NVML_LIB_CALL: + return "ERROR_NVML_LIB_CALL" + case ERROR_UNKNOWN: + return "ERROR_UNKNOWN" + default: + return fmt.Sprintf("unknown return value: %d", r) + } +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/types_gen.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/types_gen.go new file mode 100644 index 00000000..90a00ed6 --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/types_gen.go @@ -0,0 +1,39 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs types.go + +package nvsandboxutils + +type InitInput_v1 struct { + Version uint32 + Type uint32 + Value [256]int8 +} + +type InitInput struct { + Version uint32 + Type uint32 + Value [256]int8 +} + +type GpuFileInfo_v1 struct { + Next *GpuFileInfo_v1 + FileType uint32 + FileSubType uint32 + Module uint32 + Flags uint32 + FilePath *int8 +} + +type GpuRes_v1 struct { + Version uint32 + InputType uint32 + Input [256]int8 + Files *GpuFileInfo_v1 +} + +type GpuRes struct { + Version uint32 + InputType uint32 + Input [256]int8 + Files *GpuFileInfo_v1 +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/zz_generated.api.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/zz_generated.api.go new file mode 100644 index 00000000..1cc2b01a --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils/zz_generated.api.go @@ -0,0 +1,43 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +// Generated Code; DO NOT EDIT. + +package nvsandboxutils + +// The variables below represent package level methods from the library type. +var ( + ErrorString = libnvsandboxutils.ErrorString + GetDriverVersion = libnvsandboxutils.GetDriverVersion + GetFileContent = libnvsandboxutils.GetFileContent + GetGpuResource = libnvsandboxutils.GetGpuResource + Init = libnvsandboxutils.Init + LookupSymbol = libnvsandboxutils.LookupSymbol + Shutdown = libnvsandboxutils.Shutdown +) + +// Interface represents the interface for the library type. +// +//go:generate moq -out mock/interface.go -pkg mock . Interface:Interface +type Interface interface { + ErrorString(Ret) string + GetDriverVersion() (string, Ret) + GetFileContent(string) (string, Ret) + GetGpuResource(string) ([]GpuFileInfo, Ret) + Init(string) Ret + LookupSymbol(string) error + Shutdown() Ret +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/dgpu.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/dgpu.go index 00982a62..de411bd6 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/dgpu.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/dgpu.go @@ -17,28 +17,91 @@ package dgpu import ( + "errors" + "github.com/NVIDIA/go-nvlib/pkg/nvlib/device" "github.com/NVIDIA/nvidia-container-toolkit/internal/discover" "github.com/NVIDIA/nvidia-container-toolkit/internal/logger" + "github.com/NVIDIA/nvidia-container-toolkit/internal/nvcaps" ) // NewForDevice creates a discoverer for the specified Device. +// nvsandboxutils is used for discovery if specified, otherwise NVML is used. func NewForDevice(d device.Device, opts ...Option) (discover.Discover, error) { - o := &options{} - for _, opt := range opts { - opt(o) + o := new(opts...) + + var discoverers []discover.Discover + var errs error + nvsandboxutilsDiscoverer, err := o.newNvsandboxutilsDGPUDiscoverer(d) + if err != nil { + // TODO: Log a warning + errs = errors.Join(errs, err) + } else if nvsandboxutilsDiscoverer != nil { + discoverers = append(discoverers, nvsandboxutilsDiscoverer) } - if o.logger == nil { - o.logger = logger.New() + nvmlDiscoverer, err := o.newNvmlDGPUDiscoverer(&toRequiredInfo{d}) + if err != nil { + // TODO: Log a warning + errs = errors.Join(errs, err) + } else if nvmlDiscoverer != nil { + discoverers = append(discoverers, nvmlDiscoverer) + } + + if len(discoverers) == 0 { + return nil, errs } - return o.newNvmlDGPUDiscoverer(&toRequiredInfo{d}) + return discover.WithCache( + discover.FirstValid( + discoverers..., + ), + ), nil } -// NewForDevice creates a discoverer for the specified device and its associated MIG device. +// NewForMigDevice creates a discoverer for the specified device and its associated MIG device. +// nvsandboxutils is used for discovery if specified, otherwise NVML is used. func NewForMigDevice(d device.Device, mig device.MigDevice, opts ...Option) (discover.Discover, error) { + o := new(opts...) + o.isMigDevice = true + + var discoverers []discover.Discover + var errs error + nvsandboxutilsDiscoverer, err := o.newNvsandboxutilsDGPUDiscoverer(mig) + if err != nil { + // TODO: Log a warning + errs = errors.Join(errs, err) + } else if nvsandboxutilsDiscoverer != nil { + discoverers = append(discoverers, nvsandboxutilsDiscoverer) + } + + nvmlDiscoverer, err := o.newNvmlMigDiscoverer( + &toRequiredMigInfo{ + MigDevice: mig, + parent: &toRequiredInfo{d}, + }, + ) + if err != nil { + // TODO: Log a warning + errs = errors.Join(errs, err) + } else if nvmlDiscoverer != nil { + discoverers = append(discoverers, nvmlDiscoverer) + } + + if len(discoverers) == 0 { + return nil, errs + } + + return discover.WithCache( + discover.FirstValid( + discoverers..., + ), + ), nil + +} + +func new(opts ...Option) *options { o := &options{} for _, opt := range opts { opt(o) @@ -48,10 +111,15 @@ func NewForMigDevice(d device.Device, mig device.MigDevice, opts ...Option) (dis o.logger = logger.New() } - return o.newNvmlMigDiscoverer( - &toRequiredMigInfo{ - MigDevice: mig, - parent: &toRequiredInfo{d}, - }, - ) + if o.migCaps == nil { + migCaps, err := nvcaps.NewMigCaps() + if err != nil { + o.logger.Debugf("ignoring error getting MIG capability device paths: %v", err) + o.migCapsError = err + } else { + o.migCaps = migCaps + } + } + + return o } diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/nvml.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/nvml.go index be111102..f24f4d55 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/nvml.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/nvml.go @@ -78,24 +78,23 @@ type requiredMigInfo interface { } func (o *options) newNvmlMigDiscoverer(d requiredMigInfo) (discover.Discover, error) { - gpu, gi, ci, err := d.getPlacementInfo() - if err != nil { - return nil, fmt.Errorf("error getting placement info: %w", err) + if o.migCaps == nil || o.migCapsError != nil { + return nil, fmt.Errorf("error getting MIG capability device paths: %v", o.migCapsError) } - migCaps, err := nvcaps.NewMigCaps() + gpu, gi, ci, err := d.getPlacementInfo() if err != nil { - return nil, fmt.Errorf("error getting MIG capability device paths: %v", err) + return nil, fmt.Errorf("error getting placement info: %w", err) } giCap := nvcaps.NewGPUInstanceCap(gpu, gi) - giCapDevicePath, err := migCaps.GetCapDevicePath(giCap) + giCapDevicePath, err := o.migCaps.GetCapDevicePath(giCap) if err != nil { return nil, fmt.Errorf("failed to get GI cap device path: %v", err) } ciCap := nvcaps.NewComputeInstanceCap(gpu, gi, ci) - ciCapDevicePath, err := migCaps.GetCapDevicePath(ciCap) + ciCapDevicePath, err := o.migCaps.GetCapDevicePath(ciCap) if err != nil { return nil, fmt.Errorf("failed to get CI cap device path: %v", err) } diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/nvsandboxutils.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/nvsandboxutils.go new file mode 100644 index 00000000..7022deab --- /dev/null +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/nvsandboxutils.go @@ -0,0 +1,131 @@ +/** +# Copyright 2024 NVIDIA CORPORATION +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package dgpu + +import ( + "fmt" + "path/filepath" + "strings" + + "github.com/NVIDIA/go-nvml/pkg/nvml" + + "github.com/NVIDIA/nvidia-container-toolkit/internal/discover" + "github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils" +) + +type nvsandboxutilsDGPU struct { + lib nvsandboxutils.Interface + uuid string + devRoot string + isMig bool + nvidiaCDIHookPath string + deviceLinks []string +} + +var _ discover.Discover = (*nvsandboxutilsDGPU)(nil) + +type UUIDer interface { + GetUUID() (string, nvml.Return) +} + +func (o *options) newNvsandboxutilsDGPUDiscoverer(d UUIDer) (discover.Discover, error) { + if o.nvsandboxutilslib == nil { + return nil, nil + } + + uuid, nvmlRet := d.GetUUID() + if nvmlRet != nvml.SUCCESS { + return nil, fmt.Errorf("failed to get device UUID: %w", nvmlRet) + } + + nvd := nvsandboxutilsDGPU{ + lib: o.nvsandboxutilslib, + uuid: uuid, + devRoot: strings.TrimSuffix(filepath.Clean(o.devRoot), "/dev"), + isMig: o.isMigDevice, + nvidiaCDIHookPath: o.nvidiaCDIHookPath, + } + + return &nvd, nil +} + +func (d *nvsandboxutilsDGPU) Devices() ([]discover.Device, error) { + gpuFileInfos, ret := d.lib.GetGpuResource(d.uuid) + if ret != nvsandboxutils.SUCCESS { + return nil, fmt.Errorf("failed to get GPU resource: %w", ret) + } + + var devices []discover.Device + for _, info := range gpuFileInfos { + switch { + case info.SubType == nvsandboxutils.NV_DEV_DRI_CARD, info.SubType == nvsandboxutils.NV_DEV_DRI_RENDERD: + if d.isMig { + continue + } + fallthrough + case info.SubType == nvsandboxutils.NV_DEV_NVIDIA, info.SubType == nvsandboxutils.NV_DEV_NVIDIA_CAPS_NVIDIA_CAP: + containerPath := info.Path + if d.devRoot != "/" { + containerPath = strings.TrimPrefix(containerPath, d.devRoot) + } + + // TODO: Extend discover.Device with additional information. + device := discover.Device{ + HostPath: info.Path, + Path: containerPath, + } + devices = append(devices, device) + case info.SubType == nvsandboxutils.NV_DEV_DRI_CARD_SYMLINK, info.SubType == nvsandboxutils.NV_DEV_DRI_RENDERD_SYMLINK: + if d.isMig { + continue + } + if info.Flags == nvsandboxutils.NV_FILE_FLAG_CONTENT { + targetPath, ret := d.lib.GetFileContent(info.Path) + if ret != nvsandboxutils.SUCCESS { + return nil, fmt.Errorf("failed to get symlink: %w", ret) + } + d.deviceLinks = append(d.deviceLinks, fmt.Sprintf("%v::%v", targetPath, info.Path)) + } + } + } + + return devices, nil +} + +// Hooks returns a hook to create the by-path symlinks for the discovered devices. +func (d *nvsandboxutilsDGPU) Hooks() ([]discover.Hook, error) { + if len(d.deviceLinks) == 0 { + return nil, nil + } + + var args []string + for _, l := range d.deviceLinks { + args = append(args, "--link", l) + } + + hook := discover.CreateNvidiaCDIHook( + d.nvidiaCDIHookPath, + "create-symlinks", + args..., + ) + + return []discover.Hook{hook}, nil +} + +func (d *nvsandboxutilsDGPU) Mounts() ([]discover.Mount, error) { + return nil, nil +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/options.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/options.go index cea58c6d..2fd1c01b 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/options.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu/options.go @@ -18,12 +18,22 @@ package dgpu import ( "github.com/NVIDIA/nvidia-container-toolkit/internal/logger" + "github.com/NVIDIA/nvidia-container-toolkit/internal/nvcaps" + "github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils" ) type options struct { logger logger.Interface devRoot string nvidiaCDIHookPath string + + isMigDevice bool + // migCaps stores the MIG capabilities for the system. + // If MIG is not available, this is nil. + migCaps nvcaps.MigCaps + migCapsError error + + nvsandboxutilslib nvsandboxutils.Interface } type Option func(*options) @@ -48,3 +58,17 @@ func WithNVIDIACDIHookPath(path string) Option { l.nvidiaCDIHookPath = path } } + +// WithMIGCaps sets the MIG capabilities. +func WithMIGCaps(migCaps nvcaps.MigCaps) Option { + return func(l *options) { + l.migCaps = migCaps + } +} + +// WithNvsandboxuitilsLib sets the nvsandboxutils library implementation. +func WithNvsandboxuitilsLib(nvsandboxutilslib nvsandboxutils.Interface) Option { + return func(l *options) { + l.nvsandboxutilslib = nvsandboxutilslib + } +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/csv.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/csv.go index e47ae9de..9af38d71 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/csv.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/csv.go @@ -49,14 +49,20 @@ func (o tegraOptions) newDiscovererFromCSVFiles() (discover.Discover, error) { targetsByType[csv.MountSpecDir], ) - // Libraries and symlinks use the same locator. - libraries := discover.NewMounts( - o.logger, - o.symlinkLocator, - o.driverRoot, - targetsByType[csv.MountSpecLib], + // We create a discoverer for mounted libraries and add additional .so + // symlinks for the driver. + libraries := discover.WithDriverDotSoSymlinks( + discover.NewMounts( + o.logger, + o.symlinkLocator, + o.driverRoot, + targetsByType[csv.MountSpecLib], + ), + "", + o.nvidiaCDIHookPath, ) + // We process the explicitly requested symlinks. symlinkTargets := o.ignorePatterns.Apply(targetsByType[csv.MountSpecSym]...) o.logger.Debugf("Filtered symlink targets: %v", symlinkTargets) symlinks := discover.NewMounts( @@ -65,7 +71,7 @@ func (o tegraOptions) newDiscovererFromCSVFiles() (discover.Discover, error) { o.driverRoot, symlinkTargets, ) - createSymlinks := o.createCSVSymlinkHooks(symlinkTargets, libraries) + createSymlinks := o.createCSVSymlinkHooks(symlinkTargets) d := discover.Merge( devices, diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/symlinks.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/symlinks.go index 37b07e6d..cc677638 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/symlinks.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/symlinks.go @@ -18,8 +18,6 @@ package tegra import ( "fmt" - "path/filepath" - "strings" "github.com/NVIDIA/nvidia-container-toolkit/internal/discover" "github.com/NVIDIA/nvidia-container-toolkit/internal/logger" @@ -31,7 +29,6 @@ type symlinkHook struct { logger logger.Interface nvidiaCDIHookPath string targets []string - mountsFrom discover.Discover // The following can be overridden for testing symlinkChainLocator lookup.Locator @@ -39,12 +36,11 @@ type symlinkHook struct { } // createCSVSymlinkHooks creates a discoverer for a hook that creates required symlinks in the container -func (o tegraOptions) createCSVSymlinkHooks(targets []string, mounts discover.Discover) discover.Discover { +func (o tegraOptions) createCSVSymlinkHooks(targets []string) discover.Discover { return symlinkHook{ logger: o.logger, nvidiaCDIHookPath: o.nvidiaCDIHookPath, targets: targets, - mountsFrom: mounts, symlinkChainLocator: o.symlinkChainLocator, resolveSymlink: o.resolveSymlink, } @@ -52,62 +48,12 @@ func (o tegraOptions) createCSVSymlinkHooks(targets []string, mounts discover.Di // Hooks returns a hook to create the symlinks from the required CSV files func (d symlinkHook) Hooks() ([]discover.Hook, error) { - specificLinks, err := d.getSpecificLinks() - if err != nil { - return nil, fmt.Errorf("failed to determine specific links: %v", err) - } - - csvSymlinks := d.getCSVFileSymlinks() - return discover.CreateCreateSymlinkHook( d.nvidiaCDIHookPath, - append(csvSymlinks, specificLinks...), + d.getCSVFileSymlinks(), ).Hooks() } -// getSpecificLinks returns the required specic links that need to be created -func (d symlinkHook) getSpecificLinks() ([]string, error) { - mounts, err := d.mountsFrom.Mounts() - if err != nil { - return nil, fmt.Errorf("failed to discover mounts for ldcache update: %v", err) - } - - linkProcessed := make(map[string]bool) - var links []string - for _, m := range mounts { - var target string - var link string - - lib := filepath.Base(m.Path) - - switch { - case strings.HasPrefix(lib, "libcuda.so"): - // XXX Many applications wrongly assume that libcuda.so exists (e.g. with dlopen). - target = "libcuda.so.1" - link = "libcuda.so" - case strings.HasPrefix(lib, "libGLX_nvidia.so"): - // XXX GLVND requires this symlink for indirect GLX support. - target = lib - link = "libGLX_indirect.so.0" - case strings.HasPrefix(lib, "libnvidia-opticalflow.so"): - // XXX Fix missing symlink for libnvidia-opticalflow.so. - target = "libnvidia-opticalflow.so.1" - link = "libnvidia-opticalflow.so" - default: - continue - } - if linkProcessed[link] { - continue - } - linkProcessed[link] = true - - linkPath := filepath.Join(filepath.Dir(m.Path), link) - links = append(links, fmt.Sprintf("%v::%v", target, linkPath)) - } - - return links, nil -} - // getSymlinkCandidates returns a list of symlinks that are candidates for being created. func (d symlinkHook) getSymlinkCandidates() []string { var candidates []string diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/driver-nvml.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/driver-nvml.go index 8fb39888..007ead28 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/driver-nvml.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/driver-nvml.go @@ -97,11 +97,15 @@ func NewDriverLibraryDiscoverer(logger logger.Interface, driver *root.Driver, nv libraryPaths, ) - hooks, _ := discover.NewLDCacheUpdateHook(logger, libraries, nvidiaCDIHookPath, ldconfigPath) + updateLDCache, _ := discover.NewLDCacheUpdateHook(logger, libraries, nvidiaCDIHookPath, ldconfigPath) d := discover.Merge( - libraries, - hooks, + discover.WithDriverDotSoSymlinks( + libraries, + version, + nvidiaCDIHookPath, + ), + updateLDCache, ) return d, nil @@ -200,7 +204,10 @@ func getVersionLibs(logger logger.Interface, driver *root.Driver, version string libraries := lookup.NewFileLocator( lookup.WithLogger(logger), - lookup.WithSearchPaths(libRoot), + lookup.WithSearchPaths( + libRoot, + filepath.Join(libRoot, "vdpau"), + ), lookup.WithOptional(true), ) diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/full-gpu-nvml.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/full-gpu-nvml.go index 881d102d..003515ca 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/full-gpu-nvml.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/full-gpu-nvml.go @@ -72,6 +72,7 @@ func (l *nvmllib) newFullGPUDiscoverer(d device.Device) (discover.Discover, erro dgpu.WithDevRoot(l.devRoot), dgpu.WithLogger(l.logger), dgpu.WithNVIDIACDIHookPath(l.nvidiaCDIHookPath), + dgpu.WithNvsandboxuitilsLib(l.nvsandboxutilslib), ) if err != nil { return nil, fmt.Errorf("failed to create device discoverer: %v", err) diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/lib-nvml.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/lib-nvml.go index ab7cb8ba..01c22ff3 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/lib-nvml.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/lib-nvml.go @@ -27,6 +27,7 @@ import ( "tags.cncf.io/container-device-interface/specs-go" "github.com/NVIDIA/nvidia-container-toolkit/internal/edits" + "github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils" "github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec" ) @@ -52,6 +53,19 @@ func (l *nvmllib) GetAllDeviceSpecs() ([]specs.Device, error) { } }() + if l.nvsandboxutilslib != nil { + if r := l.nvsandboxutilslib.Init(l.driverRoot); r != nvsandboxutils.SUCCESS { + l.logger.Warningf("Failed to init nvsandboxutils: %v; ignoring", r) + l.nvsandboxutilslib = nil + } + defer func() { + if l.nvsandboxutilslib == nil { + return + } + _ = l.nvsandboxutilslib.Shutdown() + }() + } + gpuDeviceSpecs, err := l.getGPUDeviceSpecs() if err != nil { return nil, err @@ -89,7 +103,7 @@ func (l *nvmllib) GetDeviceSpecsByID(ids ...string) ([]specs.Device, error) { return l.GetDeviceSpecsBy(identifiers...) } -// GetDeviceSpecsBy is not supported for the gdslib specs. +// GetDeviceSpecsBy returns the device specs for devices with the specified identifiers. func (l *nvmllib) GetDeviceSpecsBy(identifiers ...device.Identifier) ([]specs.Device, error) { for _, id := range identifiers { if id == "all" { @@ -104,10 +118,23 @@ func (l *nvmllib) GetDeviceSpecsBy(identifiers ...device.Identifier) ([]specs.De } defer func() { if r := l.nvmllib.Shutdown(); r != nvml.SUCCESS { - l.logger.Warningf("failed to shutdown NVML: %w", r) + l.logger.Warningf("failed to shutdown NVML: %v", r) } }() + if l.nvsandboxutilslib != nil { + if r := l.nvsandboxutilslib.Init(l.driverRoot); r != nvsandboxutils.SUCCESS { + l.logger.Warningf("Failed to init nvsandboxutils: %v; ignoring", r) + l.nvsandboxutilslib = nil + } + defer func() { + if l.nvsandboxutilslib == nil { + return + } + _ = l.nvsandboxutilslib.Shutdown() + }() + } + nvmlDevices, err := l.getNVMLDevicesByID(identifiers...) if err != nil { return nil, fmt.Errorf("failed to get NVML device handles: %w", err) diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/lib.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/lib.go index d2db3b6c..8ed9e5aa 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/lib.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/lib.go @@ -24,8 +24,10 @@ import ( "github.com/NVIDIA/go-nvml/pkg/nvml" "tags.cncf.io/container-device-interface/pkg/cdi" + "github.com/NVIDIA/nvidia-container-toolkit/internal/config/image" "github.com/NVIDIA/nvidia-container-toolkit/internal/logger" "github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/root" + "github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils" "github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra/csv" "github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec" "github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/transform" @@ -43,6 +45,7 @@ type wrapper struct { type nvcdilib struct { logger logger.Interface nvmllib nvml.Interface + nvsandboxutilslib nvsandboxutils.Interface mode string devicelib device.Interface deviceNamers DeviceNamers @@ -107,6 +110,19 @@ func New(opts ...Option) (Interface, error) { } l.nvmllib = nvml.New(nvmlOpts...) } + if l.nvsandboxutilslib == nil { + var nvsandboxutilsOpts []nvsandboxutils.LibraryOption + // Set the library path for libnvidia-sandboxutils + candidates, err := l.driver.Libraries().Locate("libnvidia-sandboxutils.so.1") + if err != nil { + l.logger.Warningf("Ignoring error in locating libnvidia-sandboxutils.so.1: %v", err) + } else { + libNvidiaSandboxutilsPath := candidates[0] + l.logger.Infof("Using %v", libNvidiaSandboxutilsPath) + nvsandboxutilsOpts = append(nvsandboxutilsOpts, nvsandboxutils.WithLibraryPath(libNvidiaSandboxutilsPath)) + } + l.nvsandboxutilslib = nvsandboxutils.New(nvsandboxutilsOpts...) + } if l.devicelib == nil { l.devicelib = device.New(l.nvmllib) } @@ -185,7 +201,7 @@ func (m *wrapper) GetCommonEdits() (*cdi.ContainerEdits, error) { if err != nil { return nil, err } - edits.Env = append(edits.Env, "NVIDIA_VISIBLE_DEVICES=void") + edits.Env = append(edits.Env, image.EnvVarNvidiaVisibleDevices+"=void") return edits, nil } @@ -214,6 +230,16 @@ func (l *nvcdilib) resolveMode() (rmode string) { // getCudaVersion returns the CUDA version of the current system. func (l *nvcdilib) getCudaVersion() (string, error) { + version, err := l.getCudaVersionNvsandboxutils() + if err == nil { + return version, err + } + + // Fallback to NVML + return l.getCudaVersionNvml() +} + +func (l *nvcdilib) getCudaVersionNvml() (string, error) { if hasNVML, reason := l.infolib.HasNvml(); !hasNVML { return "", fmt.Errorf("nvml not detected: %v", reason) } @@ -236,3 +262,16 @@ func (l *nvcdilib) getCudaVersion() (string, error) { } return version, nil } + +func (l *nvcdilib) getCudaVersionNvsandboxutils() (string, error) { + if l.nvsandboxutilslib == nil { + return "", fmt.Errorf("libnvsandboxutils is not available") + } + + // Sandboxutils initialization should happen before this function is called + version, ret := l.nvsandboxutilslib.GetDriverVersion() + if ret != nvsandboxutils.SUCCESS { + return "", fmt.Errorf("%v", ret) + } + return version, nil +} diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/management.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/management.go index 4648e5bb..dee63a14 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/management.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/management.go @@ -28,6 +28,7 @@ import ( "github.com/NVIDIA/nvidia-container-toolkit/internal/discover" "github.com/NVIDIA/nvidia-container-toolkit/internal/edits" "github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/cuda" + "github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils" "github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec" ) @@ -61,6 +62,19 @@ func (m *managementlib) GetAllDeviceSpecs() ([]specs.Device, error) { // GetCommonEdits returns the common edits for use in managementlib containers. func (m *managementlib) GetCommonEdits() (*cdi.ContainerEdits, error) { + if m.nvsandboxutilslib != nil { + if r := m.nvsandboxutilslib.Init(m.driverRoot); r != nvsandboxutils.SUCCESS { + m.logger.Warningf("Failed to init nvsandboxutils: %v; ignoring", r) + m.nvsandboxutilslib = nil + } + defer func() { + if m.nvsandboxutilslib == nil { + return + } + _ = m.nvsandboxutilslib.Shutdown() + }() + } + version, err := m.getCudaVersion() if err != nil { return nil, fmt.Errorf("failed to get CUDA version: %v", err) @@ -117,6 +131,7 @@ func (m *managementlib) newManagementDeviceDiscoverer() (discover.Discover, erro "/dev/nvidia-uvm-tools", "/dev/nvidia-uvm", "/dev/nvidiactl", + "/dev/nvidia-caps-imex-channels/channel*", }, ) diff --git a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/mig-device-nvml.go b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/mig-device-nvml.go index 91fe879c..5c1a504c 100644 --- a/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/mig-device-nvml.go +++ b/vendor/github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/mig-device-nvml.go @@ -55,6 +55,7 @@ func (l *nvmllib) GetMIGDeviceEdits(parent device.Device, mig device.MigDevice) dgpu.WithDevRoot(l.devRoot), dgpu.WithLogger(l.logger), dgpu.WithNVIDIACDIHookPath(l.nvidiaCDIHookPath), + dgpu.WithNvsandboxuitilsLib(l.nvsandboxutilslib), ) if err != nil { return nil, fmt.Errorf("failed to create device discoverer: %v", err) diff --git a/vendor/modules.txt b/vendor/modules.txt index 081aaec0..eb7165c0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -9,7 +9,7 @@ github.com/NVIDIA/go-nvlib/pkg/nvlib/info ## explicit; go 1.20 github.com/NVIDIA/go-nvml/pkg/dl github.com/NVIDIA/go-nvml/pkg/nvml -# github.com/NVIDIA/nvidia-container-toolkit v1.16.1 +# github.com/NVIDIA/nvidia-container-toolkit v1.17.0 ## explicit; go 1.20 github.com/NVIDIA/nvidia-container-toolkit/internal/config/image github.com/NVIDIA/nvidia-container-toolkit/internal/discover @@ -24,6 +24,7 @@ github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/cuda github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/root github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks github.com/NVIDIA/nvidia-container-toolkit/internal/nvcaps +github.com/NVIDIA/nvidia-container-toolkit/internal/nvsandboxutils github.com/NVIDIA/nvidia-container-toolkit/internal/oci github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/dgpu github.com/NVIDIA/nvidia-container-toolkit/internal/platform-support/tegra