Compare commits

..

46 Commits

Author SHA1 Message Date
Evan Lezar
0db8ca9893 Fix discovery of nvidia-fs devices in non-privileged containers
The /dev/nvidia-fs* device nodes for GDS are not greated at the
driver root when running a containerized driver and are always
created in /.

This change updates the search path for these device nodes so that
non-privilged containers also have the device nodes injected.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-16 19:21:13 +02:00
Evan Lezar
8149be09ac Merge pull request #1149 from NVIDIA/dependabot/go_modules/main/github.com/urfave/cli/v2-2.27.7
Bump github.com/urfave/cli/v2 from 2.27.6 to 2.27.7
2025-06-16 16:28:29 +02:00
Evan Lezar
d935648722 Merge pull request #1140 from NVIDIA/dependabot/go_modules/main/github.com/NVIDIA/go-nvlib-0.7.3
Bump github.com/NVIDIA/go-nvlib from 0.7.2 to 0.7.3
2025-06-16 16:26:57 +02:00
dependabot[bot]
1f43b71dd8 Bump github.com/urfave/cli/v2 from 2.27.6 to 2.27.7
Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.27.6 to 2.27.7.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v2.27.6...v2.27.7)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli/v2
  dependency-version: 2.27.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-16 08:56:44 +00:00
Evan Lezar
b33d475ff3 Merge pull request #1145 from elezar/remove-docker-runc
Some checks failed
CI Pipeline / code-scanning (push) Has been cancelled
CI Pipeline / variables (push) Has been cancelled
CI Pipeline / golang (push) Has been cancelled
CI Pipeline / image (push) Has been cancelled
CI Pipeline / e2e-test (push) Has been cancelled
Remove docker-run as default runtime candidate
2025-06-13 19:27:08 +02:00
Evan Lezar
6359cc9919 Remove docker-run as default runtime candidate
This change removes docker-runc as the highest priority
default candidate for the low-level runtimes supported by
the nvidia-container-runtime.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-13 17:26:19 +02:00
Evan Lezar
4f9c860a37 Merge pull request #927 from elezar/disable-device-node-creation
Disable device node creation in CDI mode
2025-06-13 16:44:18 +02:00
Evan Lezar
bab9fdf607 Merge pull request #1144 from NVIDIA/dependabot/submodules/main/third_party/libnvidia-container-710a0f1
Bump third_party/libnvidia-container from `6eda4d7` to `710a0f1`
2025-06-13 16:42:53 +02:00
Evan Lezar
cc7812470f Merge pull request #1143 from elezar/add-device-ids-to-getspec
Add device IDs to nvcdi.GetSpec API
2025-06-13 16:41:43 +02:00
Evan Lezar
bdcdcb7449 Merge pull request #1132 from elezar/make-cdi-device-extraction-consistent
Make CDI device requests consistent with other methods
2025-06-13 16:05:44 +02:00
Evan Lezar
8be03cfc41 [no-relnote] Ignore annotation devices for non-CDI modes
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-13 15:26:48 +02:00
Evan Lezar
8650ca6533 [no-relnote] Move hookCreator initialisation for readability
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-13 15:00:51 +02:00
Evan Lezar
1bc2a9fee3 Return annotation devices from VisibleDevices
This change includes annotation devices in CUDA.VisibleDevices
with the highest priority. This allows for the CDI device
request extraction to be consistent across all request mechanisms.

Note that this does change behaviour in the following ways:
1. Annotations are considered when resolving the runtime mode.
2. Incorrectly formed device names in annotations are no longer treated as an error.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-13 14:56:08 +02:00
Evan Lezar
dc87dcf786 Make CDI device requests consistent with other methods
Following the refactoring of device request extraction, we can
now make CDI device requests consistent with other methods.

This change moves to using image.VisibleDevices instead of
separate calls to CDIDevicesFromMounts and VisibleDevicesFromEnvVar.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-13 14:34:02 +02:00
Evan Lezar
f17d424248 Construct container info once
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-13 14:05:51 +02:00
Evan Lezar
426186c992 Add logic to extract annotation device requests to image type
This change updates the image.CUDA type to also extract CDI
device requests. These are only relevant IF CDI prefixes are
specifically set.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-13 14:05:51 +02:00
Evan Lezar
6849ebd621 Add IsPrivileged function to CUDA container type
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-13 14:05:51 +02:00
dependabot[bot]
4a6685d3a8 Bump third_party/libnvidia-container from 6eda4d7 to 710a0f1
Bumps [third_party/libnvidia-container](https://github.com/NVIDIA/libnvidia-container) from `6eda4d7` to `710a0f1`.
- [Release notes](https://github.com/NVIDIA/libnvidia-container/releases)
- [Commits](6eda4d76c8...710a0f1304)

---
updated-dependencies:
- dependency-name: third_party/libnvidia-container
  dependency-version: 710a0f1304dacb9de06716a4e24160698952aa81
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-13 08:14:38 +00:00
Evan Lezar
2ccf67c40f [no-relnote] Remove test output file
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-12 16:34:08 +02:00
Evan Lezar
0134ba4250 Add device IDs to nvcdi.GetSpec API
This change allows device IDs to the specified in the GetSpec API.
This simplifies cases where CDI specs are being generated for specific
devices by ID.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-12 16:23:11 +02:00
dependabot[bot]
eab9cdf1c2 Bump github.com/NVIDIA/go-nvlib from 0.7.2 to 0.7.3
Bumps [github.com/NVIDIA/go-nvlib](https://github.com/NVIDIA/go-nvlib) from 0.7.2 to 0.7.3.
- [Release notes](https://github.com/NVIDIA/go-nvlib/releases)
- [Commits](https://github.com/NVIDIA/go-nvlib/compare/v0.7.2...v0.7.3)

---
updated-dependencies:
- dependency-name: github.com/NVIDIA/go-nvlib
  dependency-version: 0.7.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-11 12:58:33 +00:00
Evan Lezar
dba15acdcc Merge pull request #1135 from NVIDIA/dependabot/go_modules/tests/main/golang.org/x/crypto-0.39.0
Some checks failed
CI Pipeline / code-scanning (push) Has been cancelled
CI Pipeline / variables (push) Has been cancelled
CI Pipeline / golang (push) Has been cancelled
CI Pipeline / image (push) Has been cancelled
CI Pipeline / e2e-test (push) Has been cancelled
Bump golang.org/x/crypto from 0.38.0 to 0.39.0 in /tests
2025-06-11 14:57:38 +02:00
Evan Lezar
8339fb1ec3 Merge pull request #1139 from NVIDIA/dependabot/go_modules/main/github.com/NVIDIA/go-nvml-0.12.9-0
Bump github.com/NVIDIA/go-nvml from 0.12.4-1 to 0.12.9-0
2025-06-11 14:57:18 +02:00
Evan Lezar
b9d646c80d Merge pull request #1136 from NVIDIA/dependabot/docker/deployments/devel/main/golang-1.24.4
Bump golang from 1.24.3 to 1.24.4 in /deployments/devel
2025-06-11 14:53:57 +02:00
Evan Lezar
7380cff645 Merge pull request #1134 from NVIDIA/dependabot/go_modules/main/golang.org/x/mod-0.25.0
Bump golang.org/x/mod from 0.24.0 to 0.25.0
2025-06-11 14:53:34 +02:00
dependabot[bot]
f91736d832 Bump github.com/NVIDIA/go-nvml from 0.12.4-1 to 0.12.9-0
Bumps [github.com/NVIDIA/go-nvml](https://github.com/NVIDIA/go-nvml) from 0.12.4-1 to 0.12.9-0.
- [Release notes](https://github.com/NVIDIA/go-nvml/releases)
- [Commits](https://github.com/NVIDIA/go-nvml/compare/v0.12.4-1...v0.12.9-0)

---
updated-dependencies:
- dependency-name: github.com/NVIDIA/go-nvml
  dependency-version: 0.12.9-0
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-11 09:03:11 +00:00
dependabot[bot]
5ccac4da5a Bump golang from 1.24.3 to 1.24.4 in /deployments/devel
Bumps golang from 1.24.3 to 1.24.4.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.24.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-06 09:01:57 +00:00
dependabot[bot]
1aee45be2d Bump golang.org/x/crypto from 0.38.0 to 0.39.0 in /tests
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.38.0 to 0.39.0.
- [Commits](https://github.com/golang/crypto/compare/v0.38.0...v0.39.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-06 08:43:50 +00:00
dependabot[bot]
0d4a7f1d5a Bump golang.org/x/mod from 0.24.0 to 0.25.0
Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.24.0 to 0.25.0.
- [Commits](https://github.com/golang/mod/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-version: 0.25.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-06 08:43:41 +00:00
Evan Lezar
27f5ec83de Merge pull request #1125 from elezar/vulkan-target-cpu
Some checks failed
CI Pipeline / code-scanning (push) Has been cancelled
CI Pipeline / variables (push) Has been cancelled
CI Pipeline / golang (push) Has been cancelled
CI Pipeline / image (push) Has been cancelled
CI Pipeline / e2e-test (push) Has been cancelled
Add discovery of arch-specific vulkan ICD
2025-06-05 14:09:50 +02:00
Carlos Eduardo Arango Gutierrez
0a3146f74f Merge pull request #1076 from ArangoGutierrez/refresh_cdi
Add nvidia-cdi-refresh service
2025-06-05 13:08:57 +02:00
Carlos Eduardo Arango Gutierrez
28add0a532 Merge pull request #1123 from ArangoGutierrez/cdi_generate_env_cli
Add EnvVars option for all nvidia-ctk cdi commands
2025-06-05 13:05:46 +02:00
Evan Lezar
b55255e31f Merge pull request #1110 from ArangoGutierrez/i/1049
Refactor extracting requested devices from the container image
2025-06-05 13:00:32 +02:00
Carlos Eduardo Arango Gutierrez
dede03f322 Refactor extracting requested devices from the container image
This change consolidates the logic for determining requested devices
from the container image. The logic for this has been integrated into
the image.CUDA type so that multiple implementations are not required.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Co-authored-by: Evan Lezar <elezar@nvidia.com>
2025-06-05 12:38:45 +02:00
Carlos Eduardo Arango Gutierrez
ce3e2c1ed5 Add EnvVars option for all nvidia-ctk cdi commands
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
2025-06-05 11:22:35 +02:00
Carlos Eduardo Arango Gutierrez
a537d0323d Add nvidia-cdi-refresh service
Automatic regeneration of /var/run/cdi/nvidia.yaml
New units:
	•	nvidia-cdi-refresh.service – one-shot wrapper for
			nvidia-ctk cdi generate (adds sleep + required caps).
	•	nvidia-cdi-refresh.path   – fires on driver install/upgrade via
			modules.dep.bin changes.
Packaging
	•	RPM %post reloads systemd and enables the path unit on fresh
			installs.
	•	DEB postinst does the same (configure, skip on upgrade).

Result: CDI spec is always up to date

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
2025-06-05 10:54:15 +02:00
Evan Lezar
2de997e25b Add discovery of arch-specific vulkan ICD
On some RPM-based platforms, the path of the Vulkan ICD file
include an architecture-specific infix to distinguish it from
other architectures. (Most notably x86_64 vs i686). This change
attempts to discover the arch-specific ICD file in addition to
the standard nvidia_icd.json.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-04 23:06:16 +02:00
Evan Lezar
e046d6ae79 Add disabled-device-node-modification hook to CDI spec
Some checks failed
CI Pipeline / code-scanning (push) Has been cancelled
CI Pipeline / variables (push) Has been cancelled
CI Pipeline / golang (push) Has been cancelled
CI Pipeline / image (push) Has been cancelled
CI Pipeline / e2e-test (push) Has been cancelled
This hook is not added to management specs.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-04 19:08:48 +02:00
Evan Lezar
0c8723a93a Add a hook to disable device node creation in a container
If required, this hook creates a modified params file (with ModifyDeviceFiles: 0) in a tmpfs
and mounts this over /proc/driver/nvidia/params.

This prevents device node creation when running tools such as nvidia-smi. In general the
creation of these devices is cosmetic as a container does not have the required cgroup
access for the devices.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-04 19:08:48 +02:00
Evan Lezar
fdcd250362 Merge pull request #1129 from elezar/fix-deduplicate-driver-store-wsl
Minor cleanup of WSL2 CDI spec generation
2025-06-04 10:16:36 +02:00
Evan Lezar
b66d37bedb [no-relnote] Minor code cleanup in WSL2 discoverer
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-03 23:43:17 +02:00
Evan Lezar
0c905d0de2 [no-relnote] Remove unneeded indirection
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-03 23:43:17 +02:00
Evan Lezar
0d0b56816e Remove redundant deduplication of search paths for WSL
The GetDriverStorePaths function is implemented so as to
remove duplicate driver store paths which means that the
additional deduplication (which had a bug) can be removed.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-03 23:43:10 +02:00
Evan Lezar
d59fd3da11 Merge pull request #1077 from ArangoGutierrez/1074
Some checks failed
CI Pipeline / code-scanning (push) Has been cancelled
CI Pipeline / variables (push) Has been cancelled
CI Pipeline / golang (push) Has been cancelled
CI Pipeline / image (push) Has been cancelled
CI Pipeline / e2e-test (push) Has been cancelled
Add the ability to disable specific (or all) CDI hooks when generating a CDI specification
2025-06-03 16:03:18 +02:00
Carlos Eduardo Arango Gutierrez
6cf0248321 Added ability to disable specific (or all) CDI hooks
This change adds the ability to disabled specific (or all) CDI hooks to
both the nvidia-ctk cdi generate command and the nvcdi API.

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-06-03 16:01:20 +02:00
Carlos Eduardo Arango Gutierrez
b4787511d2 Consolidate HookName functionality on internal/discover pkg
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
2025-06-03 15:24:43 +02:00
109 changed files with 11637 additions and 3160 deletions

View File

@@ -22,6 +22,7 @@ import (
"github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/chmod"
symlinks "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/create-symlinks"
"github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/cudacompat"
disabledevicenodemodification "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/disable-device-node-modification"
ldcache "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-cdi-hook/update-ldcache"
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
)
@@ -34,6 +35,7 @@ func New(logger logger.Interface) []*cli.Command {
symlinks.NewCommand(logger),
chmod.NewCommand(logger),
cudacompat.NewCommand(logger),
disabledevicenodemodification.NewCommand(logger),
}
}

View File

@@ -0,0 +1,144 @@
/**
# SPDX-FileCopyrightText: Copyright (c) 2025 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.
**/
package disabledevicenodemodification
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"os"
"strings"
"github.com/urfave/cli/v2"
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
)
const (
nvidiaDriverParamsPath = "/proc/driver/nvidia/params"
)
type options struct {
containerSpec string
}
// NewCommand constructs an disable-device-node-modification subcommand with the specified logger
func NewCommand(logger logger.Interface) *cli.Command {
cfg := options{}
c := cli.Command{
Name: "disable-device-node-modification",
Usage: "Ensure that the /proc/driver/nvidia/params file present in the container does not allow device node modifications.",
Before: func(c *cli.Context) error {
return validateFlags(c, &cfg)
},
Action: func(c *cli.Context) error {
return run(c, &cfg)
},
}
c.Flags = []cli.Flag{
&cli.StringFlag{
Name: "container-spec",
Hidden: true,
Usage: "Specify the path to the OCI container spec. If empty or '-' the spec will be read from STDIN",
Destination: &cfg.containerSpec,
},
}
return &c
}
func validateFlags(c *cli.Context, cfg *options) error {
return nil
}
func run(_ *cli.Context, cfg *options) error {
modifiedParamsFileContents, err := getModifiedNVIDIAParamsContents()
if err != nil {
return fmt.Errorf("failed to get modified params file contents: %w", err)
}
if len(modifiedParamsFileContents) == 0 {
return nil
}
s, err := oci.LoadContainerState(cfg.containerSpec)
if err != nil {
return fmt.Errorf("failed to load container state: %w", err)
}
containerRootDirPath, err := s.GetContainerRoot()
if err != nil {
return fmt.Errorf("failed to determined container root: %w", err)
}
return createParamsFileInContainer(containerRootDirPath, modifiedParamsFileContents)
}
func getModifiedNVIDIAParamsContents() ([]byte, error) {
hostNvidiaParamsFile, err := os.Open(nvidiaDriverParamsPath)
if errors.Is(err, os.ErrNotExist) {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("failed to load params file: %w", err)
}
defer hostNvidiaParamsFile.Close()
modifiedContents, err := getModifiedParamsFileContentsFromReader(hostNvidiaParamsFile)
if err != nil {
return nil, fmt.Errorf("failed to get modfied params file contents: %w", err)
}
return modifiedContents, nil
}
// getModifiedParamsFileContentsFromReader returns the contents of a modified params file from the specified reader.
func getModifiedParamsFileContentsFromReader(r io.Reader) ([]byte, error) {
var modified bytes.Buffer
scanner := bufio.NewScanner(r)
var requiresModification bool
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "ModifyDeviceFiles: ") {
if line == "ModifyDeviceFiles: 0" {
return nil, nil
}
if line == "ModifyDeviceFiles: 1" {
line = "ModifyDeviceFiles: 0"
requiresModification = true
}
}
if _, err := modified.WriteString(line + "\n"); err != nil {
return nil, fmt.Errorf("failed to create output buffer: %w", err)
}
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("failed to read params file: %w", err)
}
if !requiresModification {
return nil, nil
}
return modified.Bytes(), nil
}

View File

@@ -0,0 +1,91 @@
/**
# SPDX-FileCopyrightText: Copyright (c) 2025 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.
**/
package disabledevicenodemodification
import (
"bytes"
"testing"
"github.com/stretchr/testify/require"
)
func TestGetModifiedParamsFileContentsFromReader(t *testing.T) {
testCases := map[string]struct {
contents []byte
expectedError error
expectedContents []byte
}{
"no contents": {
contents: nil,
expectedError: nil,
expectedContents: nil,
},
"other contents are ignored": {
contents: []byte(`# Some other content
that we don't care about
`),
expectedError: nil,
expectedContents: nil,
},
"already zero requires no modification": {
contents: []byte("ModifyDeviceFiles: 0"),
expectedError: nil,
expectedContents: nil,
},
"leading spaces require no modification": {
contents: []byte(" ModifyDeviceFiles: 1"),
},
"Trailing spaces require no modification": {
contents: []byte("ModifyDeviceFiles: 1 "),
},
"Not 1 require no modification": {
contents: []byte("ModifyDeviceFiles: 11"),
},
"single line requires modification": {
contents: []byte("ModifyDeviceFiles: 1"),
expectedError: nil,
expectedContents: []byte("ModifyDeviceFiles: 0\n"),
},
"single line with trailing newline requires modification": {
contents: []byte("ModifyDeviceFiles: 1\n"),
expectedError: nil,
expectedContents: []byte("ModifyDeviceFiles: 0\n"),
},
"other content is maintained": {
contents: []byte(`ModifyDeviceFiles: 1
other content
that
is maintained`),
expectedError: nil,
expectedContents: []byte(`ModifyDeviceFiles: 0
other content
that
is maintained
`),
},
}
for description, tc := range testCases {
t.Run(description, func(t *testing.T) {
contents, err := getModifiedParamsFileContentsFromReader(bytes.NewReader(tc.contents))
require.EqualValues(t, tc.expectedError, err)
require.EqualValues(t, string(tc.expectedContents), string(contents))
})
}
}

View File

@@ -0,0 +1,63 @@
//go:build linux
/**
# SPDX-FileCopyrightText: Copyright (c) 2025 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.
**/
package disabledevicenodemodification
import (
"fmt"
"os"
"path/filepath"
"github.com/opencontainers/runc/libcontainer/utils"
"golang.org/x/sys/unix"
)
func createParamsFileInContainer(containerRootDirPath string, contents []byte) error {
tmpRoot, err := os.MkdirTemp("", "nvct-empty-dir*")
if err != nil {
return fmt.Errorf("failed to create temp root: %w", err)
}
if err := createTmpFs(tmpRoot, len(contents)); err != nil {
return fmt.Errorf("failed to create tmpfs mount for params file: %w", err)
}
modifiedParamsFile, err := os.OpenFile(filepath.Join(tmpRoot, "nvct-params"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0444)
if err != nil {
return fmt.Errorf("failed to open modified params file: %w", err)
}
defer modifiedParamsFile.Close()
if _, err := modifiedParamsFile.Write(contents); err != nil {
return fmt.Errorf("failed to write temporary params file: %w", err)
}
err = utils.WithProcfd(containerRootDirPath, nvidiaDriverParamsPath, func(nvidiaDriverParamsFdPath string) error {
return unix.Mount(modifiedParamsFile.Name(), nvidiaDriverParamsFdPath, "", unix.MS_BIND|unix.MS_RDONLY|unix.MS_NODEV|unix.MS_PRIVATE|unix.MS_NOSYMFOLLOW, "")
})
if err != nil {
return fmt.Errorf("failed to mount modified params file: %w", err)
}
return nil
}
func createTmpFs(target string, size int) error {
return unix.Mount("tmpfs", target, "tmpfs", 0, fmt.Sprintf("size=%d", size))
}

View File

@@ -0,0 +1,27 @@
//go:build !linux
// +build !linux
/**
# SPDX-FileCopyrightText: Copyright (c) 2025 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.
**/
package disabledevicenodemodification
import "fmt"
func createParamsFileInContainer(containerRootDirPath string, contents []byte) error {
return fmt.Errorf("not supported")
}

View File

@@ -13,10 +13,6 @@ import (
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
)
const (
capSysAdmin = "CAP_SYS_ADMIN"
)
type nvidiaConfig struct {
Devices []string
MigConfigDevices string
@@ -103,9 +99,9 @@ func loadSpec(path string) (spec *Spec) {
return
}
func isPrivileged(s *Spec) bool {
if s.Process.Capabilities == nil {
return false
func (s *Spec) GetCapabilities() []string {
if s == nil || s.Process == nil || s.Process.Capabilities == nil {
return nil
}
var caps []string
@@ -118,67 +114,22 @@ func isPrivileged(s *Spec) bool {
if err != nil {
log.Panicln("could not decode Process.Capabilities in OCI spec:", err)
}
for _, c := range caps {
if c == capSysAdmin {
return true
}
}
return false
return caps
}
// Otherwise, parse s.Process.Capabilities as:
// github.com/opencontainers/runtime-spec/blob/v1.0.0/specs-go/config.go#L30-L54
process := specs.Process{
Env: s.Process.Env,
}
err := json.Unmarshal(*s.Process.Capabilities, &process.Capabilities)
capabilities := specs.LinuxCapabilities{}
err := json.Unmarshal(*s.Process.Capabilities, &capabilities)
if err != nil {
log.Panicln("could not decode Process.Capabilities in OCI spec:", err)
}
fullSpec := specs.Spec{
Version: *s.Version,
Process: &process,
}
return image.IsPrivileged(&fullSpec)
return image.OCISpecCapabilities(capabilities).GetCapabilities()
}
func getDevicesFromEnvvar(containerImage image.CUDA, swarmResourceEnvvars []string) []string {
// We check if the image has at least one of the Swarm resource envvars defined and use this
// if specified.
for _, envvar := range swarmResourceEnvvars {
if containerImage.HasEnvvar(envvar) {
return containerImage.DevicesFromEnvvars(swarmResourceEnvvars...).List()
}
}
return containerImage.VisibleDevicesFromEnvVar()
}
func (hookConfig *hookConfig) getDevices(image image.CUDA, privileged bool) []string {
// If enabled, try and get the device list from volume mounts first
if hookConfig.AcceptDeviceListAsVolumeMounts {
devices := image.VisibleDevicesFromMounts()
if len(devices) > 0 {
return devices
}
}
// Fallback to reading from the environment variable if privileges are correct
devices := getDevicesFromEnvvar(image, hookConfig.getSwarmResourceEnvvars())
if len(devices) == 0 {
return nil
}
if privileged || hookConfig.AcceptEnvvarUnprivileged {
return devices
}
configName := hookConfig.getConfigOption("AcceptEnvvarUnprivileged")
log.Printf("Ignoring devices specified in NVIDIA_VISIBLE_DEVICES (privileged=%v, %v=%v) ", privileged, configName, hookConfig.AcceptEnvvarUnprivileged)
return nil
func isPrivileged(s *Spec) bool {
return image.IsPrivileged(s)
}
func getMigConfigDevices(i image.CUDA) *string {
@@ -225,7 +176,6 @@ func (hookConfig *hookConfig) getDriverCapabilities(cudaImage image.CUDA, legacy
// We use the default driver capabilities by default. This is filtered to only include the
// supported capabilities
supportedDriverCapabilities := image.NewDriverCapabilities(hookConfig.SupportedDriverCapabilities)
capabilities := supportedDriverCapabilities.Intersection(image.DefaultDriverCapabilities)
capsEnvSpecified := cudaImage.HasEnvvar(image.EnvVarNvidiaDriverCapabilities)
@@ -251,7 +201,7 @@ func (hookConfig *hookConfig) getDriverCapabilities(cudaImage image.CUDA, legacy
func (hookConfig *hookConfig) getNvidiaConfig(image image.CUDA, privileged bool) *nvidiaConfig {
legacyImage := image.IsLegacy()
devices := hookConfig.getDevices(image, privileged)
devices := image.VisibleDevices()
if len(devices) == 0 {
// empty devices means this is not a GPU container.
return nil
@@ -306,20 +256,25 @@ func (hookConfig *hookConfig) getContainerConfig() (config containerConfig) {
s := loadSpec(path.Join(b, "config.json"))
image, err := image.New(
privileged := isPrivileged(s)
i, err := image.New(
image.WithEnv(s.Process.Env),
image.WithMounts(s.Mounts),
image.WithPrivileged(privileged),
image.WithDisableRequire(hookConfig.DisableRequire),
image.WithAcceptDeviceListAsVolumeMounts(hookConfig.AcceptDeviceListAsVolumeMounts),
image.WithAcceptEnvvarUnprivileged(hookConfig.AcceptEnvvarUnprivileged),
image.WithPreferredVisibleDevicesEnvVars(hookConfig.getSwarmResourceEnvvars()...),
)
if err != nil {
log.Panicln(err)
}
privileged := isPrivileged(s)
return containerConfig{
Pid: h.Pid,
Rootfs: s.Root.Path,
Image: image,
Nvidia: hookConfig.getNvidiaConfig(image, privileged),
Image: i,
Nvidia: hookConfig.getNvidiaConfig(i, privileged),
}
}

View File

@@ -1,10 +1,8 @@
package main
import (
"path/filepath"
"testing"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/require"
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
@@ -479,7 +477,10 @@ func TestGetNvidiaConfig(t *testing.T) {
t.Run(tc.description, func(t *testing.T) {
image, _ := image.New(
image.WithEnvMap(tc.env),
image.WithPrivileged(tc.privileged),
image.WithPreferredVisibleDevicesEnvVars(tc.hookConfig.getSwarmResourceEnvvars()...),
)
// Wrap the call to getNvidiaConfig() in a closure.
var cfg *nvidiaConfig
getConfig := func() {
@@ -518,340 +519,6 @@ func TestGetNvidiaConfig(t *testing.T) {
}
}
func TestDeviceListSourcePriority(t *testing.T) {
var tests = []struct {
description string
mountDevices []specs.Mount
envvarDevices string
privileged bool
acceptUnprivileged bool
acceptMounts bool
expectedDevices []string
}{
{
description: "Mount devices, unprivileged, no accept unprivileged",
mountDevices: []specs.Mount{
{
Source: "/dev/null",
Destination: filepath.Join(image.DeviceListAsVolumeMountsRoot, "GPU0"),
},
{
Source: "/dev/null",
Destination: filepath.Join(image.DeviceListAsVolumeMountsRoot, "GPU1"),
},
},
envvarDevices: "GPU2,GPU3",
privileged: false,
acceptUnprivileged: false,
acceptMounts: true,
expectedDevices: []string{"GPU0", "GPU1"},
},
{
description: "No mount devices, unprivileged, no accept unprivileged",
mountDevices: nil,
envvarDevices: "GPU0,GPU1",
privileged: false,
acceptUnprivileged: false,
acceptMounts: true,
expectedDevices: nil,
},
{
description: "No mount devices, privileged, no accept unprivileged",
mountDevices: nil,
envvarDevices: "GPU0,GPU1",
privileged: true,
acceptUnprivileged: false,
acceptMounts: true,
expectedDevices: []string{"GPU0", "GPU1"},
},
{
description: "No mount devices, unprivileged, accept unprivileged",
mountDevices: nil,
envvarDevices: "GPU0,GPU1",
privileged: false,
acceptUnprivileged: true,
acceptMounts: true,
expectedDevices: []string{"GPU0", "GPU1"},
},
{
description: "Mount devices, unprivileged, accept unprivileged, no accept mounts",
mountDevices: []specs.Mount{
{
Source: "/dev/null",
Destination: filepath.Join(image.DeviceListAsVolumeMountsRoot, "GPU0"),
},
{
Source: "/dev/null",
Destination: filepath.Join(image.DeviceListAsVolumeMountsRoot, "GPU1"),
},
},
envvarDevices: "GPU2,GPU3",
privileged: false,
acceptUnprivileged: true,
acceptMounts: false,
expectedDevices: []string{"GPU2", "GPU3"},
},
{
description: "Mount devices, unprivileged, no accept unprivileged, no accept mounts",
mountDevices: []specs.Mount{
{
Source: "/dev/null",
Destination: filepath.Join(image.DeviceListAsVolumeMountsRoot, "GPU0"),
},
{
Source: "/dev/null",
Destination: filepath.Join(image.DeviceListAsVolumeMountsRoot, "GPU1"),
},
},
envvarDevices: "GPU2,GPU3",
privileged: false,
acceptUnprivileged: false,
acceptMounts: false,
expectedDevices: nil,
},
}
for _, tc := range tests {
t.Run(tc.description, func(t *testing.T) {
// Wrap the call to getDevices() in a closure.
var devices []string
getDevices := func() {
image, _ := image.New(
image.WithEnvMap(
map[string]string{
image.EnvVarNvidiaVisibleDevices: tc.envvarDevices,
},
),
image.WithMounts(tc.mountDevices),
)
defaultConfig, _ := config.GetDefault()
cfg := &hookConfig{defaultConfig}
cfg.AcceptEnvvarUnprivileged = tc.acceptUnprivileged
cfg.AcceptDeviceListAsVolumeMounts = tc.acceptMounts
devices = cfg.getDevices(image, tc.privileged)
}
// For all other tests, just grab the devices and check the results
getDevices()
require.Equal(t, tc.expectedDevices, devices)
})
}
}
func TestGetDevicesFromEnvvar(t *testing.T) {
envDockerResourceGPUs := "DOCKER_RESOURCE_GPUS"
gpuID := "GPU-12345"
anotherGPUID := "GPU-67890"
thirdGPUID := "MIG-12345"
var tests = []struct {
description string
swarmResourceEnvvars []string
env map[string]string
expectedDevices []string
}{
{
description: "empty env returns nil for non-legacy image",
},
{
description: "blank NVIDIA_VISIBLE_DEVICES returns nil for non-legacy image",
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: "",
},
},
{
description: "'void' NVIDIA_VISIBLE_DEVICES returns nil for non-legacy image",
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: "void",
},
},
{
description: "'none' NVIDIA_VISIBLE_DEVICES returns empty for non-legacy image",
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: "none",
},
expectedDevices: []string{""},
},
{
description: "NVIDIA_VISIBLE_DEVICES set returns value for non-legacy image",
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: gpuID,
},
expectedDevices: []string{gpuID},
},
{
description: "NVIDIA_VISIBLE_DEVICES set returns value for legacy image",
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: gpuID,
image.EnvVarCudaVersion: "legacy",
},
expectedDevices: []string{gpuID},
},
{
description: "empty env returns all for legacy image",
env: map[string]string{
image.EnvVarCudaVersion: "legacy",
},
expectedDevices: []string{"all"},
},
// Add the `DOCKER_RESOURCE_GPUS` envvar and ensure that this is ignored when
// not enabled
{
description: "missing NVIDIA_VISIBLE_DEVICES returns nil for non-legacy image",
env: map[string]string{
envDockerResourceGPUs: anotherGPUID,
},
},
{
description: "blank NVIDIA_VISIBLE_DEVICES returns nil for non-legacy image",
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: "",
envDockerResourceGPUs: anotherGPUID,
},
},
{
description: "'void' NVIDIA_VISIBLE_DEVICES returns nil for non-legacy image",
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: "void",
envDockerResourceGPUs: anotherGPUID,
},
},
{
description: "'none' NVIDIA_VISIBLE_DEVICES returns empty for non-legacy image",
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: "none",
envDockerResourceGPUs: anotherGPUID,
},
expectedDevices: []string{""},
},
{
description: "NVIDIA_VISIBLE_DEVICES set returns value for non-legacy image",
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: gpuID,
envDockerResourceGPUs: anotherGPUID,
},
expectedDevices: []string{gpuID},
},
{
description: "NVIDIA_VISIBLE_DEVICES set returns value for legacy image",
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: gpuID,
envDockerResourceGPUs: anotherGPUID,
image.EnvVarCudaVersion: "legacy",
},
expectedDevices: []string{gpuID},
},
{
description: "empty env returns all for legacy image",
env: map[string]string{
envDockerResourceGPUs: anotherGPUID,
image.EnvVarCudaVersion: "legacy",
},
expectedDevices: []string{"all"},
},
// Add the `DOCKER_RESOURCE_GPUS` envvar and ensure that this is selected when
// enabled
{
description: "empty env returns nil for non-legacy image",
swarmResourceEnvvars: []string{envDockerResourceGPUs},
},
{
description: "blank DOCKER_RESOURCE_GPUS returns nil for non-legacy image",
swarmResourceEnvvars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: "",
},
},
{
description: "'void' DOCKER_RESOURCE_GPUS returns nil for non-legacy image",
swarmResourceEnvvars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: "void",
},
},
{
description: "'none' DOCKER_RESOURCE_GPUS returns empty for non-legacy image",
swarmResourceEnvvars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: "none",
},
expectedDevices: []string{""},
},
{
description: "DOCKER_RESOURCE_GPUS set returns value for non-legacy image",
swarmResourceEnvvars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: gpuID,
},
expectedDevices: []string{gpuID},
},
{
description: "DOCKER_RESOURCE_GPUS set returns value for legacy image",
swarmResourceEnvvars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: gpuID,
image.EnvVarCudaVersion: "legacy",
},
expectedDevices: []string{gpuID},
},
{
description: "DOCKER_RESOURCE_GPUS is selected if present",
swarmResourceEnvvars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: anotherGPUID,
},
expectedDevices: []string{anotherGPUID},
},
{
description: "DOCKER_RESOURCE_GPUS overrides NVIDIA_VISIBLE_DEVICES if present",
swarmResourceEnvvars: []string{envDockerResourceGPUs},
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: gpuID,
envDockerResourceGPUs: anotherGPUID,
},
expectedDevices: []string{anotherGPUID},
},
{
description: "DOCKER_RESOURCE_GPUS_ADDITIONAL overrides NVIDIA_VISIBLE_DEVICES if present",
swarmResourceEnvvars: []string{"DOCKER_RESOURCE_GPUS_ADDITIONAL"},
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: gpuID,
"DOCKER_RESOURCE_GPUS_ADDITIONAL": anotherGPUID,
},
expectedDevices: []string{anotherGPUID},
},
{
description: "All available swarm resource envvars are selected and override NVIDIA_VISIBLE_DEVICES if present",
swarmResourceEnvvars: []string{"DOCKER_RESOURCE_GPUS", "DOCKER_RESOURCE_GPUS_ADDITIONAL"},
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: gpuID,
"DOCKER_RESOURCE_GPUS": thirdGPUID,
"DOCKER_RESOURCE_GPUS_ADDITIONAL": anotherGPUID,
},
expectedDevices: []string{thirdGPUID, anotherGPUID},
},
{
description: "DOCKER_RESOURCE_GPUS_ADDITIONAL or DOCKER_RESOURCE_GPUS override NVIDIA_VISIBLE_DEVICES if present",
swarmResourceEnvvars: []string{"DOCKER_RESOURCE_GPUS", "DOCKER_RESOURCE_GPUS_ADDITIONAL"},
env: map[string]string{
image.EnvVarNvidiaVisibleDevices: gpuID,
"DOCKER_RESOURCE_GPUS_ADDITIONAL": anotherGPUID,
},
expectedDevices: []string{anotherGPUID},
},
}
for _, tc := range tests {
t.Run(tc.description, func(t *testing.T) {
image, _ := image.New(
image.WithEnvMap(tc.env),
)
devices := getDevicesFromEnvvar(image, tc.swarmResourceEnvvars)
require.EqualValues(t, tc.expectedDevices, devices)
})
}
}
func TestGetDriverCapabilities(t *testing.T) {
supportedCapabilities := "compute,display,utility,video"

View File

@@ -88,7 +88,7 @@ func (c hookConfig) getConfigOption(fieldName string) string {
// getSwarmResourceEnvvars returns the swarm resource envvars for the config.
func (c *hookConfig) getSwarmResourceEnvvars() []string {
if c.SwarmResource == "" {
if c == nil || c.SwarmResource == "" {
return nil
}

View File

@@ -21,8 +21,8 @@ The `runtimes` config option allows for the low-level runtime to be specified. T
The default value for this setting is:
```toml
runtimes = [
"docker-runc",
"runc",
"crun",
]
```

View File

@@ -27,7 +27,7 @@ const (
)
var availableRuntimes = map[string]struct{}{"docker": {}, "crio": {}, "containerd": {}}
var defaultLowLevelRuntimes = []string{"docker-runc", "runc", "crun"}
var defaultLowLevelRuntimes = []string{"runc", "crun"}
var waitingForSignal = make(chan bool, 1)
var signalReceived = make(chan bool, 1)

View File

@@ -67,7 +67,7 @@ swarm-resource = ""
debug = "/dev/null"
log-level = "info"
mode = "auto"
runtimes = ["docker-runc", "runc", "crun"]
runtimes = ["runc", "crun"]
[nvidia-container-runtime.modes]
@@ -131,7 +131,7 @@ swarm-resource = ""
debug = "/dev/null"
log-level = "info"
mode = "auto"
runtimes = ["docker-runc", "runc", "crun"]
runtimes = ["runc", "crun"]
[nvidia-container-runtime.modes]
@@ -198,7 +198,7 @@ swarm-resource = ""
debug = "/dev/null"
log-level = "info"
mode = "auto"
runtimes = ["docker-runc", "runc", "crun"]
runtimes = ["runc", "crun"]
[nvidia-container-runtime.modes]
@@ -262,7 +262,7 @@ swarm-resource = ""
debug = "/dev/null"
log-level = "info"
mode = "auto"
runtimes = ["docker-runc", "runc", "crun"]
runtimes = ["runc", "crun"]
[nvidia-container-runtime.modes]
@@ -348,7 +348,7 @@ swarm-resource = ""
debug = "/dev/null"
log-level = "info"
mode = "auto"
runtimes = ["docker-runc", "runc", "crun"]
runtimes = ["runc", "crun"]
[nvidia-container-runtime.modes]

View File

@@ -57,6 +57,7 @@ type options struct {
configSearchPaths cli.StringSlice
librarySearchPaths cli.StringSlice
disabledHooks cli.StringSlice
csv struct {
files cli.StringSlice
@@ -96,17 +97,20 @@ func (m command) build() *cli.Command {
Name: "config-search-path",
Usage: "Specify the path to search for config files when discovering the entities that should be included in the CDI specification.",
Destination: &opts.configSearchPaths,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_CONFIG_SEARCH_PATHS"},
},
&cli.StringFlag{
Name: "output",
Usage: "Specify the file to output the generated CDI specification to. If this is '' the specification is output to STDOUT",
Destination: &opts.output,
EnvVars: []string{"NVIDIA_CTK_CDI_OUTPUT_FILE_PATH"},
},
&cli.StringFlag{
Name: "format",
Usage: "The output format for the generated spec [json | yaml]. This overrides the format defined by the output file extension (if specified).",
Value: spec.FormatYAML,
Destination: &opts.format,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_OUTPUT_FORMAT"},
},
&cli.StringFlag{
Name: "mode",
@@ -116,27 +120,32 @@ func (m command) build() *cli.Command {
"If mode is set to 'auto' the mode will be determined based on the system configuration.",
Value: string(nvcdi.ModeAuto),
Destination: &opts.mode,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_MODE"},
},
&cli.StringFlag{
Name: "dev-root",
Usage: "Specify the root where `/dev` is located. If this is not specified, the driver-root is assumed.",
Destination: &opts.devRoot,
EnvVars: []string{"NVIDIA_CTK_DEV_ROOT"},
},
&cli.StringSliceFlag{
Name: "device-name-strategy",
Usage: "Specify the strategy for generating device names. If this is specified multiple times, the devices will be duplicated for each strategy. One of [index | uuid | type-index]",
Value: cli.NewStringSlice(nvcdi.DeviceNameStrategyIndex, nvcdi.DeviceNameStrategyUUID),
Destination: &opts.deviceNameStrategies,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_DEVICE_NAME_STRATEGIES"},
},
&cli.StringFlag{
Name: "driver-root",
Usage: "Specify the NVIDIA GPU driver root to use when discovering the entities that should be included in the CDI specification.",
Destination: &opts.driverRoot,
EnvVars: []string{"NVIDIA_CTK_DRIVER_ROOT"},
},
&cli.StringSliceFlag{
Name: "library-search-path",
Usage: "Specify the path to search for libraries when discovering the entities that should be included in the CDI specification.\n\tNote: This option only applies to CSV mode.",
Destination: &opts.librarySearchPaths,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_LIBRARY_SEARCH_PATHS"},
},
&cli.StringFlag{
Name: "nvidia-cdi-hook-path",
@@ -145,11 +154,13 @@ func (m command) build() *cli.Command {
"If not specified, the PATH will be searched for `nvidia-cdi-hook`. " +
"NOTE: That if this is specified as `nvidia-ctk`, the PATH will be searched for `nvidia-ctk` instead.",
Destination: &opts.nvidiaCDIHookPath,
EnvVars: []string{"NVIDIA_CTK_CDI_HOOK_PATH"},
},
&cli.StringFlag{
Name: "ldconfig-path",
Usage: "Specify the path to use for ldconfig in the generated CDI specification",
Destination: &opts.ldconfigPath,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_LDCONFIG_PATH"},
},
&cli.StringFlag{
Name: "vendor",
@@ -157,6 +168,7 @@ func (m command) build() *cli.Command {
Usage: "the vendor string to use for the generated CDI specification.",
Value: "nvidia.com",
Destination: &opts.vendor,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_VENDOR"},
},
&cli.StringFlag{
Name: "class",
@@ -164,17 +176,30 @@ func (m command) build() *cli.Command {
Usage: "the class string to use for the generated CDI specification.",
Value: "gpu",
Destination: &opts.class,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_CLASS"},
},
&cli.StringSliceFlag{
Name: "csv.file",
Usage: "The path to the list of CSV files to use when generating the CDI specification in CSV mode.",
Value: cli.NewStringSlice(csv.DefaultFileList()...),
Destination: &opts.csv.files,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_CSV_FILES"},
},
&cli.StringSliceFlag{
Name: "csv.ignore-pattern",
Usage: "Specify a pattern the CSV mount specifications.",
Usage: "specify a pattern the CSV mount specifications.",
Destination: &opts.csv.ignorePatterns,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_CSV_IGNORE_PATTERNS"},
},
&cli.StringSliceFlag{
Name: "disable-hook",
Aliases: []string{"disable-hooks"},
Usage: "specify a specific hook to skip when generating CDI " +
"specifications. This can be specified multiple times and the " +
"special hook name 'all' can be used ensure that the generated " +
"CDI specification does not include any hooks.",
Destination: &opts.disabledHooks,
EnvVars: []string{"NVIDIA_CTK_CDI_GENERATE_DISABLED_HOOKS"},
},
}
@@ -262,7 +287,7 @@ func (m command) generateSpec(opts *options) (spec.Interface, error) {
deviceNamers = append(deviceNamers, deviceNamer)
}
cdilib, err := nvcdi.New(
cdiOptions := []nvcdi.Option{
nvcdi.WithLogger(m.logger),
nvcdi.WithDriverRoot(opts.driverRoot),
nvcdi.WithDevRoot(opts.devRoot),
@@ -276,7 +301,13 @@ func (m command) generateSpec(opts *options) (spec.Interface, error) {
nvcdi.WithCSVIgnorePatterns(opts.csv.ignorePatterns.Value()),
// We set the following to allow for dependency injection:
nvcdi.WithNvmlLib(opts.nvmllib),
)
}
for _, hook := range opts.disabledHooks.Value() {
cdiOptions = append(cdiOptions, nvcdi.WithDisabledHook(hook))
}
cdilib, err := nvcdi.New(cdiOptions...)
if err != nil {
return nil, fmt.Errorf("failed to create CDI library: %v", err)
}

View File

@@ -26,6 +26,7 @@ import (
"github.com/NVIDIA/go-nvml/pkg/nvml/mock/dgxa100"
testlog "github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
"github.com/NVIDIA/nvidia-container-toolkit/internal/test"
)
@@ -110,6 +111,206 @@ containerEdits:
- /lib/x86_64-linux-gnu
env:
- NVIDIA_CTK_DEBUG=false
- hookName: createContainer
path: /usr/bin/nvidia-cdi-hook
args:
- nvidia-cdi-hook
- disable-device-node-modification
env:
- NVIDIA_CTK_DEBUG=false
mounts:
- hostPath: {{ .driverRoot }}/lib/x86_64-linux-gnu/libcuda.so.999.88.77
containerPath: /lib/x86_64-linux-gnu/libcuda.so.999.88.77
options:
- ro
- nosuid
- nodev
- rbind
- rprivate
`,
},
{
description: "disableHooks1",
options: options{
format: "yaml",
mode: "nvml",
vendor: "example.com",
class: "device",
driverRoot: driverRoot,
disabledHooks: valueOf(cli.NewStringSlice("enable-cuda-compat")),
},
expectedOptions: options{
format: "yaml",
mode: "nvml",
vendor: "example.com",
class: "device",
nvidiaCDIHookPath: "/usr/bin/nvidia-cdi-hook",
driverRoot: driverRoot,
disabledHooks: valueOf(cli.NewStringSlice("enable-cuda-compat")),
},
expectedSpec: `---
cdiVersion: 0.5.0
kind: example.com/device
devices:
- name: "0"
containerEdits:
deviceNodes:
- path: /dev/nvidia0
hostPath: {{ .driverRoot }}/dev/nvidia0
- name: all
containerEdits:
deviceNodes:
- path: /dev/nvidia0
hostPath: {{ .driverRoot }}/dev/nvidia0
containerEdits:
env:
- NVIDIA_VISIBLE_DEVICES=void
deviceNodes:
- path: /dev/nvidiactl
hostPath: {{ .driverRoot }}/dev/nvidiactl
hooks:
- hookName: createContainer
path: /usr/bin/nvidia-cdi-hook
args:
- nvidia-cdi-hook
- create-symlinks
- --link
- libcuda.so.1::/lib/x86_64-linux-gnu/libcuda.so
env:
- NVIDIA_CTK_DEBUG=false
- hookName: createContainer
path: /usr/bin/nvidia-cdi-hook
args:
- nvidia-cdi-hook
- update-ldcache
- --folder
- /lib/x86_64-linux-gnu
env:
- NVIDIA_CTK_DEBUG=false
- hookName: createContainer
path: /usr/bin/nvidia-cdi-hook
args:
- nvidia-cdi-hook
- disable-device-node-modification
env:
- NVIDIA_CTK_DEBUG=false
mounts:
- hostPath: {{ .driverRoot }}/lib/x86_64-linux-gnu/libcuda.so.999.88.77
containerPath: /lib/x86_64-linux-gnu/libcuda.so.999.88.77
options:
- ro
- nosuid
- nodev
- rbind
- rprivate
`,
},
{
description: "disableHooks2",
options: options{
format: "yaml",
mode: "nvml",
vendor: "example.com",
class: "device",
driverRoot: driverRoot,
disabledHooks: valueOf(cli.NewStringSlice("enable-cuda-compat", "update-ldcache")),
},
expectedOptions: options{
format: "yaml",
mode: "nvml",
vendor: "example.com",
class: "device",
nvidiaCDIHookPath: "/usr/bin/nvidia-cdi-hook",
driverRoot: driverRoot,
disabledHooks: valueOf(cli.NewStringSlice("enable-cuda-compat", "update-ldcache")),
},
expectedSpec: `---
cdiVersion: 0.5.0
kind: example.com/device
devices:
- name: "0"
containerEdits:
deviceNodes:
- path: /dev/nvidia0
hostPath: {{ .driverRoot }}/dev/nvidia0
- name: all
containerEdits:
deviceNodes:
- path: /dev/nvidia0
hostPath: {{ .driverRoot }}/dev/nvidia0
containerEdits:
env:
- NVIDIA_VISIBLE_DEVICES=void
deviceNodes:
- path: /dev/nvidiactl
hostPath: {{ .driverRoot }}/dev/nvidiactl
hooks:
- hookName: createContainer
path: /usr/bin/nvidia-cdi-hook
args:
- nvidia-cdi-hook
- create-symlinks
- --link
- libcuda.so.1::/lib/x86_64-linux-gnu/libcuda.so
env:
- NVIDIA_CTK_DEBUG=false
- hookName: createContainer
path: /usr/bin/nvidia-cdi-hook
args:
- nvidia-cdi-hook
- disable-device-node-modification
env:
- NVIDIA_CTK_DEBUG=false
mounts:
- hostPath: {{ .driverRoot }}/lib/x86_64-linux-gnu/libcuda.so.999.88.77
containerPath: /lib/x86_64-linux-gnu/libcuda.so.999.88.77
options:
- ro
- nosuid
- nodev
- rbind
- rprivate
`,
},
{
description: "disableHooksAll",
options: options{
format: "yaml",
mode: "nvml",
vendor: "example.com",
class: "device",
driverRoot: driverRoot,
disabledHooks: valueOf(cli.NewStringSlice("all")),
},
expectedOptions: options{
format: "yaml",
mode: "nvml",
vendor: "example.com",
class: "device",
nvidiaCDIHookPath: "/usr/bin/nvidia-cdi-hook",
driverRoot: driverRoot,
disabledHooks: valueOf(cli.NewStringSlice("all")),
},
expectedSpec: `---
cdiVersion: 0.5.0
kind: example.com/device
devices:
- name: "0"
containerEdits:
deviceNodes:
- path: /dev/nvidia0
hostPath: {{ .driverRoot }}/dev/nvidia0
- name: all
containerEdits:
deviceNodes:
- path: /dev/nvidia0
hostPath: {{ .driverRoot }}/dev/nvidia0
containerEdits:
env:
- NVIDIA_VISIBLE_DEVICES=void
deviceNodes:
- path: /dev/nvidiactl
hostPath: {{ .driverRoot }}/dev/nvidiactl
mounts:
- hostPath: {{ .driverRoot }}/lib/x86_64-linux-gnu/libcuda.so.999.88.77
containerPath: /lib/x86_64-linux-gnu/libcuda.so.999.88.77
@@ -162,3 +363,9 @@ containerEdits:
})
}
}
// valueOf returns the value of a pointer.
// Note that this does not check for a nil pointer and is only used for testing.
func valueOf[T any](v *T) T {
return *v
}

View File

@@ -64,6 +64,7 @@ func (m command) build() *cli.Command {
Usage: "specify the directories to scan for CDI specifications",
Value: cli.NewStringSlice(cdi.DefaultSpecDirs...),
Destination: &cfg.cdiSpecDirs,
EnvVars: []string{"NVIDIA_CTK_CDI_SPEC_DIRS"},
},
}

View File

@@ -14,7 +14,7 @@
# This Dockerfile is also used to define the golang version used in this project
# This allows dependabot to manage this version in addition to other images.
FROM golang:1.24.3
FROM golang:1.24.4
WORKDIR /work
COPY * .

View File

@@ -1,4 +1,3 @@
/**
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,19 +11,13 @@
# 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 nvcdi
[Unit]
Description=Trigger CDI refresh on NVIDIA driver install / uninstall events
// disabledHooks allows individual hooks to be disabled.
type disabledHooks map[HookName]bool
[Path]
PathChanged=/lib/modules/%v/modules.dep
PathChanged=/lib/modules/%v/modules.dep.bin
// HookIsSupported checks whether a hook of the specified name is supported.
// Hooks must be explicitly disabled, meaning that if no disabled hooks are
// all hooks are supported.
func (l *nvcdilib) HookIsSupported(h HookName) bool {
if len(l.disabledHooks) == 0 {
return true
}
return !l.disabledHooks[h]
}
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,28 @@
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# 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.
[Unit]
Description=Refresh NVIDIA CDI specification file
ConditionPathExists=/usr/bin/nvidia-smi
ConditionPathExists=/usr/bin/nvidia-ctk
[Service]
Type=oneshot
EnvironmentFile=-/etc/nvidia-container-toolkit/cdi-refresh.env
ExecCondition=/usr/bin/grep -qE '/nvidia.ko' /lib/modules/%v/modules.dep
ExecStart=/usr/bin/nvidia-ctk cdi generate --output=/var/run/cdi/nvidia.yaml
CapabilityBoundingSet=CAP_SYS_MODULE CAP_SYS_ADMIN CAP_MKNOD
[Install]
WantedBy=multi-user.target

View File

@@ -55,6 +55,7 @@ RUN make PREFIX=${DIST_DIR} cmds
WORKDIR $DIST_DIR
COPY packaging/debian ./debian
COPY deployments/systemd/ .
ARG LIBNVIDIA_CONTAINER_TOOLS_VERSION
ENV LIBNVIDIA_CONTAINER_TOOLS_VERSION ${LIBNVIDIA_CONTAINER_TOOLS_VERSION}

View File

@@ -46,6 +46,7 @@ RUN make PREFIX=${DIST_DIR} cmds
WORKDIR $DIST_DIR/..
COPY packaging/rpm .
COPY deployments/systemd/ .
ARG LIBNVIDIA_CONTAINER_TOOLS_VERSION
ENV LIBNVIDIA_CONTAINER_TOOLS_VERSION ${LIBNVIDIA_CONTAINER_TOOLS_VERSION}

View File

@@ -71,6 +71,7 @@ RUN make PREFIX=${DIST_DIR} cmds
WORKDIR $DIST_DIR/..
COPY packaging/rpm .
COPY deployments/systemd/ ${DIST_DIR}/
ARG LIBNVIDIA_CONTAINER_TOOLS_VERSION
ENV LIBNVIDIA_CONTAINER_TOOLS_VERSION ${LIBNVIDIA_CONTAINER_TOOLS_VERSION}

View File

@@ -53,6 +53,7 @@ RUN make PREFIX=${DIST_DIR} cmds
WORKDIR $DIST_DIR
COPY packaging/debian ./debian
COPY deployments/systemd/ .
ARG LIBNVIDIA_CONTAINER_TOOLS_VERSION
ENV LIBNVIDIA_CONTAINER_TOOLS_VERSION ${LIBNVIDIA_CONTAINER_TOOLS_VERSION}

10
go.mod
View File

@@ -3,8 +3,8 @@ module github.com/NVIDIA/nvidia-container-toolkit
go 1.23.0
require (
github.com/NVIDIA/go-nvlib v0.7.2
github.com/NVIDIA/go-nvml v0.12.4-1
github.com/NVIDIA/go-nvlib v0.7.3
github.com/NVIDIA/go-nvml v0.12.9-0
github.com/cyphar/filepath-securejoin v0.4.1
github.com/moby/sys/reexec v0.1.0
github.com/moby/sys/symlink v0.3.0
@@ -13,15 +13,15 @@ require (
github.com/pelletier/go-toml v1.9.5
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.10.0
github.com/urfave/cli/v2 v2.27.6
golang.org/x/mod v0.24.0
github.com/urfave/cli/v2 v2.27.7
golang.org/x/mod v0.25.0
golang.org/x/sys v0.33.0
tags.cncf.io/container-device-interface v1.0.1
tags.cncf.io/container-device-interface/specs-go v1.0.0
)
require (
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect

20
go.sum
View File

@@ -1,11 +1,11 @@
github.com/NVIDIA/go-nvlib v0.7.2 h1:7sy/NVUa4sM9FLKwH6CjBfHSWrJUmv8emVyxLTzjfOA=
github.com/NVIDIA/go-nvlib v0.7.2/go.mod h1:2Kh2kYSP5IJ8EKf0/SYDzHiQKb9EJkwOf2LQzu6pXzY=
github.com/NVIDIA/go-nvml v0.12.4-1 h1:WKUvqshhWSNTfm47ETRhv0A0zJyr1ncCuHiXwoTrBEc=
github.com/NVIDIA/go-nvml v0.12.4-1/go.mod h1:8Llmj+1Rr+9VGGwZuRer5N/aCjxGuR5nPb/9ebBiIEQ=
github.com/NVIDIA/go-nvlib v0.7.3 h1:kXc8PkWUlrwedSpM4fR8xT/DAq1NKy8HqhpgteFcGAw=
github.com/NVIDIA/go-nvlib v0.7.3/go.mod h1:i95Je7GinMy/+BDs++DAdbPmT2TubjNP8i8joC7DD7I=
github.com/NVIDIA/go-nvml v0.12.9-0 h1:e344UK8ZkeMeeLkdQtRhmXRxNf+u532LDZPGMtkdus0=
github.com/NVIDIA/go-nvml v0.12.9-0/go.mod h1:+KNA7c7gIBH7SKSJ1ntlwkfN80zdx8ovl4hrK3LmPt4=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
@@ -69,8 +69,8 @@ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU=
github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -80,8 +80,8 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@@ -110,7 +110,7 @@ func GetDefault() (*Config, error) {
NVIDIAContainerRuntimeConfig: RuntimeConfig{
DebugFilePath: "/dev/null",
LogLevel: "info",
Runtimes: []string{"docker-runc", "runc", "crun"},
Runtimes: []string{"runc", "crun"},
Mode: "auto",
Modes: modesConfig{
CSV: csvModeConfig{

View File

@@ -63,7 +63,7 @@ func TestGetConfig(t *testing.T) {
NVIDIAContainerRuntimeConfig: RuntimeConfig{
DebugFilePath: "/dev/null",
LogLevel: "info",
Runtimes: []string{"docker-runc", "runc", "crun"},
Runtimes: []string{"runc", "crun"},
Mode: "auto",
Modes: modesConfig{
CSV: csvModeConfig{
@@ -170,7 +170,7 @@ func TestGetConfig(t *testing.T) {
NVIDIAContainerRuntimeConfig: RuntimeConfig{
DebugFilePath: "/dev/null",
LogLevel: "info",
Runtimes: []string{"docker-runc", "runc", "crun"},
Runtimes: []string{"runc", "crun"},
Mode: "auto",
Modes: modesConfig{
CSV: csvModeConfig{
@@ -289,7 +289,7 @@ func TestGetConfig(t *testing.T) {
NVIDIAContainerRuntimeConfig: RuntimeConfig{
DebugFilePath: "/dev/null",
LogLevel: "info",
Runtimes: []string{"docker-runc", "runc", "crun"},
Runtimes: []string{"runc", "crun"},
Mode: "auto",
Modes: modesConfig{
CSV: csvModeConfig{
@@ -331,7 +331,7 @@ func TestGetConfig(t *testing.T) {
NVIDIAContainerRuntimeConfig: RuntimeConfig{
DebugFilePath: "/dev/null",
LogLevel: "info",
Runtimes: []string{"docker-runc", "runc", "crun"},
Runtimes: []string{"runc", "crun"},
Mode: "auto",
Modes: modesConfig{
CSV: csvModeConfig{

View File

@@ -21,22 +21,35 @@ import (
"strings"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
)
type builder struct {
env map[string]string
mounts []specs.Mount
CUDA
disableRequire bool
}
// Option is a functional option for creating a CUDA image.
type Option func(*builder) error
// New creates a new CUDA image from the input options.
func New(opt ...Option) (CUDA, error) {
b := &builder{}
b := &builder{
CUDA: CUDA{
acceptEnvvarUnprivileged: true,
},
}
for _, o := range opt {
if err := o(b); err != nil {
return CUDA{}, err
}
}
if b.logger == nil {
b.logger = logger.New()
}
if b.env == nil {
b.env = make(map[string]string)
}
@@ -50,15 +63,36 @@ func (b builder) build() (CUDA, error) {
b.env[EnvVarNvidiaDisableRequire] = "true"
}
c := CUDA{
env: b.env,
mounts: b.mounts,
}
return c, nil
return b.CUDA, nil
}
// Option is a functional option for creating a CUDA image.
type Option func(*builder) error
func WithAcceptDeviceListAsVolumeMounts(acceptDeviceListAsVolumeMounts bool) Option {
return func(b *builder) error {
b.acceptDeviceListAsVolumeMounts = acceptDeviceListAsVolumeMounts
return nil
}
}
func WithAcceptEnvvarUnprivileged(acceptEnvvarUnprivileged bool) Option {
return func(b *builder) error {
b.acceptEnvvarUnprivileged = acceptEnvvarUnprivileged
return nil
}
}
func WithAnnotations(annotations map[string]string) Option {
return func(b *builder) error {
b.annotations = annotations
return nil
}
}
func WithAnnotationsPrefixes(annotationsPrefixes []string) Option {
return func(b *builder) error {
b.annotationsPrefixes = annotationsPrefixes
return nil
}
}
// WithDisableRequire sets the disable require option.
func WithDisableRequire(disableRequire bool) Option {
@@ -93,6 +127,14 @@ func WithEnvMap(env map[string]string) Option {
}
}
// WithLogger sets the logger to use when creating the CUDA image.
func WithLogger(logger logger.Interface) Option {
return func(b *builder) error {
b.logger = logger
return nil
}
}
// WithMounts sets the mounts associated with the CUDA image.
func WithMounts(mounts []specs.Mount) Option {
return func(b *builder) error {
@@ -100,3 +142,20 @@ func WithMounts(mounts []specs.Mount) Option {
return nil
}
}
// WithPreferredVisibleDevicesEnvVars sets the environment variables that
// should take precedence over the default NVIDIA_VISIBLE_DEVICES.
func WithPreferredVisibleDevicesEnvVars(preferredVisibleDeviceEnvVars ...string) Option {
return func(b *builder) error {
b.preferredVisibleDeviceEnvVars = preferredVisibleDeviceEnvVars
return nil
}
}
// WithPrivileged sets whether an image is privileged or not.
func WithPrivileged(isPrivileged bool) Option {
return func(b *builder) error {
b.isPrivileged = isPrivileged
return nil
}
}

View File

@@ -25,6 +25,8 @@ import (
"github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/mod/semver"
"tags.cncf.io/container-device-interface/pkg/parser"
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
)
const (
@@ -38,27 +40,44 @@ const (
// a map of environment variable to values that can be used to perform lookups
// such as requirements.
type CUDA struct {
env map[string]string
mounts []specs.Mount
logger logger.Interface
annotations map[string]string
env map[string]string
isPrivileged bool
mounts []specs.Mount
annotationsPrefixes []string
acceptDeviceListAsVolumeMounts bool
acceptEnvvarUnprivileged bool
preferredVisibleDeviceEnvVars []string
}
// NewCUDAImageFromSpec creates a CUDA image from the input OCI runtime spec.
// The process environment is read (if present) to construc the CUDA Image.
func NewCUDAImageFromSpec(spec *specs.Spec) (CUDA, error) {
func NewCUDAImageFromSpec(spec *specs.Spec, opts ...Option) (CUDA, error) {
if spec == nil {
return New(opts...)
}
var env []string
if spec != nil && spec.Process != nil {
if spec.Process != nil {
env = spec.Process.Env
}
return New(
specOpts := []Option{
WithAnnotations(spec.Annotations),
WithEnv(env),
WithMounts(spec.Mounts),
)
WithPrivileged(IsPrivileged((*OCISpec)(spec))),
}
return New(append(opts, specOpts...)...)
}
// NewCUDAImageFromEnv creates a CUDA image from the input environment. The environment
// newCUDAImageFromEnv creates a CUDA image from the input environment. The environment
// is a list of strings of the form ENVAR=VALUE.
func NewCUDAImageFromEnv(env []string) (CUDA, error) {
func newCUDAImageFromEnv(env []string) (CUDA, error) {
return New(WithEnv(env))
}
@@ -83,6 +102,10 @@ func (i CUDA) IsLegacy() bool {
return len(legacyCudaVersion) > 0 && len(cudaRequire) == 0
}
func (i CUDA) IsPrivileged() bool {
return i.isPrivileged
}
// GetRequirements returns the requirements from all NVIDIA_REQUIRE_ environment
// variables.
func (i CUDA) GetRequirements() ([]string, error) {
@@ -200,46 +223,115 @@ 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.VisibleDevicesFromEnvVar() {
for _, device := range i.VisibleDevices() {
if !parser.IsQualifiedName(device) {
return false
}
hasCDIdevice = true
}
for _, device := range i.DevicesFromMounts() {
if !strings.HasPrefix(device, "cdi/") {
return false
}
hasCDIdevice = true
}
return hasCDIdevice
}
// 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()
// VisibleDevices returns a list of devices requested in the container image.
// If volume mount requests are enabled these are returned if requested,
// otherwise device requests through environment variables are considered.
// In cases where environment variable requests required privileged containers,
// such devices requests are ignored.
func (i CUDA) VisibleDevices() []string {
// If annotation device requests are present, these are preferred.
annotationDeviceRequests := i.cdiDeviceRequestsFromAnnotations()
if len(annotationDeviceRequests) > 0 {
return annotationDeviceRequests
}
// If enabled, try and get the device list from volume mounts first
if i.acceptDeviceListAsVolumeMounts {
volumeMountDeviceRequests := i.visibleDevicesFromMounts()
if len(volumeMountDeviceRequests) > 0 {
return volumeMountDeviceRequests
}
}
// Get the Fallback to reading from the environment variable if privileges are correct
envVarDeviceRequests := i.VisibleDevicesFromEnvVar()
if len(envVarDeviceRequests) == 0 {
return nil
}
// If the container is privileged, or environment variable requests are
// allowed for unprivileged containers, these devices are returned.
if i.isPrivileged || i.acceptEnvvarUnprivileged {
return envVarDeviceRequests
}
// We log a warning if we are ignoring the environment variable requests.
i.logger.Warningf("Ignoring devices specified in NVIDIA_VISIBLE_DEVICES in unprivileged container")
return nil
}
// VisibleDevicesFromMounts returns the set of visible devices requested as mounts.
func (i CUDA) VisibleDevicesFromMounts() []string {
// cdiDeviceRequestsFromAnnotations returns a list of devices specified in the
// annotations.
// Keys starting with the specified prefixes are considered and expected to
// contain a comma-separated list of fully-qualified CDI devices names.
// The format of the requested devices is not checked and the list is not
// deduplicated.
func (i CUDA) cdiDeviceRequestsFromAnnotations() []string {
if len(i.annotationsPrefixes) == 0 || len(i.annotations) == 0 {
return nil
}
var devices []string
for _, device := range i.DevicesFromMounts() {
switch {
case strings.HasPrefix(device, volumeMountDevicePrefixCDI):
continue
case strings.HasPrefix(device, volumeMountDevicePrefixImex):
continue
for key, value := range i.annotations {
for _, prefix := range i.annotationsPrefixes {
if strings.HasPrefix(key, prefix) {
devices = append(devices, strings.Split(value, ",")...)
// There is no need to check additional prefixes since we
// typically deduplicate devices in any case.
break
}
}
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 {
// VisibleDevicesFromEnvVar returns the set of visible devices requested through environment variables.
// If any of the preferredVisibleDeviceEnvVars are present in the image, they
// are used to determine the visible devices. If this is not the case, the
// NVIDIA_VISIBLE_DEVICES environment variable is used.
func (i CUDA) VisibleDevicesFromEnvVar() []string {
for _, envVar := range i.preferredVisibleDeviceEnvVars {
if i.HasEnvvar(envVar) {
return i.DevicesFromEnvvars(i.preferredVisibleDeviceEnvVars...).List()
}
}
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.requestsFromMounts() {
switch {
case strings.HasPrefix(device, volumeMountDevicePrefixImex):
continue
case strings.HasPrefix(device, volumeMountDevicePrefixCDI):
name, err := cdiDeviceMountRequest(device).qualifiedName()
if err != nil {
i.logger.Warningf("Ignoring invalid mount request for CDI device %v: %v", device, err)
continue
}
devices = append(devices, name)
default:
devices = append(devices, device)
}
}
return devices
}
// requestsFromMounts returns a list of device specified as mounts.
func (i CUDA) requestsFromMounts() []string {
root := filepath.Clean(DeviceListAsVolumeMountsRoot)
seen := make(map[string]bool)
var devices []string
@@ -271,23 +363,30 @@ func (i CUDA) DevicesFromMounts() []string {
return devices
}
// CDIDevicesFromMounts returns a list of CDI devices specified as mounts on the image.
func (i CUDA) CDIDevicesFromMounts() []string {
var devices []string
for _, mountDevice := range i.DevicesFromMounts() {
if !strings.HasPrefix(mountDevice, volumeMountDevicePrefixCDI) {
continue
}
parts := strings.SplitN(strings.TrimPrefix(mountDevice, volumeMountDevicePrefixCDI), "/", 3)
if len(parts) != 3 {
continue
}
vendor := parts[0]
class := parts[1]
device := parts[2]
devices = append(devices, fmt.Sprintf("%s/%s=%s", vendor, class, device))
// a cdiDeviceMountRequest represents a CDI device requests as a mount.
// Here the host path /dev/null is mounted to a particular path in the container.
// The container path has the form:
// /var/run/nvidia-container-devices/cdi/<vendor>/<class>/<device>
// or
// /var/run/nvidia-container-devices/cdi/<vendor>/<class>=<device>
type cdiDeviceMountRequest string
// qualifiedName returns the fully-qualified name of the CDI device.
func (m cdiDeviceMountRequest) qualifiedName() (string, error) {
if !strings.HasPrefix(string(m), volumeMountDevicePrefixCDI) {
return "", fmt.Errorf("invalid mount CDI device request: %s", m)
}
return devices
requestedDevice := strings.TrimPrefix(string(m), volumeMountDevicePrefixCDI)
if parser.IsQualifiedName(requestedDevice) {
return requestedDevice, nil
}
parts := strings.SplitN(requestedDevice, "/", 3)
if len(parts) != 3 {
return "", fmt.Errorf("invalid mount CDI device request: %s", m)
}
return fmt.Sprintf("%s/%s=%s", parts[0], parts[1], parts[2]), nil
}
// ImexChannelsFromEnvVar returns the list of IMEX channels requested for the image.
@@ -302,7 +401,7 @@ func (i CUDA) ImexChannelsFromEnvVar() []string {
// ImexChannelsFromMounts returns the list of IMEX channels requested for the image.
func (i CUDA) ImexChannelsFromMounts() []string {
var channels []string
for _, mountDevice := range i.DevicesFromMounts() {
for _, mountDevice := range i.requestsFromMounts() {
if !strings.HasPrefix(mountDevice, volumeMountDevicePrefixImex) {
continue
}

View File

@@ -21,9 +21,91 @@ import (
"testing"
"github.com/opencontainers/runtime-spec/specs-go"
testlog "github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/require"
)
func TestNewCUDAImageFromSpec(t *testing.T) {
logger, _ := testlog.NewNullLogger()
testCases := []struct {
description string
spec *specs.Spec
options []Option
expected CUDA
}{
{
description: "no env vars",
spec: &specs.Spec{
Process: &specs.Process{
Env: []string{},
},
},
expected: CUDA{
logger: logger,
env: map[string]string{},
acceptEnvvarUnprivileged: true,
},
},
{
description: "NVIDIA_VISIBLE_DEVICES=all",
spec: &specs.Spec{
Process: &specs.Process{
Env: []string{"NVIDIA_VISIBLE_DEVICES=all"},
},
},
expected: CUDA{
logger: logger,
env: map[string]string{"NVIDIA_VISIBLE_DEVICES": "all"},
acceptEnvvarUnprivileged: true,
},
},
{
description: "Spec overrides options",
spec: &specs.Spec{
Process: &specs.Process{
Env: []string{"NVIDIA_VISIBLE_DEVICES=all"},
},
Mounts: []specs.Mount{
{
Source: "/spec-source",
Destination: "/spec-destination",
},
},
},
options: []Option{
WithEnvMap(map[string]string{"OTHER": "value"}),
WithMounts([]specs.Mount{
{
Source: "/option-source",
Destination: "/option-destination",
},
}),
},
expected: CUDA{
logger: logger,
env: map[string]string{"NVIDIA_VISIBLE_DEVICES": "all"},
mounts: []specs.Mount{
{
Source: "/spec-source",
Destination: "/spec-destination",
},
},
acceptEnvvarUnprivileged: true,
},
},
}
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
options := append([]Option{WithLogger(logger)}, tc.options...)
image, err := NewCUDAImageFromSpec(tc.spec, options...)
require.NoError(t, err)
require.EqualValues(t, tc.expected, image)
})
}
}
func TestParseMajorMinorVersionValid(t *testing.T) {
var tests = []struct {
version string
@@ -122,7 +204,7 @@ func TestGetRequirements(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
image, err := NewCUDAImageFromEnv(tc.env)
image, err := newCUDAImageFromEnv(tc.env)
require.NoError(t, err)
requirements, err := image.GetRequirements()
@@ -133,6 +215,226 @@ func TestGetRequirements(t *testing.T) {
}
}
func TestGetDevicesFromEnvvar(t *testing.T) {
envDockerResourceGPUs := "DOCKER_RESOURCE_GPUS"
gpuID := "GPU-12345"
anotherGPUID := "GPU-67890"
thirdGPUID := "MIG-12345"
var tests = []struct {
description string
preferredVisibleDeviceEnvVars []string
env map[string]string
expectedDevices []string
}{
{
description: "empty env returns nil for non-legacy image",
},
{
description: "blank NVIDIA_VISIBLE_DEVICES returns nil for non-legacy image",
env: map[string]string{
EnvVarNvidiaVisibleDevices: "",
},
},
{
description: "'void' NVIDIA_VISIBLE_DEVICES returns nil for non-legacy image",
env: map[string]string{
EnvVarNvidiaVisibleDevices: "void",
},
},
{
description: "'none' NVIDIA_VISIBLE_DEVICES returns empty for non-legacy image",
env: map[string]string{
EnvVarNvidiaVisibleDevices: "none",
},
expectedDevices: []string{""},
},
{
description: "NVIDIA_VISIBLE_DEVICES set returns value for non-legacy image",
env: map[string]string{
EnvVarNvidiaVisibleDevices: gpuID,
},
expectedDevices: []string{gpuID},
},
{
description: "NVIDIA_VISIBLE_DEVICES set returns value for legacy image",
env: map[string]string{
EnvVarNvidiaVisibleDevices: gpuID,
EnvVarCudaVersion: "legacy",
},
expectedDevices: []string{gpuID},
},
{
description: "empty env returns all for legacy image",
env: map[string]string{
EnvVarCudaVersion: "legacy",
},
expectedDevices: []string{"all"},
},
// Add the `DOCKER_RESOURCE_GPUS` envvar and ensure that this is ignored when
// not enabled
{
description: "missing NVIDIA_VISIBLE_DEVICES returns nil for non-legacy image",
env: map[string]string{
envDockerResourceGPUs: anotherGPUID,
},
},
{
description: "blank NVIDIA_VISIBLE_DEVICES returns nil for non-legacy image",
env: map[string]string{
EnvVarNvidiaVisibleDevices: "",
envDockerResourceGPUs: anotherGPUID,
},
},
{
description: "'void' NVIDIA_VISIBLE_DEVICES returns nil for non-legacy image",
env: map[string]string{
EnvVarNvidiaVisibleDevices: "void",
envDockerResourceGPUs: anotherGPUID,
},
},
{
description: "'none' NVIDIA_VISIBLE_DEVICES returns empty for non-legacy image",
env: map[string]string{
EnvVarNvidiaVisibleDevices: "none",
envDockerResourceGPUs: anotherGPUID,
},
expectedDevices: []string{""},
},
{
description: "NVIDIA_VISIBLE_DEVICES set returns value for non-legacy image",
env: map[string]string{
EnvVarNvidiaVisibleDevices: gpuID,
envDockerResourceGPUs: anotherGPUID,
},
expectedDevices: []string{gpuID},
},
{
description: "NVIDIA_VISIBLE_DEVICES set returns value for legacy image",
env: map[string]string{
EnvVarNvidiaVisibleDevices: gpuID,
envDockerResourceGPUs: anotherGPUID,
EnvVarCudaVersion: "legacy",
},
expectedDevices: []string{gpuID},
},
{
description: "empty env returns all for legacy image",
env: map[string]string{
envDockerResourceGPUs: anotherGPUID,
EnvVarCudaVersion: "legacy",
},
expectedDevices: []string{"all"},
},
// Add the `DOCKER_RESOURCE_GPUS` envvar and ensure that this is selected when
// enabled
{
description: "empty env returns nil for non-legacy image",
preferredVisibleDeviceEnvVars: []string{envDockerResourceGPUs},
},
{
description: "blank DOCKER_RESOURCE_GPUS returns nil for non-legacy image",
preferredVisibleDeviceEnvVars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: "",
},
},
{
description: "'void' DOCKER_RESOURCE_GPUS returns nil for non-legacy image",
preferredVisibleDeviceEnvVars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: "void",
},
},
{
description: "'none' DOCKER_RESOURCE_GPUS returns empty for non-legacy image",
preferredVisibleDeviceEnvVars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: "none",
},
expectedDevices: []string{""},
},
{
description: "DOCKER_RESOURCE_GPUS set returns value for non-legacy image",
preferredVisibleDeviceEnvVars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: gpuID,
},
expectedDevices: []string{gpuID},
},
{
description: "DOCKER_RESOURCE_GPUS set returns value for legacy image",
preferredVisibleDeviceEnvVars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: gpuID,
EnvVarCudaVersion: "legacy",
},
expectedDevices: []string{gpuID},
},
{
description: "DOCKER_RESOURCE_GPUS is selected if present",
preferredVisibleDeviceEnvVars: []string{envDockerResourceGPUs},
env: map[string]string{
envDockerResourceGPUs: anotherGPUID,
},
expectedDevices: []string{anotherGPUID},
},
{
description: "DOCKER_RESOURCE_GPUS overrides NVIDIA_VISIBLE_DEVICES if present",
preferredVisibleDeviceEnvVars: []string{envDockerResourceGPUs},
env: map[string]string{
EnvVarNvidiaVisibleDevices: gpuID,
envDockerResourceGPUs: anotherGPUID,
},
expectedDevices: []string{anotherGPUID},
},
{
description: "DOCKER_RESOURCE_GPUS_ADDITIONAL overrides NVIDIA_VISIBLE_DEVICES if present",
preferredVisibleDeviceEnvVars: []string{"DOCKER_RESOURCE_GPUS_ADDITIONAL"},
env: map[string]string{
EnvVarNvidiaVisibleDevices: gpuID,
"DOCKER_RESOURCE_GPUS_ADDITIONAL": anotherGPUID,
},
expectedDevices: []string{anotherGPUID},
},
{
description: "All available swarm resource envvars are selected and override NVIDIA_VISIBLE_DEVICES if present",
preferredVisibleDeviceEnvVars: []string{"DOCKER_RESOURCE_GPUS", "DOCKER_RESOURCE_GPUS_ADDITIONAL"},
env: map[string]string{
EnvVarNvidiaVisibleDevices: gpuID,
"DOCKER_RESOURCE_GPUS": thirdGPUID,
"DOCKER_RESOURCE_GPUS_ADDITIONAL": anotherGPUID,
},
expectedDevices: []string{thirdGPUID, anotherGPUID},
},
{
description: "DOCKER_RESOURCE_GPUS_ADDITIONAL or DOCKER_RESOURCE_GPUS override NVIDIA_VISIBLE_DEVICES if present",
preferredVisibleDeviceEnvVars: []string{"DOCKER_RESOURCE_GPUS", "DOCKER_RESOURCE_GPUS_ADDITIONAL"},
env: map[string]string{
EnvVarNvidiaVisibleDevices: gpuID,
"DOCKER_RESOURCE_GPUS_ADDITIONAL": anotherGPUID,
},
expectedDevices: []string{anotherGPUID},
},
}
for _, tc := range tests {
t.Run(tc.description, func(t *testing.T) {
image, err := New(
WithEnvMap(tc.env),
WithPrivileged(true),
WithAcceptDeviceListAsVolumeMounts(false),
WithAcceptEnvvarUnprivileged(false),
WithPreferredVisibleDevicesEnvVars(tc.preferredVisibleDeviceEnvVars...),
)
require.NoError(t, err)
devices := image.VisibleDevicesFromEnvVar()
require.EqualValues(t, tc.expectedDevices, devices)
})
}
}
func TestGetVisibleDevicesFromMounts(t *testing.T) {
var tests = []struct {
description string
@@ -185,9 +487,9 @@ func TestGetVisibleDevicesFromMounts(t *testing.T) {
expectedDevices: []string{"GPU0-MIG0/0/1", "GPU1-MIG0/0/1"},
},
{
description: "cdi devices are ignored",
mounts: makeTestMounts("GPU0", "cdi/nvidia.com/gpu=all", "GPU1"),
expectedDevices: []string{"GPU0", "GPU1"},
description: "cdi devices are included",
mounts: makeTestMounts("GPU0", "nvidia.com/gpu=all", "GPU1"),
expectedDevices: []string{"GPU0", "nvidia.com/gpu=all", "GPU1"},
},
{
description: "imex devices are ignored",
@@ -197,8 +499,121 @@ func TestGetVisibleDevicesFromMounts(t *testing.T) {
}
for _, tc := range tests {
t.Run(tc.description, func(t *testing.T) {
image, _ := New(WithMounts(tc.mounts))
require.Equal(t, tc.expectedDevices, image.VisibleDevicesFromMounts())
image, err := New(WithMounts(tc.mounts))
require.NoError(t, err)
require.Equal(t, tc.expectedDevices, image.visibleDevicesFromMounts())
})
}
}
func TestVisibleDevices(t *testing.T) {
var tests = []struct {
description string
mountDevices []specs.Mount
envvarDevices string
privileged bool
acceptUnprivileged bool
acceptMounts bool
expectedDevices []string
}{
{
description: "Mount devices, unprivileged, no accept unprivileged",
mountDevices: []specs.Mount{
{
Source: "/dev/null",
Destination: filepath.Join(DeviceListAsVolumeMountsRoot, "GPU0"),
},
{
Source: "/dev/null",
Destination: filepath.Join(DeviceListAsVolumeMountsRoot, "GPU1"),
},
},
envvarDevices: "GPU2,GPU3",
privileged: false,
acceptUnprivileged: false,
acceptMounts: true,
expectedDevices: []string{"GPU0", "GPU1"},
},
{
description: "No mount devices, unprivileged, no accept unprivileged",
mountDevices: nil,
envvarDevices: "GPU0,GPU1",
privileged: false,
acceptUnprivileged: false,
acceptMounts: true,
expectedDevices: nil,
},
{
description: "No mount devices, privileged, no accept unprivileged",
mountDevices: nil,
envvarDevices: "GPU0,GPU1",
privileged: true,
acceptUnprivileged: false,
acceptMounts: true,
expectedDevices: []string{"GPU0", "GPU1"},
},
{
description: "No mount devices, unprivileged, accept unprivileged",
mountDevices: nil,
envvarDevices: "GPU0,GPU1",
privileged: false,
acceptUnprivileged: true,
acceptMounts: true,
expectedDevices: []string{"GPU0", "GPU1"},
},
{
description: "Mount devices, unprivileged, accept unprivileged, no accept mounts",
mountDevices: []specs.Mount{
{
Source: "/dev/null",
Destination: filepath.Join(DeviceListAsVolumeMountsRoot, "GPU0"),
},
{
Source: "/dev/null",
Destination: filepath.Join(DeviceListAsVolumeMountsRoot, "GPU1"),
},
},
envvarDevices: "GPU2,GPU3",
privileged: false,
acceptUnprivileged: true,
acceptMounts: false,
expectedDevices: []string{"GPU2", "GPU3"},
},
{
description: "Mount devices, unprivileged, no accept unprivileged, no accept mounts",
mountDevices: []specs.Mount{
{
Source: "/dev/null",
Destination: filepath.Join(DeviceListAsVolumeMountsRoot, "GPU0"),
},
{
Source: "/dev/null",
Destination: filepath.Join(DeviceListAsVolumeMountsRoot, "GPU1"),
},
},
envvarDevices: "GPU2,GPU3",
privileged: false,
acceptUnprivileged: false,
acceptMounts: false,
expectedDevices: nil,
},
}
for _, tc := range tests {
t.Run(tc.description, func(t *testing.T) {
// Wrap the call to getDevices() in a closure.
image, err := New(
WithEnvMap(
map[string]string{
EnvVarNvidiaVisibleDevices: tc.envvarDevices,
},
),
WithMounts(tc.mountDevices),
WithPrivileged(tc.privileged),
WithAcceptDeviceListAsVolumeMounts(tc.acceptMounts),
WithAcceptEnvvarUnprivileged(tc.acceptUnprivileged),
)
require.NoError(t, err)
require.Equal(t, tc.expectedDevices, image.VisibleDevices())
})
}
}
@@ -224,7 +639,7 @@ func TestImexChannelsFromEnvVar(t *testing.T) {
for _, tc := range testCases {
for id, baseEnvvars := range map[string][]string{"": nil, "legacy": {"CUDA_VERSION=1.2.3"}} {
t.Run(tc.description+id, func(t *testing.T) {
i, err := NewCUDAImageFromEnv(append(baseEnvvars, tc.env...))
i, err := newCUDAImageFromEnv(append(baseEnvvars, tc.env...))
require.NoError(t, err)
channels := i.ImexChannelsFromEnvVar()
@@ -234,6 +649,73 @@ func TestImexChannelsFromEnvVar(t *testing.T) {
}
}
func TestCDIDeviceRequestsFromAnnotations(t *testing.T) {
testCases := []struct {
description string
prefixes []string
annotations map[string]string
expectedDevices []string
}{
{
description: "no annotations",
},
{
description: "no matching annotations",
prefixes: []string{"not-prefix/"},
annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
},
},
{
description: "single matching annotation",
prefixes: []string{"prefix/"},
annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
},
expectedDevices: []string{"example.com/device=bar"},
},
{
description: "multiple matching annotations",
prefixes: []string{"prefix/", "another-prefix/"},
annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
"another-prefix/bar": "example.com/device=baz",
},
expectedDevices: []string{"example.com/device=bar", "example.com/device=baz"},
},
{
description: "multiple matching annotations with duplicate devices",
prefixes: []string{"prefix/", "another-prefix/"},
annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
"another-prefix/bar": "example.com/device=bar",
},
expectedDevices: []string{"example.com/device=bar", "example.com/device=bar"},
},
{
description: "invalid devices are returned as is",
prefixes: []string{"prefix/"},
annotations: map[string]string{
"prefix/foo": "example.com/device",
},
expectedDevices: []string{"example.com/device"},
},
}
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
image, err := New(
WithAnnotationsPrefixes(tc.prefixes),
WithAnnotations(tc.annotations),
)
require.NoError(t, err)
devices := image.cdiDeviceRequestsFromAnnotations()
require.ElementsMatch(t, tc.expectedDevices, devices)
})
}
}
func makeTestMounts(paths ...string) []specs.Mount {
var mounts []specs.Mount
for _, path := range paths {

View File

@@ -24,20 +24,39 @@ const (
capSysAdmin = "CAP_SYS_ADMIN"
)
type CapabilitiesGetter interface {
GetCapabilities() []string
}
type OCISpec specs.Spec
type OCISpecCapabilities specs.LinuxCapabilities
// IsPrivileged returns true if the container is a privileged container.
func IsPrivileged(s *specs.Spec) bool {
if s.Process.Capabilities == nil {
func IsPrivileged(s CapabilitiesGetter) bool {
if s == nil {
return false
}
// We only make sure that the bounding capabibility set has
// CAP_SYS_ADMIN. This allows us to make sure that the container was
// actually started as '--privileged', but also allow non-root users to
// access the privileged NVIDIA capabilities.
for _, c := range s.Process.Capabilities.Bounding {
for _, c := range s.GetCapabilities() {
if c == capSysAdmin {
return true
}
}
return false
}
func (s OCISpec) GetCapabilities() []string {
if s.Process == nil || s.Process.Capabilities == nil {
return nil
}
return (*OCISpecCapabilities)(s.Process.Capabilities).GetCapabilities()
}
func (c OCISpecCapabilities) GetCapabilities() []string {
// We only make sure that the bounding capability set has
// CAP_SYS_ADMIN. This allows us to make sure that the container was
// actually started as '--privileged', but also allow non-root users to
// access the privileged NVIDIA capabilities.
return c.Bounding
}

View File

@@ -0,0 +1,57 @@
/**
# Copyright (c) NVIDIA CORPORATION. All rights reserved.
#
# 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
import (
"testing"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/require"
)
func TestIsPrivileged(t *testing.T) {
var tests = []struct {
spec specs.Spec
expected bool
}{
{
specs.Spec{
Process: &specs.Process{
Capabilities: &specs.LinuxCapabilities{
Bounding: []string{"CAP_SYS_ADMIN"},
},
},
},
true,
},
{
specs.Spec{
Process: &specs.Process{
Capabilities: &specs.LinuxCapabilities{
Bounding: []string{"CAP_SYS_FOO"},
},
},
},
false,
},
}
for i, tc := range tests {
privileged := IsPrivileged((*OCISpec)(&tc.spec))
require.Equal(t, tc.expected, privileged, "%d: %v", i, tc)
}
}

View File

@@ -62,7 +62,7 @@ load-kmods = true
#debug = "/var/log/nvidia-container-runtime.log"
log-level = "info"
mode = "auto"
runtimes = ["docker-runc", "runc", "crun"]
runtimes = ["runc", "crun"]
[nvidia-container-runtime.modes]

View File

@@ -29,10 +29,11 @@ type gdsDeviceDiscoverer struct {
}
// NewGDSDiscoverer creates a discoverer for GPUDirect Storage devices and mounts.
func NewGDSDiscoverer(logger logger.Interface, driverRoot string, devRoot string) (Discover, error) {
func NewGDSDiscoverer(logger logger.Interface, driverRoot string) (Discover, error) {
devices := NewCharDeviceDiscoverer(
logger,
devRoot,
// The /dev/nvidia-fs* devices are always created at /
"/",
[]string{"/dev/nvidia-fs*"},
)

View File

@@ -20,6 +20,7 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
@@ -81,14 +82,25 @@ func NewGraphicsMountsDiscoverer(logger logger.Interface, driver *root.Driver, h
// vulkan ICD files are at {{ .driverRoot }}/vulkan instead of in /etc/vulkan.
func newVulkanConfigsDiscover(logger logger.Interface, driver *root.Driver) Discover {
locator := lookup.First(driver.Configs(), driver.Files())
required := []string{
"vulkan/icd.d/nvidia_icd.json",
"vulkan/icd.d/nvidia_layers.json",
"vulkan/implicit_layer.d/nvidia_layers.json",
}
// For some RPM-based driver packages, the vulkan ICD files are installed to
// /usr/share/vulkan/icd.d/nvidia_icd.%{_target_cpu}.json
// We also include this in the list of candidates for the ICD file.
switch runtime.GOARCH {
case "amd64":
required = append(required, "vulkan/icd.d/nvidia_icd.x86_64.json")
case "arm64":
required = append(required, "vulkan/icd.d/nvidia_icd.aarch64.json")
}
return &mountsToContainerPath{
logger: logger,
locator: locator,
required: []string{
"vulkan/icd.d/nvidia_icd.json",
"vulkan/icd.d/nvidia_layers.json",
"vulkan/implicit_layer.d/nvidia_layers.json",
},
logger: logger,
locator: locator,
required: required,
containerRoot: "/etc",
}
}

View File

@@ -25,7 +25,7 @@ import (
func TestGraphicsLibrariesDiscoverer(t *testing.T) {
logger, _ := testlog.NewNullLogger()
hookCreator := NewHookCreator("/usr/bin/nvidia-cdi-hook", false)
hookCreator := NewHookCreator()
testCases := []struct {
description string

View File

@@ -23,6 +23,33 @@ import (
"tags.cncf.io/container-device-interface/pkg/cdi"
)
// A HookName represents a supported CDI hooks.
type HookName string
const (
// AllHooks is a special hook name that allows all hooks to be matched.
AllHooks = HookName("all")
// A ChmodHook is used to set the file mode of the specified paths.
// Deprecated: The chmod hook is deprecated and will be removed in a future release.
ChmodHook = HookName("chmod")
// A CreateSymlinksHook is used to create symlinks in the container.
CreateSymlinksHook = HookName("create-symlinks")
// DisableDeviceNodeModificationHook refers to the hook used to ensure that
// device nodes are not created by libnvidia-ml.so or nvidia-smi in a
// container.
// Added in v1.17.8
DisableDeviceNodeModificationHook = HookName("disable-device-node-modification")
// An EnableCudaCompatHook is used to enabled CUDA Forward Compatibility.
// Added in v1.17.5
EnableCudaCompatHook = HookName("enable-cuda-compat")
// An UpdateLDCacheHook is the hook used to update the ldcache in the
// container. This allows injected libraries to be discoverable.
UpdateLDCacheHook = HookName("update-ldcache")
defaultNvidiaCDIHookPath = "/usr/bin/nvidia-cdi-hook"
)
var _ Discover = (*Hook)(nil)
// Devices returns an empty list of devices for a Hook discoverer.
@@ -45,52 +72,130 @@ func (h *Hook) Hooks() ([]Hook, error) {
return []Hook{*h}, nil
}
// Option is a function that configures the nvcdilib
type Option func(*CDIHook)
type Option func(*cdiHookCreator)
type CDIHook struct {
type cdiHookCreator struct {
nvidiaCDIHookPath string
debugLogging bool
disabledHooks map[HookName]bool
fixedArgs []string
debugLogging bool
}
// An allDisabledHookCreator is a HookCreator that does not create any hooks.
type allDisabledHookCreator struct{}
// Create returns nil for all hooks for an allDisabledHookCreator.
func (a *allDisabledHookCreator) Create(name HookName, args ...string) *Hook {
return nil
}
// A HookCreator defines an interface for creating discover hooks.
type HookCreator interface {
Create(string, ...string) *Hook
Create(HookName, ...string) *Hook
}
func NewHookCreator(nvidiaCDIHookPath string, debugLogging bool) HookCreator {
CDIHook := &CDIHook{
nvidiaCDIHookPath: nvidiaCDIHookPath,
debugLogging: debugLogging,
// WithDisabledHooks sets the set of hooks that are disabled for the CDI hook creator.
// This can be specified multiple times.
func WithDisabledHooks(hooks ...HookName) Option {
return func(c *cdiHookCreator) {
for _, hook := range hooks {
c.disabledHooks[hook] = true
}
}
}
// WithNVIDIACDIHookPath sets the path to the nvidia-cdi-hook binary.
func WithNVIDIACDIHookPath(nvidiaCDIHookPath string) Option {
return func(c *cdiHookCreator) {
c.nvidiaCDIHookPath = nvidiaCDIHookPath
}
}
func NewHookCreator(opts ...Option) HookCreator {
cdiHookCreator := &cdiHookCreator{
nvidiaCDIHookPath: defaultNvidiaCDIHookPath,
disabledHooks: make(map[HookName]bool),
}
for _, opt := range opts {
opt(cdiHookCreator)
}
return CDIHook
if cdiHookCreator.disabledHooks[AllHooks] {
return &allDisabledHookCreator{}
}
cdiHookCreator.fixedArgs = getFixedArgsForCDIHookCLI(cdiHookCreator.nvidiaCDIHookPath)
return cdiHookCreator
}
func (c CDIHook) Create(name string, args ...string) *Hook {
if name == "create-symlinks" {
if len(args) == 0 {
return nil
}
links := []string{}
for _, arg := range args {
links = append(links, "--link", arg)
}
args = links
// Create creates a new hook with the given name and arguments.
// If a hook is disabled, a nil hook is returned.
func (c cdiHookCreator) Create(name HookName, args ...string) *Hook {
if c.isDisabled(name, args...) {
return nil
}
return &Hook{
Lifecycle: cdi.CreateContainerHook,
Path: c.nvidiaCDIHookPath,
Args: append(c.requiredArgs(name), args...),
Args: append(c.requiredArgs(name), c.transformArgs(name, args...)...),
Env: []string{fmt.Sprintf("NVIDIA_CTK_DEBUG=%v", c.debugLogging)},
}
}
func (c CDIHook) requiredArgs(name string) []string {
base := filepath.Base(c.nvidiaCDIHookPath)
if base == "nvidia-ctk" {
return []string{base, "hook", name}
// isDisabled checks if the specified hook name is disabled.
func (c cdiHookCreator) isDisabled(name HookName, args ...string) bool {
if c.disabledHooks[name] {
return true
}
return []string{base, name}
switch name {
case CreateSymlinksHook:
if len(args) == 0 {
return true
}
case ChmodHook:
if len(args) == 0 {
return true
}
}
return false
}
func (c cdiHookCreator) requiredArgs(name HookName) []string {
return append(c.fixedArgs, string(name))
}
func (c cdiHookCreator) transformArgs(name HookName, args ...string) []string {
switch name {
case CreateSymlinksHook:
var transformedArgs []string
for _, arg := range args {
transformedArgs = append(transformedArgs, "--link", arg)
}
return transformedArgs
case ChmodHook:
var transformedArgs = []string{"--mode", "755"}
for _, arg := range args {
transformedArgs = append(transformedArgs, "--path", arg)
}
return transformedArgs
default:
return args
}
}
// getFixedArgsForCDIHookCLI returns the fixed arguments for the hook CLI.
// If the nvidia-ctk binary is used, hooks are implemented under the hook
// subcommand.
// For the nvidia-cdi-hook binary, the hooks are implemented as subcommands of
// the top-level CLI.
func getFixedArgsForCDIHookCLI(nvidiaCDIHookPath string) []string {
base := filepath.Base(nvidiaCDIHookPath)
if base == "nvidia-ctk" {
return []string{base, "hook"}
}
return []string{base}
}

View File

@@ -72,7 +72,7 @@ func createLDCacheUpdateHook(hookCreator HookCreator, ldconfig string, libraries
args = append(args, "--folder", f)
}
return hookCreator.Create("update-ldcache", args...)
return hookCreator.Create(UpdateLDCacheHook, args...)
}
// getLibraryPaths extracts the library dirs from the specified mounts

View File

@@ -31,7 +31,7 @@ const (
func TestLDCacheUpdateHook(t *testing.T) {
logger, _ := testlog.NewNullLogger()
hookCreator := NewHookCreator(testNvidiaCDIHookPath, false)
hookCreator := NewHookCreator(WithNVIDIACDIHookPath(testNvidiaCDIHookPath))
testCases := []struct {
description string

View File

@@ -113,7 +113,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
expectedHooks: []Hook{
{
Lifecycle: "createContainer",
Path: "/path/to/nvidia-cdi-hook",
Path: "/usr/bin/nvidia-cdi-hook",
Args: []string{"nvidia-cdi-hook", "create-symlinks", "--link", "libcuda.so.1::/usr/lib/libcuda.so"},
Env: []string{"NVIDIA_CTK_DEBUG=false"},
},
@@ -146,7 +146,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
expectedHooks: []Hook{
{
Lifecycle: "createContainer",
Path: "/path/to/nvidia-cdi-hook",
Path: "/usr/bin/nvidia-cdi-hook",
Args: []string{"nvidia-cdi-hook", "create-symlinks", "--link", "libcuda.so.1::/usr/lib/libcuda.so"},
Env: []string{"NVIDIA_CTK_DEBUG=false"},
},
@@ -178,7 +178,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
expectedHooks: []Hook{
{
Lifecycle: "createContainer",
Path: "/path/to/nvidia-cdi-hook",
Path: "/usr/bin/nvidia-cdi-hook",
Args: []string{"nvidia-cdi-hook", "create-symlinks", "--link", "libcuda.so.1::/usr/lib/libcuda.so"},
Env: []string{"NVIDIA_CTK_DEBUG=false"},
},
@@ -248,7 +248,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
},
{
Lifecycle: "createContainer",
Path: "/path/to/nvidia-cdi-hook",
Path: "/usr/bin/nvidia-cdi-hook",
Args: []string{"nvidia-cdi-hook", "create-symlinks", "--link", "libcuda.so.1::/usr/lib/libcuda.so"},
Env: []string{"NVIDIA_CTK_DEBUG=false"},
},
@@ -298,7 +298,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
expectedHooks: []Hook{
{
Lifecycle: "createContainer",
Path: "/path/to/nvidia-cdi-hook",
Path: "/usr/bin/nvidia-cdi-hook",
Args: []string{
"nvidia-cdi-hook", "create-symlinks",
"--link", "libcuda.so.1::/usr/lib/libcuda.so",
@@ -311,7 +311,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
},
}
hookCreator := NewHookCreator("/path/to/nvidia-cdi-hook", false)
hookCreator := NewHookCreator()
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
d := WithDriverDotSoSymlinks(

View File

@@ -184,7 +184,7 @@ func TestResolveAutoMode(t *testing.T) {
expectedMode: "legacy",
},
{
description: "cdi mount and non-CDI envvar resolves to legacy",
description: "cdi mount and non-CDI envvar resolves to cdi",
mode: "auto",
envmap: map[string]string{
"NVIDIA_VISIBLE_DEVICES": "0",
@@ -197,6 +197,22 @@ func TestResolveAutoMode(t *testing.T) {
"tegra": false,
"nvgpu": false,
},
expectedMode: "cdi",
},
{
description: "non-cdi mount and CDI envvar resolves to legacy",
mode: "auto",
envmap: map[string]string{
"NVIDIA_VISIBLE_DEVICES": "nvidia.com/gpu=0",
},
mounts: []string{
"/var/run/nvidia-container-devices/0",
},
info: map[string]bool{
"nvml": true,
"tegra": false,
"nvgpu": false,
},
expectedMode: "legacy",
},
}
@@ -232,6 +248,8 @@ func TestResolveAutoMode(t *testing.T) {
image, _ := image.New(
image.WithEnvMap(tc.envmap),
image.WithMounts(mounts),
image.WithAcceptDeviceListAsVolumeMounts(true),
image.WithAcceptEnvvarUnprivileged(true),
)
mode := resolveMode(logger, tc.mode, image, properties)
require.EqualValues(t, tc.expectedMode, mode)

View File

@@ -18,7 +18,6 @@ package modifier
import (
"fmt"
"strings"
"tags.cncf.io/container-device-interface/pkg/parser"
@@ -34,11 +33,13 @@ import (
// NewCDIModifier creates an OCI spec modifier that determines the modifications to make based on the
// CDI specifications available on the system. The NVIDIA_VISIBLE_DEVICES environment variable is
// used to select the devices to include.
func NewCDIModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Spec) (oci.SpecModifier, error) {
devices, err := getDevicesFromSpec(logger, ociSpec, cfg)
if err != nil {
return nil, fmt.Errorf("failed to get required devices from OCI specification: %v", err)
}
func NewCDIModifier(logger logger.Interface, cfg *config.Config, image image.CUDA) (oci.SpecModifier, error) {
deviceRequestor := newCDIDeviceRequestor(
logger,
image,
cfg.NVIDIAContainerRuntimeConfig.Modes.CDI.DefaultKind,
)
devices := deviceRequestor.DeviceRequests()
if len(devices) == 0 {
logger.Debugf("No devices requested; no modification required.")
return nil, nil
@@ -65,87 +66,38 @@ func NewCDIModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Spe
)
}
func getDevicesFromSpec(logger logger.Interface, ociSpec oci.Spec, cfg *config.Config) ([]string, error) {
rawSpec, err := ociSpec.Load()
if err != nil {
return nil, fmt.Errorf("failed to load OCI spec: %v", err)
}
type deviceRequestor interface {
DeviceRequests() []string
}
annotationDevices, err := getAnnotationDevices(cfg.NVIDIAContainerRuntimeConfig.Modes.CDI.AnnotationPrefixes, rawSpec.Annotations)
if err != nil {
return nil, fmt.Errorf("failed to parse container annotations: %v", err)
}
if len(annotationDevices) > 0 {
return annotationDevices, nil
}
type cdiDeviceRequestor struct {
image image.CUDA
logger logger.Interface
defaultKind string
}
container, err := image.NewCUDAImageFromSpec(rawSpec)
if err != nil {
return nil, err
}
if cfg.AcceptDeviceListAsVolumeMounts {
mountDevices := container.CDIDevicesFromMounts()
if len(mountDevices) > 0 {
return mountDevices, nil
}
func newCDIDeviceRequestor(logger logger.Interface, image image.CUDA, defaultKind string) deviceRequestor {
c := &cdiDeviceRequestor{
logger: logger,
image: image,
defaultKind: defaultKind,
}
return withUniqueDevices(c)
}
func (c *cdiDeviceRequestor) DeviceRequests() []string {
if c == nil {
return nil
}
var devices []string
seen := make(map[string]bool)
for _, name := range container.VisibleDevicesFromEnvVar() {
for _, name := range c.image.VisibleDevices() {
if !parser.IsQualifiedName(name) {
name = fmt.Sprintf("%s=%s", cfg.NVIDIAContainerRuntimeConfig.Modes.CDI.DefaultKind, name)
}
if seen[name] {
logger.Debugf("Ignoring duplicate device %q", name)
continue
name = fmt.Sprintf("%s=%s", c.defaultKind, name)
}
devices = append(devices, name)
}
if len(devices) == 0 {
return nil, nil
}
if cfg.AcceptEnvvarUnprivileged || image.IsPrivileged(rawSpec) {
return devices, nil
}
logger.Warningf("Ignoring devices specified in NVIDIA_VISIBLE_DEVICES: %v", devices)
return nil, nil
}
// getAnnotationDevices returns a list of devices specified in the annotations.
// Keys starting with the specified prefixes are considered and expected to contain a comma-separated list of
// fully-qualified CDI devices names. If any device name is not fully-quality an error is returned.
// The list of returned devices is deduplicated.
func getAnnotationDevices(prefixes []string, annotations map[string]string) ([]string, error) {
devicesByKey := make(map[string][]string)
for key, value := range annotations {
for _, prefix := range prefixes {
if strings.HasPrefix(key, prefix) {
devicesByKey[key] = strings.Split(value, ",")
}
}
}
seen := make(map[string]bool)
var annotationDevices []string
for key, devices := range devicesByKey {
for _, device := range devices {
if !parser.IsQualifiedName(device) {
return nil, fmt.Errorf("invalid device name %q in annotation %q", device, key)
}
if seen[device] {
continue
}
annotationDevices = append(annotationDevices, device)
seen[device] = true
}
}
return annotationDevices, nil
return devices
}
// filterAutomaticDevices searches for "automatic" device names in the input slice.
@@ -169,7 +121,7 @@ func newAutomaticCDISpecModifier(logger logger.Interface, cfg *config.Config, de
if err != nil {
return nil, fmt.Errorf("failed to generate CDI spec: %w", err)
}
cdiModifier, err := cdi.New(
cdiDeviceRequestor, err := cdi.New(
cdi.WithLogger(logger),
cdi.WithSpec(spec.Raw()),
)
@@ -177,7 +129,7 @@ func newAutomaticCDISpecModifier(logger logger.Interface, cfg *config.Config, de
return nil, fmt.Errorf("failed to construct CDI modifier: %w", err)
}
return cdiModifier, nil
return cdiDeviceRequestor, nil
}
func generateAutomaticCDISpec(logger logger.Interface, cfg *config.Config, devices []string) (spec.Interface, error) {
@@ -192,26 +144,35 @@ func generateAutomaticCDISpec(logger logger.Interface, cfg *config.Config, devic
return nil, fmt.Errorf("failed to construct CDI library: %w", err)
}
identifiers := []string{}
var identifiers []string
for _, device := range devices {
_, _, id := parser.ParseDevice(device)
identifiers = append(identifiers, id)
}
deviceSpecs, err := cdilib.GetDeviceSpecsByID(identifiers...)
if err != nil {
return nil, fmt.Errorf("failed to get CDI device specs: %w", err)
}
commonEdits, err := cdilib.GetCommonEdits()
if err != nil {
return nil, fmt.Errorf("failed to get common CDI spec edits: %w", err)
}
return spec.New(
spec.WithDeviceSpecs(deviceSpecs),
spec.WithEdits(*commonEdits.ContainerEdits),
spec.WithVendor("runtime.nvidia.com"),
spec.WithClass("gpu"),
)
return cdilib.GetSpec(identifiers...)
}
type deduplicatedDeviceRequestor struct {
deviceRequestor
}
func withUniqueDevices(deviceRequestor deviceRequestor) deviceRequestor {
return &deduplicatedDeviceRequestor{deviceRequestor: deviceRequestor}
}
func (d *deduplicatedDeviceRequestor) DeviceRequests() []string {
if d == nil {
return nil
}
seen := make(map[string]bool)
var devices []string
for _, device := range d.deviceRequestor.DeviceRequests() {
if seen[device] {
continue
}
seen[device] = true
devices = append(devices, device)
}
return devices
}

View File

@@ -17,76 +17,144 @@
package modifier
import (
"fmt"
"testing"
"github.com/opencontainers/runtime-spec/specs-go"
testlog "github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/require"
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
)
func TestGetAnnotationDevices(t *testing.T) {
func TestDeviceRequests(t *testing.T) {
logger, _ := testlog.NewNullLogger()
testCases := []struct {
description string
input cdiDeviceRequestor
spec *specs.Spec
prefixes []string
annotations map[string]string
expectedDevices []string
expectedError error
}{
{
description: "no annotations",
description: "empty spec yields no devices",
},
{
description: "cdi devices from mounts",
input: cdiDeviceRequestor{
defaultKind: "nvidia.com/gpu",
},
spec: &specs.Spec{
Mounts: []specs.Mount{
{
Destination: "/var/run/nvidia-container-devices/cdi/nvidia.com/gpu/0",
Source: "/dev/null",
},
{
Destination: "/var/run/nvidia-container-devices/cdi/nvidia.com/gpu/1",
Source: "/dev/null",
},
},
},
expectedDevices: []string{"nvidia.com/gpu=0", "nvidia.com/gpu=1"},
},
{
description: "cdi devices from envvar",
input: cdiDeviceRequestor{
defaultKind: "nvidia.com/gpu",
},
spec: &specs.Spec{
Process: &specs.Process{
Env: []string{"NVIDIA_VISIBLE_DEVICES=0,example.com/class=device"},
},
},
expectedDevices: []string{"nvidia.com/gpu=0", "example.com/class=device"},
},
{
description: "no matching annotations",
prefixes: []string{"not-prefix/"},
annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
spec: &specs.Spec{
Annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
},
},
},
{
description: "single matching annotation",
prefixes: []string{"prefix/"},
annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
spec: &specs.Spec{
Annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
},
},
expectedDevices: []string{"example.com/device=bar"},
},
{
description: "multiple matching annotations",
prefixes: []string{"prefix/", "another-prefix/"},
annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
"another-prefix/bar": "example.com/device=baz",
spec: &specs.Spec{
Annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
"another-prefix/bar": "example.com/device=baz",
},
},
expectedDevices: []string{"example.com/device=bar", "example.com/device=baz"},
},
{
description: "multiple matching annotations with duplicate devices",
prefixes: []string{"prefix/", "another-prefix/"},
annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
"another-prefix/bar": "example.com/device=bar",
spec: &specs.Spec{
Annotations: map[string]string{
"prefix/foo": "example.com/device=bar",
"another-prefix/bar": "example.com/device=bar",
},
},
expectedDevices: []string{"example.com/device=bar"},
expectedDevices: []string{"example.com/device=bar", "example.com/device=bar"},
},
{
description: "invalid devices",
prefixes: []string{"prefix/"},
annotations: map[string]string{
"prefix/foo": "example.com/device",
description: "devices in annotations are expanded",
input: cdiDeviceRequestor{
defaultKind: "nvidia.com/gpu",
},
expectedError: fmt.Errorf("invalid device %q", "example.com/device"),
prefixes: []string{"prefix/"},
spec: &specs.Spec{
Annotations: map[string]string{
"prefix/foo": "device",
},
},
expectedDevices: []string{"nvidia.com/gpu=device"},
},
{
description: "invalid devices in annotations are treated as strings",
input: cdiDeviceRequestor{
defaultKind: "nvidia.com/gpu",
},
prefixes: []string{"prefix/"},
spec: &specs.Spec{
Annotations: map[string]string{
"prefix/foo": "example.com/device",
},
},
expectedDevices: []string{"nvidia.com/gpu=example.com/device"},
},
}
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
devices, err := getAnnotationDevices(tc.prefixes, tc.annotations)
if tc.expectedError != nil {
require.Error(t, err)
return
}
tc.input.logger = logger
image, err := image.NewCUDAImageFromSpec(
tc.spec,
image.WithAcceptDeviceListAsVolumeMounts(true),
image.WithAcceptEnvvarUnprivileged(true),
image.WithAnnotationsPrefixes(tc.prefixes),
)
require.NoError(t, err)
tc.input.image = image
t.Run(tc.description, func(t *testing.T) {
devices := tc.input.DeviceRequests()
require.NoError(t, err)
require.ElementsMatch(t, tc.expectedDevices, devices)
require.EqualValues(t, tc.expectedDevices, devices)
})
}
}

View File

@@ -48,7 +48,7 @@ func NewFeatureGatedModifier(logger logger.Interface, cfg *config.Config, image
devRoot := cfg.NVIDIAContainerCLIConfig.Root
if image.Getenv("NVIDIA_GDS") == "enabled" {
d, err := discover.NewGDSDiscoverer(logger, driverRoot, devRoot)
d, err := discover.NewGDSDiscoverer(logger, driverRoot)
if err != nil {
return nil, fmt.Errorf("failed to construct discoverer for GDS devices: %w", err)
}

View File

@@ -183,7 +183,7 @@ func TestDiscovererFromCSVFiles(t *testing.T) {
},
}
hookCreator := discover.NewHookCreator("/usr/bin/nvidia-cdi-hook", false)
hookCreator := discover.NewHookCreator()
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
defer setGetTargetsFromCSVFiles(tc.moutSpecs)()

View File

@@ -18,7 +18,6 @@ package runtime
import (
"fmt"
"os"
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
@@ -66,29 +65,17 @@ func newNVIDIAContainerRuntime(logger logger.Interface, cfg *config.Config, argv
// newSpecModifier is a factory method that creates constructs an OCI spec modifer based on the provided config.
func newSpecModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Spec, driver *root.Driver) (oci.SpecModifier, error) {
rawSpec, err := ociSpec.Load()
if err != nil {
return nil, fmt.Errorf("failed to load OCI spec: %v", err)
}
image, err := image.NewCUDAImageFromSpec(rawSpec)
mode, image, err := initRuntimeModeAndImage(logger, cfg, ociSpec)
if err != nil {
return nil, err
}
hookCreator := discover.NewHookCreator(
cfg.NVIDIACTKConfig.Path,
cfg.NVIDIAContainerRuntimeConfig.DebugFilePath == "" || cfg.NVIDIAContainerRuntimeConfig.DebugFilePath == os.DevNull,
)
mode := info.ResolveAutoMode(logger, cfg.NVIDIAContainerRuntimeConfig.Mode, image)
// We update the mode here so that we can continue passing just the config to other functions.
cfg.NVIDIAContainerRuntimeConfig.Mode = mode
modeModifier, err := newModeModifier(logger, mode, cfg, ociSpec, image)
modeModifier, err := newModeModifier(logger, mode, cfg, *image)
if err != nil {
return nil, err
}
hookCreator := discover.NewHookCreator(discover.WithNVIDIACDIHookPath(cfg.NVIDIACTKConfig.Path))
var modifiers modifier.List
for _, modifierType := range supportedModifierTypes(mode) {
switch modifierType {
@@ -97,13 +84,13 @@ func newSpecModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Sp
case "nvidia-hook-remover":
modifiers = append(modifiers, modifier.NewNvidiaContainerRuntimeHookRemover(logger))
case "graphics":
graphicsModifier, err := modifier.NewGraphicsModifier(logger, cfg, image, driver, hookCreator)
graphicsModifier, err := modifier.NewGraphicsModifier(logger, cfg, *image, driver, hookCreator)
if err != nil {
return nil, err
}
modifiers = append(modifiers, graphicsModifier)
case "feature-gated":
featureGatedModifier, err := modifier.NewFeatureGatedModifier(logger, cfg, image, driver, hookCreator)
featureGatedModifier, err := modifier.NewFeatureGatedModifier(logger, cfg, *image, driver, hookCreator)
if err != nil {
return nil, err
}
@@ -114,19 +101,58 @@ func newSpecModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Sp
return modifiers, nil
}
func newModeModifier(logger logger.Interface, mode string, cfg *config.Config, ociSpec oci.Spec, image image.CUDA) (oci.SpecModifier, error) {
func newModeModifier(logger logger.Interface, mode string, cfg *config.Config, image image.CUDA) (oci.SpecModifier, error) {
switch mode {
case "legacy":
return modifier.NewStableRuntimeModifier(logger, cfg.NVIDIAContainerRuntimeHookConfig.Path), nil
case "csv":
return modifier.NewCSVModifier(logger, cfg, image)
case "cdi":
return modifier.NewCDIModifier(logger, cfg, ociSpec)
return modifier.NewCDIModifier(logger, cfg, image)
}
return nil, fmt.Errorf("invalid runtime mode: %v", cfg.NVIDIAContainerRuntimeConfig.Mode)
}
// initRuntimeModeAndImage constructs an image from the specified OCI runtime
// specification and runtime config.
// The image is also used to determine the runtime mode to apply.
// If a non-CDI mode is detected we ensure that the image does not process
// annotation devices.
func initRuntimeModeAndImage(logger logger.Interface, cfg *config.Config, ociSpec oci.Spec) (string, *image.CUDA, error) {
rawSpec, err := ociSpec.Load()
if err != nil {
return "", nil, fmt.Errorf("failed to load OCI spec: %v", err)
}
image, err := image.NewCUDAImageFromSpec(
rawSpec,
image.WithLogger(logger),
image.WithAcceptDeviceListAsVolumeMounts(cfg.AcceptDeviceListAsVolumeMounts),
image.WithAcceptEnvvarUnprivileged(cfg.AcceptEnvvarUnprivileged),
image.WithAnnotationsPrefixes(cfg.NVIDIAContainerRuntimeConfig.Modes.CDI.AnnotationPrefixes),
)
if err != nil {
return "", nil, err
}
mode := info.ResolveAutoMode(logger, cfg.NVIDIAContainerRuntimeConfig.Mode, image)
// We update the mode here so that we can continue passing just the config to other functions.
cfg.NVIDIAContainerRuntimeConfig.Mode = mode
if mode == "cdi" || len(cfg.NVIDIAContainerRuntimeConfig.Modes.CDI.AnnotationPrefixes) == 0 {
return mode, &image, nil
}
// For non-cdi modes we explicitly set the annotation prefixes to nil and
// call this function again to force a reconstruction of the image.
// Note that since the mode is now explicitly set, we will effectively skip
// the mode resolution.
cfg.NVIDIAContainerRuntimeConfig.Modes.CDI.AnnotationPrefixes = nil
return initRuntimeModeAndImage(logger, cfg, ociSpec)
}
// supportedModifierTypes returns the modifiers supported for a specific runtime mode.
func supportedModifierTypes(mode string) []string {
switch mode {

View File

@@ -1,3 +1,5 @@
nvidia-container-runtime /usr/bin
nvidia-ctk /usr/bin
nvidia-cdi-hook /usr/bin
nvidia-cdi-refresh.service /etc/systemd/system/
nvidia-cdi-refresh.path /etc/systemd/system/

View File

@@ -5,6 +5,16 @@ set -e
case "$1" in
configure)
/usr/bin/nvidia-ctk --quiet config --config-file=/etc/nvidia-container-runtime/config.toml --in-place
if command -v systemctl >/dev/null 2>&1 \
&& systemctl --quiet is-system-running 2>/dev/null; then
systemctl daemon-reload || true
if [ -z "$2" ]; then # $2 empty → first install
systemctl enable --now nvidia-cdi-refresh.path || true
fi
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)

View File

@@ -5,3 +5,14 @@
%:
dh $@
override_dh_fixperms:
dh_fixperms
chmod 755 debian/$(shell dh_listpackages)/usr/bin/nvidia-container-runtime-hook || true
chmod 755 debian/$(shell dh_listpackages)/usr/bin/nvidia-container-runtime || true
chmod 755 debian/$(shell dh_listpackages)/usr/bin/nvidia-container-runtime.cdi || true
chmod 755 debian/$(shell dh_listpackages)/usr/bin/nvidia-container-runtime.legacy || true
chmod 755 debian/$(shell dh_listpackages)/usr/bin/nvidia-ctk || true
chmod 755 debian/$(shell dh_listpackages)/usr/bin/nvidia-cdi-hook || true
chmod 644 debian/$(shell dh_listpackages)/etc/systemd/system/nvidia-cdi-refresh.service || true
chmod 644 debian/$(shell dh_listpackages)/etc/systemd/system/nvidia-cdi-refresh.path || true

View File

@@ -17,6 +17,8 @@ Source3: nvidia-container-runtime
Source4: nvidia-container-runtime.cdi
Source5: nvidia-container-runtime.legacy
Source6: nvidia-cdi-hook
Source7: nvidia-cdi-refresh.service
Source8: nvidia-cdi-refresh.path
Obsoletes: nvidia-container-runtime <= 3.5.0-1, nvidia-container-runtime-hook <= 1.4.0-2
Provides: nvidia-container-runtime
@@ -28,16 +30,20 @@ Requires: nvidia-container-toolkit-base == %{version}-%{release}
Provides tools and utilities to enable GPU support in containers.
%prep
cp %{SOURCE0} %{SOURCE1} %{SOURCE2} %{SOURCE3} %{SOURCE4} %{SOURCE5} %{SOURCE6} .
cp %{SOURCE0} %{SOURCE1} %{SOURCE2} %{SOURCE3} %{SOURCE4} %{SOURCE5} %{SOURCE6} %{SOURCE7} %{SOURCE8} .
%install
mkdir -p %{buildroot}%{_bindir}
mkdir -p %{buildroot}%{_sysconfdir}/systemd/system/
install -m 755 -t %{buildroot}%{_bindir} nvidia-container-runtime-hook
install -m 755 -t %{buildroot}%{_bindir} nvidia-container-runtime
install -m 755 -t %{buildroot}%{_bindir} nvidia-container-runtime.cdi
install -m 755 -t %{buildroot}%{_bindir} nvidia-container-runtime.legacy
install -m 755 -t %{buildroot}%{_bindir} nvidia-ctk
install -m 755 -t %{buildroot}%{_bindir} nvidia-cdi-hook
install -m 644 -t %{buildroot}%{_sysconfdir}/systemd/system nvidia-cdi-refresh.service
install -m 644 -t %{buildroot}%{_sysconfdir}/systemd/system nvidia-cdi-refresh.path
%post
if [ $1 -gt 1 ]; then # only on package upgrade
@@ -45,6 +51,17 @@ if [ $1 -gt 1 ]; then # only on package upgrade
cp -af %{_bindir}/nvidia-container-runtime-hook %{_localstatedir}/lib/rpm-state/nvidia-container-toolkit
fi
# Reload systemd unit cache
if command -v systemctl >/dev/null 2>&1 \
&& systemctl --quiet is-system-running 2>/dev/null; then
systemctl daemon-reload || true
# On fresh install ($1 == 1) enable the path unit so it starts at boot
if [ "$1" -eq 1 ]; then
systemctl enable --now nvidia-cdi-refresh.path || true
fi
fi
%posttrans
if [ ! -e %{_bindir}/nvidia-container-runtime-hook ]; then
# repairing lost file nvidia-container-runtime-hook
@@ -89,6 +106,8 @@ Provides tools such as the NVIDIA Container Runtime and NVIDIA Container Toolkit
%{_bindir}/nvidia-container-runtime
%{_bindir}/nvidia-ctk
%{_bindir}/nvidia-cdi-hook
%{_sysconfdir}/systemd/system/nvidia-cdi-refresh.service
%{_sysconfdir}/systemd/system/nvidia-cdi-refresh.path
# The OPERATOR EXTENSIONS package consists of components that are required to enable GPU support in Kubernetes.
# This package is not distributed as part of the NVIDIA Container Toolkit RPMs.

View File

@@ -21,12 +21,13 @@ import (
"tags.cncf.io/container-device-interface/pkg/cdi"
"tags.cncf.io/container-device-interface/specs-go"
"github.com/NVIDIA/nvidia-container-toolkit/internal/discover"
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec"
)
// Interface defines the API for the nvcdi package
type Interface interface {
GetSpec() (spec.Interface, error)
GetSpec(...string) (spec.Interface, error)
GetCommonEdits() (*cdi.ContainerEdits, error)
GetAllDeviceSpecs() ([]specs.Device, error)
GetGPUDeviceEdits(device.Device) (*cdi.ContainerEdits, error)
@@ -36,14 +37,32 @@ type Interface interface {
GetDeviceSpecsByID(...string) ([]specs.Device, error)
}
// A HookName refers to one of the predefined set of CDI hooks that may be
// included in the generated CDI specification.
type HookName string
// A HookName represents one of the predefined NVIDIA CDI hooks.
type HookName = discover.HookName
const (
// HookEnableCudaCompat refers to the hook used to enable CUDA Forward Compatibility.
// This was added with v1.17.5 of the NVIDIA Container Toolkit.
HookEnableCudaCompat = HookName("enable-cuda-compat")
// AllHooks is a special hook name that allows all hooks to be matched.
AllHooks = discover.AllHooks
// A CreateSymlinksHook is used to create symlinks in the container.
CreateSymlinksHook = discover.CreateSymlinksHook
// DisableDeviceNodeModificationHook refers to the hook used to ensure that
// device nodes are not created by libnvidia-ml.so or nvidia-smi in a
// container.
// Added in v1.17.8
DisableDeviceNodeModificationHook = discover.DisableDeviceNodeModificationHook
// An EnableCudaCompatHook is used to enabled CUDA Forward Compatibility.
// Added in v1.17.5
EnableCudaCompatHook = discover.EnableCudaCompatHook
// An UpdateLDCacheHook is used to update the ldcache in the container.
UpdateLDCacheHook = discover.UpdateLDCacheHook
// Deprecated: Use CreateSymlinksHook instead.
HookCreateSymlinks = CreateSymlinksHook
// Deprecated: Use EnableCudaCompatHook instead.
HookEnableCudaCompat = EnableCudaCompatHook
// Deprecated: Use UpdateLDCacheHook instead.
HookUpdateLDCache = UpdateLDCacheHook
)
// A FeatureFlag refers to a specific feature that can be toggled in the CDI api.

View File

@@ -106,15 +106,16 @@ func (l *nvcdilib) NewDriverLibraryDiscoverer(version string) (discover.Discover
)
discoverers = append(discoverers, driverDotSoSymlinksDiscoverer)
if l.HookIsSupported(HookEnableCudaCompat) {
// TODO: The following should use the version directly.
cudaCompatLibHookDiscoverer := discover.NewCUDACompatHookDiscoverer(l.logger, l.hookCreator, l.driver)
discoverers = append(discoverers, cudaCompatLibHookDiscoverer)
}
// TODO: The following should use the version directly.
cudaCompatLibHookDiscoverer := discover.NewCUDACompatHookDiscoverer(l.logger, l.hookCreator, l.driver)
discoverers = append(discoverers, cudaCompatLibHookDiscoverer)
updateLDCache, _ := discover.NewLDCacheUpdateHook(l.logger, libraries, l.hookCreator, l.ldconfigPath)
discoverers = append(discoverers, updateLDCache)
disableDeviceNodeModification := l.hookCreator.Create(DisableDeviceNodeModificationHook)
discoverers = append(discoverers, disableDeviceNodeModification)
d := discover.Merge(discoverers...)
return d, nil

View File

@@ -40,13 +40,12 @@ var requiredDriverStoreFiles = []string{
// newWSLDriverDiscoverer returns a Discoverer for WSL2 drivers.
func newWSLDriverDiscoverer(logger logger.Interface, driverRoot string, hookCreator discover.HookCreator, ldconfigPath string) (discover.Discover, error) {
err := dxcore.Init()
if err != nil {
return nil, fmt.Errorf("failed to initialize dxcore: %v", err)
if err := dxcore.Init(); err != nil {
return nil, fmt.Errorf("failed to initialize dxcore: %w", err)
}
defer func() {
if err := dxcore.Shutdown(); err != nil {
logger.Warningf("failed to shutdown dxcore: %v", err)
logger.Warningf("failed to shutdown dxcore: %w", err)
}
}()
@@ -54,32 +53,19 @@ func newWSLDriverDiscoverer(logger logger.Interface, driverRoot string, hookCrea
if len(driverStorePaths) == 0 {
return nil, fmt.Errorf("no driver store paths found")
}
if len(driverStorePaths) > 1 {
logger.Warningf("Found multiple driver store paths: %v", driverStorePaths)
}
logger.Infof("Using WSL driver store paths: %v", driverStorePaths)
return newWSLDriverStoreDiscoverer(logger, driverRoot, hookCreator, ldconfigPath, driverStorePaths)
}
driverStorePaths = append(driverStorePaths, "/usr/lib/wsl/lib")
// newWSLDriverStoreDiscoverer returns a Discoverer for WSL2 drivers in the driver store associated with a dxcore adapter.
func newWSLDriverStoreDiscoverer(logger logger.Interface, driverRoot string, hookCreator discover.HookCreator, ldconfigPath string, driverStorePaths []string) (discover.Discover, error) {
var searchPaths []string
seen := make(map[string]bool)
for _, path := range driverStorePaths {
if seen[path] {
continue
}
searchPaths = append(searchPaths, path)
}
if len(searchPaths) > 1 {
logger.Warningf("Found multiple driver store paths: %v", searchPaths)
}
searchPaths = append(searchPaths, "/usr/lib/wsl/lib")
libraries := discover.NewMounts(
driverStoreMounts := discover.NewMounts(
logger,
lookup.NewFileLocator(
lookup.WithLogger(logger),
lookup.WithSearchPaths(
searchPaths...,
driverStorePaths...,
),
lookup.WithCount(1),
),
@@ -89,14 +75,14 @@ func newWSLDriverStoreDiscoverer(logger logger.Interface, driverRoot string, hoo
symlinkHook := nvidiaSMISimlinkHook{
logger: logger,
mountsFrom: libraries,
mountsFrom: driverStoreMounts,
hookCreator: hookCreator,
}
ldcacheHook, _ := discover.NewLDCacheUpdateHook(logger, libraries, hookCreator, ldconfigPath)
ldcacheHook, _ := discover.NewLDCacheUpdateHook(logger, driverStoreMounts, hookCreator, ldconfigPath)
d := discover.Merge(
libraries,
driverStoreMounts,
symlinkHook,
ldcacheHook,
)
@@ -135,7 +121,7 @@ func (m nvidiaSMISimlinkHook) Hooks() ([]discover.Hook, error) {
}
link := "/usr/bin/nvidia-smi"
links := []string{fmt.Sprintf("%s::%s", target, link)}
symlinkHook := m.hookCreator.Create("create-symlinks", links...)
symlinkHook := m.hookCreator.Create(CreateSymlinksHook, links...)
return symlinkHook.Hooks()
}

View File

@@ -29,7 +29,7 @@ import (
func TestNvidiaSMISymlinkHook(t *testing.T) {
logger, _ := testlog.NewNullLogger()
hookCreator := discover.NewHookCreator("nvidia-cdi-hook", false)
hookCreator := discover.NewHookCreator()
errMounts := errors.New("mounts error")
@@ -93,7 +93,7 @@ func TestNvidiaSMISymlinkHook(t *testing.T) {
expectedHooks: []discover.Hook{
{
Lifecycle: "createContainer",
Path: "nvidia-cdi-hook",
Path: "/usr/bin/nvidia-cdi-hook",
Args: []string{"nvidia-cdi-hook", "create-symlinks",
"--link", "nvidia-smi::/usr/bin/nvidia-smi"},
Env: []string{"NVIDIA_CTK_DEBUG=false"},
@@ -114,7 +114,7 @@ func TestNvidiaSMISymlinkHook(t *testing.T) {
expectedHooks: []discover.Hook{
{
Lifecycle: "createContainer",
Path: "nvidia-cdi-hook",
Path: "/usr/bin/nvidia-cdi-hook",
Args: []string{"nvidia-cdi-hook", "create-symlinks",
"--link", "/some/path/nvidia-smi::/usr/bin/nvidia-smi"},
Env: []string{"NVIDIA_CTK_DEBUG=false"},
@@ -135,7 +135,7 @@ func TestNvidiaSMISymlinkHook(t *testing.T) {
expectedHooks: []discover.Hook{
{
Lifecycle: "createContainer",
Path: "nvidia-cdi-hook",
Path: "/usr/bin/nvidia-cdi-hook",
Args: []string{"nvidia-cdi-hook", "create-symlinks",
"--link", "/some/path/nvidia-smi::/usr/bin/nvidia-smi"},
Env: []string{"NVIDIA_CTK_DEBUG=false"},

View File

@@ -34,7 +34,7 @@ var _ Interface = (*gdslib)(nil)
// GetAllDeviceSpecs returns the device specs for all available devices.
func (l *gdslib) GetAllDeviceSpecs() ([]specs.Device, error) {
discoverer, err := discover.NewGDSDiscoverer(l.logger, l.driverRoot, l.devRoot)
discoverer, err := discover.NewGDSDiscoverer(l.logger, l.driverRoot)
if err != nil {
return nil, fmt.Errorf("failed to create GPUDirect Storage discoverer: %v", err)
}
@@ -58,7 +58,7 @@ func (l *gdslib) GetCommonEdits() (*cdi.ContainerEdits, error) {
// GetSpec is unsppported for the gdslib specs.
// gdslib is typically wrapped by a spec that implements GetSpec.
func (l *gdslib) GetSpec() (spec.Interface, error) {
func (l *gdslib) GetSpec(...string) (spec.Interface, error) {
return nil, fmt.Errorf("GetSpec is not supported")
}

View File

@@ -34,7 +34,7 @@ type csvlib nvcdilib
var _ Interface = (*csvlib)(nil)
// GetSpec should not be called for wsllib
func (l *csvlib) GetSpec() (spec.Interface, error) {
func (l *csvlib) GetSpec(...string) (spec.Interface, error) {
return nil, fmt.Errorf("unexpected call to csvlib.GetSpec()")
}

View File

@@ -41,7 +41,7 @@ const (
)
// GetSpec should not be called for imexlib.
func (l *imexlib) GetSpec() (spec.Interface, error) {
func (l *imexlib) GetSpec(...string) (spec.Interface, error) {
return nil, fmt.Errorf("unexpected call to imexlib.GetSpec()")
}

View File

@@ -36,7 +36,7 @@ type nvmllib nvcdilib
var _ Interface = (*nvmllib)(nil)
// GetSpec should not be called for nvmllib
func (l *nvmllib) GetSpec() (spec.Interface, error) {
func (l *nvmllib) GetSpec(...string) (spec.Interface, error) {
return nil, fmt.Errorf("unexpected call to nvmllib.GetSpec()")
}

View File

@@ -32,7 +32,7 @@ type wsllib nvcdilib
var _ Interface = (*wsllib)(nil)
// GetSpec should not be called for wsllib
func (l *wsllib) GetSpec() (spec.Interface, error) {
func (l *wsllib) GetSpec(...string) (spec.Interface, error) {
return nil, fmt.Errorf("unexpected call to wsllib.GetSpec()")
}

View File

@@ -58,16 +58,13 @@ type nvcdilib struct {
featureFlags map[FeatureFlag]bool
disabledHooks disabledHooks
disabledHooks []discover.HookName
hookCreator discover.HookCreator
}
// New creates a new nvcdi library
func New(opts ...Option) (Interface, error) {
l := &nvcdilib{
disabledHooks: make(disabledHooks),
featureFlags: make(map[FeatureFlag]bool),
}
l := &nvcdilib{}
for _, opt := range opts {
opt(l)
}
@@ -84,9 +81,6 @@ func New(opts ...Option) (Interface, error) {
if l.nvidiaCDIHookPath == "" {
l.nvidiaCDIHookPath = "/usr/bin/nvidia-cdi-hook"
}
// create hookCreator
l.hookCreator = discover.NewHookCreator(l.nvidiaCDIHookPath, false)
if l.driverRoot == "" {
l.driverRoot = "/"
}
@@ -136,7 +130,7 @@ func New(opts ...Option) (Interface, error) {
l.vendor = "management.nvidia.com"
}
// Management containers in general do not require CUDA Forward compatibility.
l.disabledHooks[HookEnableCudaCompat] = true
l.disabledHooks = append(l.disabledHooks, HookEnableCudaCompat, DisableDeviceNodeModificationHook)
lib = (*managementlib)(l)
case ModeNvml:
lib = (*nvmllib)(l)
@@ -161,6 +155,12 @@ func New(opts ...Option) (Interface, error) {
return nil, fmt.Errorf("unknown mode %q", l.mode)
}
// create hookCreator
l.hookCreator = discover.NewHookCreator(
discover.WithNVIDIACDIHookPath(l.nvidiaCDIHookPath),
discover.WithDisabledHooks(l.disabledHooks...),
)
w := wrapper{
Interface: lib,
vendor: l.vendor,

View File

@@ -180,7 +180,7 @@ func (m managementDiscoverer) nodeIsBlocked(path string) bool {
// GetSpec is unsppported for the managementlib specs.
// managementlib is typically wrapped by a spec that implements GetSpec.
func (m *managementlib) GetSpec() (spec.Interface, error) {
func (m *managementlib) GetSpec(...string) (spec.Interface, error) {
return nil, fmt.Errorf("GetSpec is not supported")
}

View File

@@ -58,7 +58,7 @@ func (l *mofedlib) GetCommonEdits() (*cdi.ContainerEdits, error) {
// GetSpec is unsppported for the mofedlib specs.
// mofedlib is typically wrapped by a spec that implements GetSpec.
func (l *mofedlib) GetSpec() (spec.Interface, error) {
func (l *mofedlib) GetSpec(...string) (spec.Interface, error) {
return nil, fmt.Errorf("GetSpec is not supported")
}

View File

@@ -21,6 +21,7 @@ import (
"github.com/NVIDIA/go-nvlib/pkg/nvlib/info"
"github.com/NVIDIA/go-nvml/pkg/nvml"
"github.com/NVIDIA/nvidia-container-toolkit/internal/discover"
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/transform"
)
@@ -158,12 +159,9 @@ func WithLibrarySearchPaths(paths []string) Option {
// WithDisabledHook allows specific hooks to the disabled.
// This option can be specified multiple times for each hook.
func WithDisabledHook(hook HookName) Option {
func WithDisabledHook[T string | HookName](hook T) Option {
return func(o *nvcdilib) {
if o.disabledHooks == nil {
o.disabledHooks = make(map[HookName]bool)
}
o.disabledHooks[hook] = true
o.disabledHooks = append(o.disabledHooks, discover.HookName(hook))
}
}

View File

@@ -61,18 +61,9 @@ func (d *deviceFolderPermissions) Hooks() ([]discover.Hook, error) {
if err != nil {
return nil, fmt.Errorf("failed to get device subfolders: %v", err)
}
if len(folders) == 0 {
return nil, nil
}
args := []string{"--mode", "755"}
for _, folder := range folders {
args = append(args, "--path", folder)
}
hook := d.hookCreator.Create("chmod", args...)
return []discover.Hook{*hook}, nil
//nolint:staticcheck // The ChmodHook is deprecated and will be removed in a future release.
return d.hookCreator.Create(discover.ChmodHook, folders...).Hooks()
}
func (d *deviceFolderPermissions) getDeviceSubfolders() ([]string, error) {

View File

@@ -35,8 +35,11 @@ type wrapper struct {
}
// GetSpec combines the device specs and common edits from the wrapped Interface to a single spec.Interface.
func (l *wrapper) GetSpec() (spec.Interface, error) {
deviceSpecs, err := l.GetAllDeviceSpecs()
func (l *wrapper) GetSpec(devices ...string) (spec.Interface, error) {
if len(devices) == 0 {
devices = append(devices, "all")
}
deviceSpecs, err := l.GetDeviceSpecsByID(devices...)
if err != nil {
return nil, err
}
@@ -55,6 +58,16 @@ func (l *wrapper) GetSpec() (spec.Interface, error) {
)
}
func (l *wrapper) GetDeviceSpecsByID(devices ...string) ([]specs.Device, error) {
for _, device := range devices {
if device != "all" {
continue
}
return l.GetAllDeviceSpecs()
}
return l.Interface.GetDeviceSpecsByID(devices...)
}
// GetAllDeviceSpecs returns the device specs for all available devices.
func (l *wrapper) GetAllDeviceSpecs() ([]specs.Device, error) {
return l.Interface.GetAllDeviceSpecs()

View File

@@ -20,14 +20,8 @@ LOG_ARTIFACTS_DIR ?= $(CURDIR)/e2e_logs
GINKGO_BIN := $(CURDIR)/bin/ginkgo
# If GINKGO_FOCUS is not set, run all tests
# current available tests:
# - nvidia-container-cli
# - docker
GINKGO_FOCUS ?=
test: $(GINKGO_BIN)
$(GINKGO_BIN) $(GINKGO_ARGS) -v --json-report ginkgo.json --focus="$(GINKGO_FOCUS)" ./tests/e2e/...
$(GINKGO_BIN) $(GINKGO_ARGS) -v --json-report ginkgo.json ./tests/e2e/...
$(GINKGO_BIN):
mkdir -p $(CURDIR)/bin

View File

@@ -28,21 +28,12 @@ var dockerInstallTemplate = `
#! /usr/bin/env bash
set -xe
# if the TEMP_DIR is already set, use it
if [ -f /tmp/ctk_e2e_temp_dir.txt ]; then
TEMP_DIR=$(cat /tmp/ctk_e2e_temp_dir.txt)
else
TEMP_DIR="/tmp/ctk_e2e.$(date +%s)_$RANDOM"
echo "$TEMP_DIR" > /tmp/ctk_e2e_temp_dir.txt
fi
# if TEMP_DIR does not exist, create it
if [ ! -d "$TEMP_DIR" ]; then
mkdir -p "$TEMP_DIR"
fi
: ${IMAGE:={{.Image}}}
# Create a temporary directory
TEMP_DIR="/tmp/ctk_e2e.$(date +%s)_$RANDOM"
mkdir -p "$TEMP_DIR"
# Given that docker has an init function that checks for the existence of the
# nvidia-container-toolkit, we need to create a symlink to the nvidia-container-runtime-hook
# in the /usr/bin directory.

View File

@@ -1,208 +0,0 @@
/*
* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
*
* 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 e2e
import (
"context"
"fmt"
"strings"
"text/template"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
const (
dockerDindTemplate = `docker run -d --rm --privileged \
-v {{.SharedDir}}/etc/docker:/etc/docker \
-v {{.SharedDir}}/run/nvidia:/run/nvidia \
-v {{.SharedDir}}/usr/local/nvidia:/usr/local/nvidia \
--name {{.ContainerName}} \
docker:dind -H unix://{{.DockerSocket}}`
dockerToolkitTemplate = `docker run -d --rm --privileged \
--volumes-from {{.DindContainerName}} \
--pid "container:{{.DindContainerName}}" \
-e RUNTIME_ARGS="--socket {{.DockerSocket}}" \
-v {{.TestScriptPath}}:/usr/local/bin/libnvidia-container-cli.sh \
--name {{.ContainerName}} \
{{.ToolkitImage}} /usr/local/bin/libnvidia-container-cli.sh`
dockerDefaultConfigTemplate = `
{
"registry-mirrors": ["https://mirror.gcr.io"]
}`
libnvidiaContainerCliTestTemplate = `#!/usr/bin/env bash
set -euo pipefail
apt-get update -y && apt-get install -y curl gnupg2
WORKDIR="$(mktemp -d)"
ROOTFS="${WORKDIR}/rootfs"
mkdir -p "${ROOTFS}"
export WORKDIR ROOTFS # make them visible in the child shell
unshare --mount --pid --fork --propagation private -- bash -eux <<'IN_NS'
: "${ROOTFS:?}" "${WORKDIR:?}" # abort if either is empty
# 1 Populate minimal Ubuntu base
curl -L http://cdimage.ubuntu.com/ubuntu-base/releases/22.04/release/ubuntu-base-22.04-base-amd64.tar.gz \
| tar -C "$ROOTFS" -xz
# 2 Add non-root user
useradd -R "$ROOTFS" -U -u 1000 -s /bin/bash nvidia
# 3 Bind-mount new root and unshare mounts
mount --bind "$ROOTFS" "$ROOTFS"
mount --make-private "$ROOTFS"
cd "$ROOTFS"
# 4 Minimal virtual filesystems
mount -t proc proc proc
mount -t sysfs sys sys
mount -t tmpfs tmp tmp
mount -t tmpfs run run
# 5 GPU setup
nvidia-container-cli --load-kmods --debug=container-cli.log \
configure --ldconfig=@/sbin/ldconfig.real \
--no-cgroups --utility --device=0 "$(pwd)"
# 6 Switch root
mkdir -p mnt
pivot_root . mnt
umount -l /mnt
exec nvidia-smi -L
IN_NS
`
)
// Integration tests for Docker runtime
var _ = Describe("nvidia-container-cli", Ordered, ContinueOnFailure, func() {
var runner Runner
var sharedDir string
var dindContainerName string
var toolkitContainerName string
var dockerSocket string
var hostOutput string
// Install the NVIDIA Container Toolkit
BeforeAll(func(ctx context.Context) {
runner = NewRunner(
WithHost(sshHost),
WithPort(sshPort),
WithSshKey(sshKey),
WithSshUser(sshUser),
)
// Setup shared directory and container names
sharedDir = "/tmp/nvidia-container-toolkit-test"
dindContainerName = "nvidia-container-toolkit-dind"
toolkitContainerName = "nvidia-container-toolkit-test"
dockerSocket = "/run/nvidia/docker.sock"
// Get host nvidia-smi output
var err error
hostOutput, _, err = runner.Run("nvidia-smi -L")
Expect(err).ToNot(HaveOccurred())
// Pull ubuntu image
_, _, err = runner.Run("docker pull ubuntu")
Expect(err).ToNot(HaveOccurred())
// Create shared directory structure
_, _, err = runner.Run(fmt.Sprintf("mkdir -p %s/{etc/docker,run/nvidia,usr/local/nvidia}", sharedDir))
Expect(err).ToNot(HaveOccurred())
// Copy docker default config
createDockerConfigCmd := fmt.Sprintf("cat > %s/etc/docker/daemon.json <<'EOF'\n%s\nEOF",
sharedDir, dockerDefaultConfigTemplate)
_, _, err = runner.Run(createDockerConfigCmd)
Expect(err).ToNot(HaveOccurred())
// Start Docker-in-Docker container
tmpl, err := template.New("dockerDind").Parse(dockerDindTemplate)
Expect(err).ToNot(HaveOccurred())
var dindCmdBuilder strings.Builder
err = tmpl.Execute(&dindCmdBuilder, map[string]string{
"SharedDir": sharedDir,
"ContainerName": dindContainerName,
"DockerSocket": dockerSocket,
})
Expect(err).ToNot(HaveOccurred())
_, _, err = runner.Run(dindCmdBuilder.String())
Expect(err).ToNot(HaveOccurred())
})
AfterAll(func(ctx context.Context) {
// Cleanup containers
runner.Run(fmt.Sprintf("docker rm -f %s", toolkitContainerName))
runner.Run(fmt.Sprintf("docker rm -f %s", dindContainerName))
// Cleanup shared directory
_, _, err := runner.Run(fmt.Sprintf("rm -rf %s", sharedDir))
Expect(err).ToNot(HaveOccurred())
})
When("running nvidia-smi -L", Ordered, func() {
It("should support NVIDIA_VISIBLE_DEVICES and NVIDIA_DRIVER_CAPABILITIES", func(ctx context.Context) {
// 1. Create the test script
testScriptPath := fmt.Sprintf("%s/libnvidia-container-cli.sh", sharedDir)
createScriptCmd := fmt.Sprintf("cat > %s <<'EOF'\n%s\nEOF\nchmod +x %s",
testScriptPath, libnvidiaContainerCliTestTemplate, testScriptPath)
_, _, err := runner.Run(createScriptCmd)
Expect(err).ToNot(HaveOccurred())
// 2. Start the toolkit container
tmpl, err := template.New("dockerToolkit").Parse(dockerToolkitTemplate)
Expect(err).ToNot(HaveOccurred())
var toolkitCmdBuilder strings.Builder
err = tmpl.Execute(&toolkitCmdBuilder, map[string]string{
"DindContainerName": dindContainerName,
"ContainerName": toolkitContainerName,
"DockerSocket": dockerSocket,
"TestScriptPath": testScriptPath,
"ToolkitImage": imageName + ":" + imageTag,
})
Expect(err).ToNot(HaveOccurred())
_, _, err = runner.Run(toolkitCmdBuilder.String())
Expect(err).ToNot(HaveOccurred())
// 3. Wait for and verify the output
expected := strings.TrimSpace(strings.ReplaceAll(hostOutput, "\r", ""))
Eventually(func() string {
logs, _, err := runner.Run(fmt.Sprintf("docker logs %s | tail -n 20", toolkitContainerName))
if err != nil {
return ""
}
logLines := strings.Split(strings.TrimSpace(logs), "\n")
if len(logLines) == 0 {
return ""
}
return strings.TrimSpace(strings.ReplaceAll(logLines[len(logLines)-1], "\r", ""))
}, "5m", "5s").Should(Equal(expected))
})
})
})

View File

@@ -216,4 +216,23 @@ var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
Expect(ldconfigOut).To(ContainSubstring("/usr/lib64"))
})
})
Describe("Disabling device node creation", Ordered, func() {
BeforeAll(func(ctx context.Context) {
_, _, err := runner.Run("docker pull ubuntu")
Expect(err).ToNot(HaveOccurred())
})
It("should work with nvidia-container-runtime-hook", func(ctx context.Context) {
output, _, err := runner.Run("docker run --rm -i --runtime=runc --gpus=all ubuntu bash -c \"grep ModifyDeviceFiles: /proc/driver/nvidia/params\"")
Expect(err).ToNot(HaveOccurred())
Expect(output).To(Equal("ModifyDeviceFiles: 0\n"))
})
It("should work with automatic CDI spec generation", func(ctx context.Context) {
output, _, err := runner.Run("docker run --rm -i --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=runtime.nvidia.com/gpu=all ubuntu bash -c \"grep ModifyDeviceFiles: /proc/driver/nvidia/params\"")
Expect(err).ToNot(HaveOccurred())
Expect(output).To(Equal("ModifyDeviceFiles: 0\n"))
})
})
})

View File

@@ -7,7 +7,7 @@ toolchain go1.24.1
require (
github.com/onsi/ginkgo/v2 v2.23.4
github.com/onsi/gomega v1.37.0
golang.org/x/crypto v0.38.0
golang.org/x/crypto v0.39.0
)
require (
@@ -16,9 +16,9 @@ require (
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/tools v0.31.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/tools v0.33.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View File

@@ -24,18 +24,18 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -1 +0,0 @@
{"ociVersion":"1.0.1-dev","process":{"terminal":true,"user":{"uid":0,"gid":0},"args":["sh"],"env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","TERM=xterm"],"cwd":"/","capabilities":{"bounding":["CAP_AUDIT_WRITE","CAP_KILL","CAP_NET_BIND_SERVICE"],"effective":["CAP_AUDIT_WRITE","CAP_KILL","CAP_NET_BIND_SERVICE"],"inheritable":["CAP_AUDIT_WRITE","CAP_KILL","CAP_NET_BIND_SERVICE"],"permitted":["CAP_AUDIT_WRITE","CAP_KILL","CAP_NET_BIND_SERVICE"],"ambient":["CAP_AUDIT_WRITE","CAP_KILL","CAP_NET_BIND_SERVICE"]},"rlimits":[{"type":"RLIMIT_NOFILE","hard":1024,"soft":1024}],"noNewPrivileges":true},"root":{"path":"rootfs","readonly":true},"hostname":"runc","mounts":[{"destination":"/proc","type":"proc","source":"proc"},{"destination":"/dev","type":"tmpfs","source":"tmpfs","options":["nosuid","strictatime","mode=755","size=65536k"]},{"destination":"/dev/pts","type":"devpts","source":"devpts","options":["nosuid","noexec","newinstance","ptmxmode=0666","mode=0620","gid=5"]},{"destination":"/dev/shm","type":"tmpfs","source":"shm","options":["nosuid","noexec","nodev","mode=1777","size=65536k"]},{"destination":"/dev/mqueue","type":"mqueue","source":"mqueue","options":["nosuid","noexec","nodev"]},{"destination":"/sys","type":"sysfs","source":"sysfs","options":["nosuid","noexec","nodev","ro"]},{"destination":"/sys/fs/cgroup","type":"cgroup","source":"cgroup","options":["nosuid","noexec","nodev","relatime","ro"]}],"hooks":{"prestart":[{"path":"nvidia-container-runtime-hook","args":["nvidia-container-runtime-hook","prestart"]}]},"linux":{"resources":{"devices":[{"allow":false,"access":"rwm"}]},"namespaces":[{"type":"pid"},{"type":"network"},{"type":"ipc"},{"type":"uts"},{"type":"mount"}],"maskedPaths":["/proc/kcore","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/sys/firmware","/proc/scsi"],"readonlyPaths":["/proc/asound","/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]}}

View File

@@ -20,14 +20,19 @@ import (
// returned by MultiAlgorithmSigner and don't appear in the Signature.Format
// field.
const (
CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"
CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com"
CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com"
CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
// Deprecated: DSA is only supported at insecure key sizes, and was removed
// from major implementations.
CertAlgoDSAv01 = InsecureCertAlgoDSAv01
// Deprecated: DSA is only supported at insecure key sizes, and was removed
// from major implementations.
InsecureCertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"
CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com"
CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com"
// CertAlgoRSASHA256v01 and CertAlgoRSASHA512v01 can't appear as a
// Certificate.Type (or PublicKey.Type), but only in
@@ -485,16 +490,16 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
//
// This map must be kept in sync with the one in agent/client.go.
var certKeyAlgoNames = map[string]string{
CertAlgoRSAv01: KeyAlgoRSA,
CertAlgoRSASHA256v01: KeyAlgoRSASHA256,
CertAlgoRSASHA512v01: KeyAlgoRSASHA512,
CertAlgoDSAv01: KeyAlgoDSA,
CertAlgoECDSA256v01: KeyAlgoECDSA256,
CertAlgoECDSA384v01: KeyAlgoECDSA384,
CertAlgoECDSA521v01: KeyAlgoECDSA521,
CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256,
CertAlgoED25519v01: KeyAlgoED25519,
CertAlgoSKED25519v01: KeyAlgoSKED25519,
CertAlgoRSAv01: KeyAlgoRSA,
CertAlgoRSASHA256v01: KeyAlgoRSASHA256,
CertAlgoRSASHA512v01: KeyAlgoRSASHA512,
InsecureCertAlgoDSAv01: InsecureKeyAlgoDSA,
CertAlgoECDSA256v01: KeyAlgoECDSA256,
CertAlgoECDSA384v01: KeyAlgoECDSA384,
CertAlgoECDSA521v01: KeyAlgoECDSA521,
CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256,
CertAlgoED25519v01: KeyAlgoED25519,
CertAlgoSKED25519v01: KeyAlgoSKED25519,
}
// underlyingAlgo returns the signature algorithm associated with algo (which is

View File

@@ -58,11 +58,11 @@ func newRC4(key, iv []byte) (cipher.Stream, error) {
type cipherMode struct {
keySize int
ivSize int
create func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error)
create func(key, iv []byte, macKey []byte, algs DirectionAlgorithms) (packetCipher, error)
}
func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
return func(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) {
return func(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) {
stream, err := createFunc(key, iv)
if err != nil {
return nil, err
@@ -98,36 +98,36 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream,
var cipherModes = map[string]*cipherMode{
// Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms
// are defined in the order specified in the RFC.
"aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},
"aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},
"aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},
CipherAES128CTR: {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},
CipherAES192CTR: {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},
CipherAES256CTR: {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},
// Ciphers from RFC 4345, which introduces security-improved arcfour ciphers.
// They are defined in the order specified in the RFC.
"arcfour128": {16, 0, streamCipherMode(1536, newRC4)},
"arcfour256": {32, 0, streamCipherMode(1536, newRC4)},
InsecureCipherRC4128: {16, 0, streamCipherMode(1536, newRC4)},
InsecureCipherRC4256: {32, 0, streamCipherMode(1536, newRC4)},
// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
// Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
// RC4) has problems with weak keys, and should be used with caution."
// RFC 4345 introduces improved versions of Arcfour.
"arcfour": {16, 0, streamCipherMode(0, newRC4)},
InsecureCipherRC4: {16, 0, streamCipherMode(0, newRC4)},
// AEAD ciphers
gcm128CipherID: {16, 12, newGCMCipher},
gcm256CipherID: {32, 12, newGCMCipher},
chacha20Poly1305ID: {64, 0, newChaCha20Cipher},
CipherAES128GCM: {16, 12, newGCMCipher},
CipherAES256GCM: {32, 12, newGCMCipher},
CipherChaCha20Poly1305: {64, 0, newChaCha20Cipher},
// CBC mode is insecure and so is not included in the default config.
// (See https://www.ieee-security.org/TC/SP2013/papers/4977a526.pdf). If absolutely
// needed, it's possible to specify a custom Config to enable it.
// You should expect that an active attacker can recover plaintext if
// you do.
aes128cbcID: {16, aes.BlockSize, newAESCBCCipher},
InsecureCipherAES128CBC: {16, aes.BlockSize, newAESCBCCipher},
// 3des-cbc is insecure and is not included in the default
// config.
tripledescbcID: {24, des.BlockSize, newTripleDESCBCCipher},
InsecureCipherTripleDESCBC: {24, des.BlockSize, newTripleDESCBCCipher},
}
// prefixLen is the length of the packet prefix that contains the packet length
@@ -307,7 +307,7 @@ type gcmCipher struct {
buf []byte
}
func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) {
func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs DirectionAlgorithms) (packetCipher, error) {
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
@@ -429,7 +429,7 @@ type cbcCipher struct {
oracleCamouflage uint32
}
func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) {
cbc := &cbcCipher{
mac: macModes[algs.MAC].new(macKey),
decrypter: cipher.NewCBCDecrypter(c, iv),
@@ -443,7 +443,7 @@ func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorith
return cbc, nil
}
func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
func newAESCBCCipher(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) {
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
@@ -457,7 +457,7 @@ func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCi
return cbc, nil
}
func newTripleDESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
func newTripleDESCBCCipher(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) {
c, err := des.NewTripleDESCipher(key)
if err != nil {
return nil, err
@@ -635,8 +635,6 @@ func (c *cbcCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader
return nil
}
const chacha20Poly1305ID = "chacha20-poly1305@openssh.com"
// chacha20Poly1305Cipher implements the chacha20-poly1305@openssh.com
// AEAD, which is described here:
//
@@ -650,7 +648,7 @@ type chacha20Poly1305Cipher struct {
buf []byte
}
func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) {
func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs DirectionAlgorithms) (packetCipher, error) {
if len(key) != 64 {
panic(len(key))
}

View File

@@ -110,6 +110,7 @@ func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) e
}
c.sessionID = c.transport.getSessionID()
c.algorithms = c.transport.getAlgorithms()
return c.clientAuthenticate(config)
}

View File

@@ -10,6 +10,7 @@ import (
"fmt"
"io"
"math"
"slices"
"sync"
_ "crypto/sha1"
@@ -24,69 +25,258 @@ const (
serviceSSH = "ssh-connection"
)
// supportedCiphers lists ciphers we support but might not recommend.
var supportedCiphers = []string{
"aes128-ctr", "aes192-ctr", "aes256-ctr",
"aes128-gcm@openssh.com", gcm256CipherID,
chacha20Poly1305ID,
"arcfour256", "arcfour128", "arcfour",
aes128cbcID,
tripledescbcID,
// The ciphers currently or previously implemented by this library, to use in
// [Config.Ciphers]. For a list, see the [Algorithms.Ciphers] returned by
// [SupportedAlgorithms] or [InsecureAlgorithms].
const (
CipherAES128GCM = "aes128-gcm@openssh.com"
CipherAES256GCM = "aes256-gcm@openssh.com"
CipherChaCha20Poly1305 = "chacha20-poly1305@openssh.com"
CipherAES128CTR = "aes128-ctr"
CipherAES192CTR = "aes192-ctr"
CipherAES256CTR = "aes256-ctr"
InsecureCipherAES128CBC = "aes128-cbc"
InsecureCipherTripleDESCBC = "3des-cbc"
InsecureCipherRC4 = "arcfour"
InsecureCipherRC4128 = "arcfour128"
InsecureCipherRC4256 = "arcfour256"
)
// The key exchanges currently or previously implemented by this library, to use
// in [Config.KeyExchanges]. For a list, see the
// [Algorithms.KeyExchanges] returned by [SupportedAlgorithms] or
// [InsecureAlgorithms].
const (
InsecureKeyExchangeDH1SHA1 = "diffie-hellman-group1-sha1"
InsecureKeyExchangeDH14SHA1 = "diffie-hellman-group14-sha1"
KeyExchangeDH14SHA256 = "diffie-hellman-group14-sha256"
KeyExchangeDH16SHA512 = "diffie-hellman-group16-sha512"
KeyExchangeECDHP256 = "ecdh-sha2-nistp256"
KeyExchangeECDHP384 = "ecdh-sha2-nistp384"
KeyExchangeECDHP521 = "ecdh-sha2-nistp521"
KeyExchangeCurve25519 = "curve25519-sha256"
InsecureKeyExchangeDHGEXSHA1 = "diffie-hellman-group-exchange-sha1"
KeyExchangeDHGEXSHA256 = "diffie-hellman-group-exchange-sha256"
// KeyExchangeMLKEM768X25519 is supported from Go 1.24.
KeyExchangeMLKEM768X25519 = "mlkem768x25519-sha256"
// An alias for KeyExchangeCurve25519SHA256. This kex ID will be added if
// KeyExchangeCurve25519SHA256 is requested for backward compatibility with
// OpenSSH versions up to 7.2.
keyExchangeCurve25519LibSSH = "curve25519-sha256@libssh.org"
)
// The message authentication code (MAC) currently or previously implemented by
// this library, to use in [Config.MACs]. For a list, see the
// [Algorithms.MACs] returned by [SupportedAlgorithms] or
// [InsecureAlgorithms].
const (
HMACSHA256ETM = "hmac-sha2-256-etm@openssh.com"
HMACSHA512ETM = "hmac-sha2-512-etm@openssh.com"
HMACSHA256 = "hmac-sha2-256"
HMACSHA512 = "hmac-sha2-512"
HMACSHA1 = "hmac-sha1"
InsecureHMACSHA196 = "hmac-sha1-96"
)
var (
// supportedKexAlgos specifies key-exchange algorithms implemented by this
// package in preference order, excluding those with security issues.
supportedKexAlgos = []string{
KeyExchangeCurve25519,
KeyExchangeECDHP256,
KeyExchangeECDHP384,
KeyExchangeECDHP521,
KeyExchangeDH14SHA256,
KeyExchangeDH16SHA512,
KeyExchangeDHGEXSHA256,
}
// defaultKexAlgos specifies the default preference for key-exchange
// algorithms in preference order.
defaultKexAlgos = []string{
KeyExchangeCurve25519,
KeyExchangeECDHP256,
KeyExchangeECDHP384,
KeyExchangeECDHP521,
KeyExchangeDH14SHA256,
InsecureKeyExchangeDH14SHA1,
}
// insecureKexAlgos specifies key-exchange algorithms implemented by this
// package and which have security issues.
insecureKexAlgos = []string{
InsecureKeyExchangeDH14SHA1,
InsecureKeyExchangeDH1SHA1,
InsecureKeyExchangeDHGEXSHA1,
}
// supportedCiphers specifies cipher algorithms implemented by this package
// in preference order, excluding those with security issues.
supportedCiphers = []string{
CipherAES128GCM,
CipherAES256GCM,
CipherChaCha20Poly1305,
CipherAES128CTR,
CipherAES192CTR,
CipherAES256CTR,
}
// defaultCiphers specifies the default preference for ciphers algorithms
// in preference order.
defaultCiphers = supportedCiphers
// insecureCiphers specifies cipher algorithms implemented by this
// package and which have security issues.
insecureCiphers = []string{
InsecureCipherAES128CBC,
InsecureCipherTripleDESCBC,
InsecureCipherRC4256,
InsecureCipherRC4128,
InsecureCipherRC4,
}
// supportedMACs specifies MAC algorithms implemented by this package in
// preference order, excluding those with security issues.
supportedMACs = []string{
HMACSHA256ETM,
HMACSHA512ETM,
HMACSHA256,
HMACSHA512,
HMACSHA1,
}
// defaultMACs specifies the default preference for MAC algorithms in
// preference order.
defaultMACs = []string{
HMACSHA256ETM,
HMACSHA512ETM,
HMACSHA256,
HMACSHA512,
HMACSHA1,
InsecureHMACSHA196,
}
// insecureMACs specifies MAC algorithms implemented by this
// package and which have security issues.
insecureMACs = []string{
InsecureHMACSHA196,
}
// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e.
// methods of authenticating servers) implemented by this package in
// preference order, excluding those with security issues.
supportedHostKeyAlgos = []string{
CertAlgoRSASHA256v01,
CertAlgoRSASHA512v01,
CertAlgoECDSA256v01,
CertAlgoECDSA384v01,
CertAlgoECDSA521v01,
CertAlgoED25519v01,
KeyAlgoRSASHA256,
KeyAlgoRSASHA512,
KeyAlgoECDSA256,
KeyAlgoECDSA384,
KeyAlgoECDSA521,
KeyAlgoED25519,
}
// defaultHostKeyAlgos specifies the default preference for host-key
// algorithms in preference order.
defaultHostKeyAlgos = []string{
CertAlgoRSASHA256v01,
CertAlgoRSASHA512v01,
CertAlgoRSAv01,
InsecureCertAlgoDSAv01,
CertAlgoECDSA256v01,
CertAlgoECDSA384v01,
CertAlgoECDSA521v01,
CertAlgoED25519v01,
KeyAlgoECDSA256,
KeyAlgoECDSA384,
KeyAlgoECDSA521,
KeyAlgoRSASHA256,
KeyAlgoRSASHA512,
KeyAlgoRSA,
InsecureKeyAlgoDSA,
KeyAlgoED25519,
}
// insecureHostKeyAlgos specifies host-key algorithms implemented by this
// package and which have security issues.
insecureHostKeyAlgos = []string{
KeyAlgoRSA,
InsecureKeyAlgoDSA,
CertAlgoRSAv01,
InsecureCertAlgoDSAv01,
}
// supportedPubKeyAuthAlgos specifies the supported client public key
// authentication algorithms. Note that this doesn't include certificate
// types since those use the underlying algorithm. Order is irrelevant.
supportedPubKeyAuthAlgos = []string{
KeyAlgoED25519,
KeyAlgoSKED25519,
KeyAlgoSKECDSA256,
KeyAlgoECDSA256,
KeyAlgoECDSA384,
KeyAlgoECDSA521,
KeyAlgoRSASHA256,
KeyAlgoRSASHA512,
}
// defaultPubKeyAuthAlgos specifies the preferred client public key
// authentication algorithms. This list is sent to the client if it supports
// the server-sig-algs extension. Order is irrelevant.
defaultPubKeyAuthAlgos = []string{
KeyAlgoED25519,
KeyAlgoSKED25519,
KeyAlgoSKECDSA256,
KeyAlgoECDSA256,
KeyAlgoECDSA384,
KeyAlgoECDSA521,
KeyAlgoRSASHA256,
KeyAlgoRSASHA512,
KeyAlgoRSA,
InsecureKeyAlgoDSA,
}
// insecurePubKeyAuthAlgos specifies client public key authentication
// algorithms implemented by this package and which have security issues.
insecurePubKeyAuthAlgos = []string{
KeyAlgoRSA,
InsecureKeyAlgoDSA,
}
)
// NegotiatedAlgorithms defines algorithms negotiated between client and server.
type NegotiatedAlgorithms struct {
KeyExchange string
HostKey string
Read DirectionAlgorithms
Write DirectionAlgorithms
}
// preferredCiphers specifies the default preference for ciphers.
var preferredCiphers = []string{
"aes128-gcm@openssh.com", gcm256CipherID,
chacha20Poly1305ID,
"aes128-ctr", "aes192-ctr", "aes256-ctr",
// Algorithms defines a set of algorithms that can be configured in the client
// or server config for negotiation during a handshake.
type Algorithms struct {
KeyExchanges []string
Ciphers []string
MACs []string
HostKeys []string
PublicKeyAuths []string
}
// supportedKexAlgos specifies the supported key-exchange algorithms in
// preference order.
var supportedKexAlgos = []string{
kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,
// P384 and P521 are not constant-time yet, but since we don't
// reuse ephemeral keys, using them for ECDH should be OK.
kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
kexAlgoDH14SHA256, kexAlgoDH16SHA512, kexAlgoDH14SHA1,
kexAlgoDH1SHA1,
// SupportedAlgorithms returns algorithms currently implemented by this package,
// excluding those with security issues, which are returned by
// InsecureAlgorithms. The algorithms listed here are in preference order.
func SupportedAlgorithms() Algorithms {
return Algorithms{
Ciphers: slices.Clone(supportedCiphers),
MACs: slices.Clone(supportedMACs),
KeyExchanges: slices.Clone(supportedKexAlgos),
HostKeys: slices.Clone(supportedHostKeyAlgos),
PublicKeyAuths: slices.Clone(supportedPubKeyAuthAlgos),
}
}
// serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden
// for the server half.
var serverForbiddenKexAlgos = map[string]struct{}{
kexAlgoDHGEXSHA1: {}, // server half implementation is only minimal to satisfy the automated tests
kexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests
}
// preferredKexAlgos specifies the default preference for key-exchange
// algorithms in preference order. The diffie-hellman-group16-sha512 algorithm
// is disabled by default because it is a bit slower than the others.
var preferredKexAlgos = []string{
kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,
kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
kexAlgoDH14SHA256, kexAlgoDH14SHA1,
}
// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
// of authenticating servers) in preference order.
var supportedHostKeyAlgos = []string{
CertAlgoRSASHA256v01, CertAlgoRSASHA512v01,
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
KeyAlgoRSASHA256, KeyAlgoRSASHA512,
KeyAlgoRSA, KeyAlgoDSA,
KeyAlgoED25519,
}
// supportedMACs specifies a default set of MAC algorithms in preference order.
// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed
// because they have reached the end of their useful life.
var supportedMACs = []string{
"hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1", "hmac-sha1-96",
// InsecureAlgorithms returns algorithms currently implemented by this package
// and which have security issues.
func InsecureAlgorithms() Algorithms {
return Algorithms{
KeyExchanges: slices.Clone(insecureKexAlgos),
Ciphers: slices.Clone(insecureCiphers),
MACs: slices.Clone(insecureMACs),
HostKeys: slices.Clone(insecureHostKeyAlgos),
PublicKeyAuths: slices.Clone(insecurePubKeyAuthAlgos),
}
}
var supportedCompressions = []string{compressionNone}
@@ -94,13 +284,13 @@ var supportedCompressions = []string{compressionNone}
// hashFuncs keeps the mapping of supported signature algorithms to their
// respective hashes needed for signing and verification.
var hashFuncs = map[string]crypto.Hash{
KeyAlgoRSA: crypto.SHA1,
KeyAlgoRSASHA256: crypto.SHA256,
KeyAlgoRSASHA512: crypto.SHA512,
KeyAlgoDSA: crypto.SHA1,
KeyAlgoECDSA256: crypto.SHA256,
KeyAlgoECDSA384: crypto.SHA384,
KeyAlgoECDSA521: crypto.SHA512,
KeyAlgoRSA: crypto.SHA1,
KeyAlgoRSASHA256: crypto.SHA256,
KeyAlgoRSASHA512: crypto.SHA512,
InsecureKeyAlgoDSA: crypto.SHA1,
KeyAlgoECDSA256: crypto.SHA256,
KeyAlgoECDSA384: crypto.SHA384,
KeyAlgoECDSA521: crypto.SHA512,
// KeyAlgoED25519 doesn't pre-hash.
KeyAlgoSKECDSA256: crypto.SHA256,
KeyAlgoSKED25519: crypto.SHA256,
@@ -135,18 +325,6 @@ func isRSACert(algo string) bool {
return isRSA(algo)
}
// supportedPubKeyAuthAlgos specifies the supported client public key
// authentication algorithms. Note that this doesn't include certificate types
// since those use the underlying algorithm. This list is sent to the client if
// it supports the server-sig-algs extension. Order is irrelevant.
var supportedPubKeyAuthAlgos = []string{
KeyAlgoED25519,
KeyAlgoSKED25519, KeyAlgoSKECDSA256,
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA,
KeyAlgoDSA,
}
// unexpectedMessageError results when the SSH message that we received didn't
// match what we wanted.
func unexpectedMessageError(expected, got uint8) error {
@@ -169,20 +347,21 @@ func findCommon(what string, client []string, server []string) (common string, e
return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server)
}
// directionAlgorithms records algorithm choices in one direction (either read or write)
type directionAlgorithms struct {
// DirectionAlgorithms defines the algorithms negotiated in one direction
// (either read or write).
type DirectionAlgorithms struct {
Cipher string
MAC string
Compression string
compression string
}
// rekeyBytes returns a rekeying intervals in bytes.
func (a *directionAlgorithms) rekeyBytes() int64 {
func (a *DirectionAlgorithms) rekeyBytes() int64 {
// According to RFC 4344 block ciphers should rekey after
// 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is
// 128.
switch a.Cipher {
case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcm128CipherID, gcm256CipherID, aes128cbcID:
case CipherAES128CTR, CipherAES192CTR, CipherAES256CTR, CipherAES128GCM, CipherAES256GCM, InsecureCipherAES128CBC:
return 16 * (1 << 32)
}
@@ -192,32 +371,25 @@ func (a *directionAlgorithms) rekeyBytes() int64 {
}
var aeadCiphers = map[string]bool{
gcm128CipherID: true,
gcm256CipherID: true,
chacha20Poly1305ID: true,
CipherAES128GCM: true,
CipherAES256GCM: true,
CipherChaCha20Poly1305: true,
}
type algorithms struct {
kex string
hostKey string
w directionAlgorithms
r directionAlgorithms
}
func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *NegotiatedAlgorithms, err error) {
result := &NegotiatedAlgorithms{}
func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) {
result := &algorithms{}
result.kex, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos)
result.KeyExchange, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos)
if err != nil {
return
}
result.hostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos)
result.HostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos)
if err != nil {
return
}
stoc, ctos := &result.w, &result.r
stoc, ctos := &result.Write, &result.Read
if isClient {
ctos, stoc = stoc, ctos
}
@@ -246,12 +418,12 @@ func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMs
}
}
ctos.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
ctos.compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
if err != nil {
return
}
stoc.Compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient)
stoc.compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient)
if err != nil {
return
}
@@ -297,7 +469,7 @@ func (c *Config) SetDefaults() {
c.Rand = rand.Reader
}
if c.Ciphers == nil {
c.Ciphers = preferredCiphers
c.Ciphers = defaultCiphers
}
var ciphers []string
for _, c := range c.Ciphers {
@@ -309,19 +481,22 @@ func (c *Config) SetDefaults() {
c.Ciphers = ciphers
if c.KeyExchanges == nil {
c.KeyExchanges = preferredKexAlgos
c.KeyExchanges = defaultKexAlgos
}
var kexs []string
for _, k := range c.KeyExchanges {
if kexAlgoMap[k] != nil {
// Ignore the KEX if we have no kexAlgoMap definition.
kexs = append(kexs, k)
if k == KeyExchangeCurve25519 && !contains(c.KeyExchanges, keyExchangeCurve25519LibSSH) {
kexs = append(kexs, keyExchangeCurve25519LibSSH)
}
}
}
c.KeyExchanges = kexs
if c.MACs == nil {
c.MACs = supportedMACs
c.MACs = defaultMACs
}
var macs []string
for _, m := range c.MACs {

View File

@@ -74,6 +74,13 @@ type Conn interface {
// Disconnect
}
// AlgorithmsConnMetadata is a ConnMetadata that can return the algorithms
// negotiated between client and server.
type AlgorithmsConnMetadata interface {
ConnMetadata
Algorithms() NegotiatedAlgorithms
}
// DiscardRequests consumes and rejects all requests from the
// passed-in channel.
func DiscardRequests(in <-chan *Request) {
@@ -106,6 +113,7 @@ type sshConn struct {
sessionID []byte
clientVersion []byte
serverVersion []byte
algorithms NegotiatedAlgorithms
}
func dup(src []byte) []byte {
@@ -141,3 +149,7 @@ func (c *sshConn) ClientVersion() []byte {
func (c *sshConn) ServerVersion() []byte {
return dup(c.serverVersion)
}
func (c *sshConn) Algorithms() NegotiatedAlgorithms {
return c.algorithms
}

View File

@@ -38,7 +38,7 @@ type keyingTransport interface {
// prepareKeyChange sets up a key change. The key change for a
// direction will be effected if a msgNewKeys message is sent
// or received.
prepareKeyChange(*algorithms, *kexResult) error
prepareKeyChange(*NegotiatedAlgorithms, *kexResult) error
// setStrictMode sets the strict KEX mode, notably triggering
// sequence number resets on sending or receiving msgNewKeys.
@@ -115,7 +115,7 @@ type handshakeTransport struct {
bannerCallback BannerCallback
// Algorithms agreed in the last key exchange.
algorithms *algorithms
algorithms *NegotiatedAlgorithms
// Counters exclusively owned by readLoop.
readPacketsLeft uint32
@@ -164,7 +164,7 @@ func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byt
if config.HostKeyAlgorithms != nil {
t.hostKeyAlgorithms = config.HostKeyAlgorithms
} else {
t.hostKeyAlgorithms = supportedHostKeyAlgos
t.hostKeyAlgorithms = defaultHostKeyAlgos
}
go t.readLoop()
go t.kexLoop()
@@ -184,6 +184,10 @@ func (t *handshakeTransport) getSessionID() []byte {
return t.sessionID
}
func (t *handshakeTransport) getAlgorithms() NegotiatedAlgorithms {
return *t.algorithms
}
// waitSession waits for the session to be established. This should be
// the first thing to call after instantiating handshakeTransport.
func (t *handshakeTransport) waitSession() error {
@@ -290,7 +294,7 @@ func (t *handshakeTransport) resetWriteThresholds() {
if t.config.RekeyThreshold > 0 {
t.writeBytesLeft = int64(t.config.RekeyThreshold)
} else if t.algorithms != nil {
t.writeBytesLeft = t.algorithms.w.rekeyBytes()
t.writeBytesLeft = t.algorithms.Write.rekeyBytes()
} else {
t.writeBytesLeft = 1 << 30
}
@@ -407,7 +411,7 @@ func (t *handshakeTransport) resetReadThresholds() {
if t.config.RekeyThreshold > 0 {
t.readBytesLeft = int64(t.config.RekeyThreshold)
} else if t.algorithms != nil {
t.readBytesLeft = t.algorithms.r.rekeyBytes()
t.readBytesLeft = t.algorithms.Read.rekeyBytes()
} else {
t.readBytesLeft = 1 << 30
}
@@ -700,9 +704,9 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
}
}
kex, ok := kexAlgoMap[t.algorithms.kex]
kex, ok := kexAlgoMap[t.algorithms.KeyExchange]
if !ok {
return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.kex)
return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.KeyExchange)
}
var result *kexResult
@@ -809,12 +813,12 @@ func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner {
}
func (t *handshakeTransport) server(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {
hostKey := pickHostKey(t.hostKeys, t.algorithms.hostKey)
hostKey := pickHostKey(t.hostKeys, t.algorithms.HostKey)
if hostKey == nil {
return nil, errors.New("ssh: internal error: negotiated unsupported signature type")
}
r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.hostKey)
r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.HostKey)
return r, err
}
@@ -829,7 +833,7 @@ func (t *handshakeTransport) client(kex kexAlgorithm, magics *handshakeMagics) (
return nil, err
}
if err := verifyHostKeySignature(hostKey, t.algorithms.hostKey, result); err != nil {
if err := verifyHostKeySignature(hostKey, t.algorithms.HostKey, result); err != nil {
return nil, err
}

View File

@@ -20,21 +20,18 @@ import (
)
const (
kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1"
kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1"
kexAlgoDH14SHA256 = "diffie-hellman-group14-sha256"
kexAlgoDH16SHA512 = "diffie-hellman-group16-sha512"
kexAlgoECDH256 = "ecdh-sha2-nistp256"
kexAlgoECDH384 = "ecdh-sha2-nistp384"
kexAlgoECDH521 = "ecdh-sha2-nistp521"
kexAlgoCurve25519SHA256LibSSH = "curve25519-sha256@libssh.org"
kexAlgoCurve25519SHA256 = "curve25519-sha256"
// For the following kex only the client half contains a production
// ready implementation. The server half only consists of a minimal
// implementation to satisfy the automated tests.
kexAlgoDHGEXSHA1 = "diffie-hellman-group-exchange-sha1"
kexAlgoDHGEXSHA256 = "diffie-hellman-group-exchange-sha256"
// This is the group called diffie-hellman-group1-sha1 in RFC 4253 and
// Oakley Group 2 in RFC 2409.
oakleyGroup2 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF"
// This is the group called diffie-hellman-group14-sha1 in RFC 4253 and
// Oakley Group 14 in RFC 3526.
oakleyGroup14 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF"
// This is the group called diffie-hellman-group15-sha512 in RFC 8268 and
// Oakley Group 15 in RFC 3526.
oakleyGroup15 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
// This is the group called diffie-hellman-group16-sha512 in RFC 8268 and
// Oakley Group 16 in RFC 3526.
oakleyGroup16 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF"
)
// kexResult captures the outcome of a key exchange.
@@ -402,53 +399,46 @@ func ecHash(curve elliptic.Curve) crypto.Hash {
var kexAlgoMap = map[string]kexAlgorithm{}
func init() {
// This is the group called diffie-hellman-group1-sha1 in
// RFC 4253 and Oakley Group 2 in RFC 2409.
p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16)
kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{
p, _ := new(big.Int).SetString(oakleyGroup2, 16)
kexAlgoMap[InsecureKeyExchangeDH1SHA1] = &dhGroup{
g: new(big.Int).SetInt64(2),
p: p,
pMinus1: new(big.Int).Sub(p, bigOne),
hashFunc: crypto.SHA1,
}
// This are the groups called diffie-hellman-group14-sha1 and
// diffie-hellman-group14-sha256 in RFC 4253 and RFC 8268,
// and Oakley Group 14 in RFC 3526.
p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
p, _ = new(big.Int).SetString(oakleyGroup14, 16)
group14 := &dhGroup{
g: new(big.Int).SetInt64(2),
p: p,
pMinus1: new(big.Int).Sub(p, bigOne),
}
kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{
kexAlgoMap[InsecureKeyExchangeDH14SHA1] = &dhGroup{
g: group14.g, p: group14.p, pMinus1: group14.pMinus1,
hashFunc: crypto.SHA1,
}
kexAlgoMap[kexAlgoDH14SHA256] = &dhGroup{
kexAlgoMap[KeyExchangeDH14SHA256] = &dhGroup{
g: group14.g, p: group14.p, pMinus1: group14.pMinus1,
hashFunc: crypto.SHA256,
}
// This is the group called diffie-hellman-group16-sha512 in RFC
// 8268 and Oakley Group 16 in RFC 3526.
p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", 16)
p, _ = new(big.Int).SetString(oakleyGroup16, 16)
kexAlgoMap[kexAlgoDH16SHA512] = &dhGroup{
kexAlgoMap[KeyExchangeDH16SHA512] = &dhGroup{
g: new(big.Int).SetInt64(2),
p: p,
pMinus1: new(big.Int).Sub(p, bigOne),
hashFunc: crypto.SHA512,
}
kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}
kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}
kexAlgoMap[kexAlgoCurve25519SHA256LibSSH] = &curve25519sha256{}
kexAlgoMap[kexAlgoDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}
kexAlgoMap[kexAlgoDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}
kexAlgoMap[KeyExchangeECDHP521] = &ecdh{elliptic.P521()}
kexAlgoMap[KeyExchangeECDHP384] = &ecdh{elliptic.P384()}
kexAlgoMap[KeyExchangeECDHP256] = &ecdh{elliptic.P256()}
kexAlgoMap[KeyExchangeCurve25519] = &curve25519sha256{}
kexAlgoMap[keyExchangeCurve25519LibSSH] = &curve25519sha256{}
kexAlgoMap[InsecureKeyExchangeDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}
kexAlgoMap[KeyExchangeDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}
}
// curve25519sha256 implements the curve25519-sha256 (formerly known as
@@ -601,9 +591,9 @@ const (
func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
// Send GexRequest
kexDHGexRequest := kexDHGexRequestMsg{
MinBits: dhGroupExchangeMinimumBits,
PreferedBits: dhGroupExchangePreferredBits,
MaxBits: dhGroupExchangeMaximumBits,
MinBits: dhGroupExchangeMinimumBits,
PreferredBits: dhGroupExchangePreferredBits,
MaxBits: dhGroupExchangeMaximumBits,
}
if err := c.writePacket(Marshal(&kexDHGexRequest)); err != nil {
return nil, err
@@ -690,9 +680,7 @@ func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshak
}
// Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256.
//
// This is a minimal implementation to satisfy the automated tests.
func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
func (gex *dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
// Receive GexRequest
packet, err := c.readPacket()
if err != nil {
@@ -702,13 +690,32 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
if err = Unmarshal(packet, &kexDHGexRequest); err != nil {
return
}
// We check that the request received is valid and that the MaxBits
// requested are at least equal to our supported minimum. This is the same
// check done in OpenSSH:
// https://github.com/openssh/openssh-portable/blob/80a2f64b/kexgexs.c#L94
//
// Furthermore, we also check that the required MinBits are less than or
// equal to 4096 because we can use up to Oakley Group 16.
if kexDHGexRequest.MaxBits < kexDHGexRequest.MinBits || kexDHGexRequest.PreferredBits < kexDHGexRequest.MinBits ||
kexDHGexRequest.MaxBits < kexDHGexRequest.PreferredBits || kexDHGexRequest.MaxBits < dhGroupExchangeMinimumBits ||
kexDHGexRequest.MinBits > 4096 {
return nil, fmt.Errorf("ssh: DH GEX request out of range, min: %d, max: %d, preferred: %d", kexDHGexRequest.MinBits,
kexDHGexRequest.MaxBits, kexDHGexRequest.PreferredBits)
}
var p *big.Int
// We hardcode sending Oakley Group 14 (2048 bits), Oakley Group 15 (3072
// bits) or Oakley Group 16 (4096 bits), based on the requested max size.
if kexDHGexRequest.MaxBits < 3072 {
p, _ = new(big.Int).SetString(oakleyGroup14, 16)
} else if kexDHGexRequest.MaxBits < 4096 {
p, _ = new(big.Int).SetString(oakleyGroup15, 16)
} else {
p, _ = new(big.Int).SetString(oakleyGroup16, 16)
}
// Send GexGroup
// This is the group called diffie-hellman-group14-sha1 in RFC
// 4253 and Oakley Group 14 in RFC 3526.
p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
g := big.NewInt(2)
msg := &kexDHGexGroupMsg{
P: p,
G: g,
@@ -746,9 +753,9 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
h := gex.hashFunc.New()
magics.write(h)
writeString(h, hostKeyBytes)
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
binary.Write(h, binary.BigEndian, kexDHGexRequest.MinBits)
binary.Write(h, binary.BigEndian, kexDHGexRequest.PreferredBits)
binary.Write(h, binary.BigEndian, kexDHGexRequest.MaxBits)
writeInt(h, p)
writeInt(h, g)
writeInt(h, kexDHGexInit.X)

View File

@@ -36,14 +36,19 @@ import (
// ClientConfig.HostKeyAlgorithms, Signature.Format, or as AlgorithmSigner
// arguments.
const (
KeyAlgoRSA = "ssh-rsa"
KeyAlgoDSA = "ssh-dss"
KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com"
KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
KeyAlgoED25519 = "ssh-ed25519"
KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com"
KeyAlgoRSA = "ssh-rsa"
// Deprecated: DSA is only supported at insecure key sizes, and was removed
// from major implementations.
KeyAlgoDSA = InsecureKeyAlgoDSA
// Deprecated: DSA is only supported at insecure key sizes, and was removed
// from major implementations.
InsecureKeyAlgoDSA = "ssh-dss"
KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com"
KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
KeyAlgoED25519 = "ssh-ed25519"
KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com"
// KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, not
// public key formats, so they can't appear as a PublicKey.Type. The
@@ -67,7 +72,7 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err
switch algo {
case KeyAlgoRSA:
return parseRSA(in)
case KeyAlgoDSA:
case InsecureKeyAlgoDSA:
return parseDSA(in)
case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
return parseECDSA(in)
@@ -77,7 +82,7 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err
return parseED25519(in)
case KeyAlgoSKED25519:
return parseSKEd25519(in)
case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
case CertAlgoRSAv01, InsecureCertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
cert, err := parseCert(in, certKeyAlgoNames[algo])
if err != nil {
return nil, nil, err

View File

@@ -47,22 +47,22 @@ func (t truncatingMAC) Size() int {
func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() }
var macModes = map[string]*macMode{
"hmac-sha2-512-etm@openssh.com": {64, true, func(key []byte) hash.Hash {
HMACSHA512ETM: {64, true, func(key []byte) hash.Hash {
return hmac.New(sha512.New, key)
}},
"hmac-sha2-256-etm@openssh.com": {32, true, func(key []byte) hash.Hash {
HMACSHA256ETM: {32, true, func(key []byte) hash.Hash {
return hmac.New(sha256.New, key)
}},
"hmac-sha2-512": {64, false, func(key []byte) hash.Hash {
HMACSHA512: {64, false, func(key []byte) hash.Hash {
return hmac.New(sha512.New, key)
}},
"hmac-sha2-256": {32, false, func(key []byte) hash.Hash {
HMACSHA256: {32, false, func(key []byte) hash.Hash {
return hmac.New(sha256.New, key)
}},
"hmac-sha1": {20, false, func(key []byte) hash.Hash {
HMACSHA1: {20, false, func(key []byte) hash.Hash {
return hmac.New(sha1.New, key)
}},
"hmac-sha1-96": {20, false, func(key []byte) hash.Hash {
InsecureHMACSHA196: {20, false, func(key []byte) hash.Hash {
return truncatingMAC{12, hmac.New(sha1.New, key)}
}},
}

View File

@@ -122,9 +122,9 @@ type kexDHGexReplyMsg struct {
const msgKexDHGexRequest = 34
type kexDHGexRequestMsg struct {
MinBits uint32 `sshtype:"34"`
PreferedBits uint32
MaxBits uint32
MinBits uint32 `sshtype:"34"`
PreferredBits uint32
MaxBits uint32
}
// See RFC 4253, section 10.

View File

@@ -19,19 +19,15 @@ import (
"golang.org/x/crypto/curve25519"
)
const (
kexAlgoMLKEM768xCurve25519SHA256 = "mlkem768x25519-sha256"
)
func init() {
// After Go 1.24rc1 mlkem swapped the order of return values of Encapsulate.
// See #70950.
if runtime.Version() == "go1.24rc1" {
return
}
supportedKexAlgos = slices.Insert(supportedKexAlgos, 0, kexAlgoMLKEM768xCurve25519SHA256)
preferredKexAlgos = slices.Insert(preferredKexAlgos, 0, kexAlgoMLKEM768xCurve25519SHA256)
kexAlgoMap[kexAlgoMLKEM768xCurve25519SHA256] = &mlkem768WithCurve25519sha256{}
supportedKexAlgos = slices.Insert(supportedKexAlgos, 0, KeyExchangeMLKEM768X25519)
defaultKexAlgos = slices.Insert(defaultKexAlgos, 0, KeyExchangeMLKEM768X25519)
kexAlgoMap[KeyExchangeMLKEM768X25519] = &mlkem768WithCurve25519sha256{}
}
// mlkem768WithCurve25519sha256 implements the hybrid ML-KEM768 with

View File

@@ -243,22 +243,15 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
fullConf.MaxAuthTries = 6
}
if len(fullConf.PublicKeyAuthAlgorithms) == 0 {
fullConf.PublicKeyAuthAlgorithms = supportedPubKeyAuthAlgos
fullConf.PublicKeyAuthAlgorithms = defaultPubKeyAuthAlgos
} else {
for _, algo := range fullConf.PublicKeyAuthAlgorithms {
if !contains(supportedPubKeyAuthAlgos, algo) {
if !contains(SupportedAlgorithms().PublicKeyAuths, algo) && !contains(InsecureAlgorithms().PublicKeyAuths, algo) {
c.Close()
return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo)
}
}
}
// Check if the config contains any unsupported key exchanges
for _, kex := range fullConf.KeyExchanges {
if _, ok := serverForbiddenKexAlgos[kex]; ok {
c.Close()
return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex)
}
}
s := &connection{
sshConn: sshConn{conn: c},
@@ -315,6 +308,7 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error)
// We just did the key change, so the session ID is established.
s.sessionID = s.transport.getSessionID()
s.algorithms = s.transport.getAlgorithms()
var packet []byte
if packet, err = s.transport.readPacket(); err != nil {

View File

@@ -16,13 +16,6 @@ import (
// wire. No message decoding is done, to minimize the impact on timing.
const debugTransport = false
const (
gcm128CipherID = "aes128-gcm@openssh.com"
gcm256CipherID = "aes256-gcm@openssh.com"
aes128cbcID = "aes128-cbc"
tripledescbcID = "3des-cbc"
)
// packetConn represents a transport that implements packet based
// operations.
type packetConn interface {
@@ -92,14 +85,14 @@ func (t *transport) setInitialKEXDone() {
// prepareKeyChange sets up key material for a keychange. The key changes in
// both directions are triggered by reading and writing a msgNewKey packet
// respectively.
func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error {
ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult)
func (t *transport) prepareKeyChange(algs *NegotiatedAlgorithms, kexResult *kexResult) error {
ciph, err := newPacketCipher(t.reader.dir, algs.Read, kexResult)
if err != nil {
return err
}
t.reader.pendingKeyChange <- ciph
ciph, err = newPacketCipher(t.writer.dir, algs.w, kexResult)
ciph, err = newPacketCipher(t.writer.dir, algs.Write, kexResult)
if err != nil {
return err
}
@@ -259,7 +252,7 @@ var (
// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as
// described in RFC 4253, section 6.4. direction should either be serverKeys
// (to setup server->client keys) or clientKeys (for client->server keys).
func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
func newPacketCipher(d direction, algs DirectionAlgorithms, kex *kexResult) (packetCipher, error) {
cipherMode := cipherModes[algs.Cipher]
iv := make([]byte, cipherMode.ivSize)

View File

@@ -10,6 +10,7 @@
// builds a list of push/pop events and their node type. Subsequent
// method calls that request a traversal scan this list, rather than walk
// the AST, and perform type filtering using efficient bit sets.
// This representation is sometimes called a "balanced parenthesis tree."
//
// Experiments suggest the inspector's traversals are about 2.5x faster
// than ast.Inspect, but it may take around 5 traversals for this
@@ -47,9 +48,10 @@ type Inspector struct {
events []event
}
//go:linkname events
//go:linkname events golang.org/x/tools/go/ast/inspector.events
func events(in *Inspector) []event { return in.events }
//go:linkname packEdgeKindAndIndex golang.org/x/tools/go/ast/inspector.packEdgeKindAndIndex
func packEdgeKindAndIndex(ek edge.Kind, index int) int32 {
return int32(uint32(index+1)<<7 | uint32(ek))
}
@@ -57,7 +59,7 @@ func packEdgeKindAndIndex(ek edge.Kind, index int) int32 {
// unpackEdgeKindAndIndex unpacks the edge kind and edge index (within
// an []ast.Node slice) from the parent field of a pop event.
//
//go:linkname unpackEdgeKindAndIndex
//go:linkname unpackEdgeKindAndIndex golang.org/x/tools/go/ast/inspector.unpackEdgeKindAndIndex
func unpackEdgeKindAndIndex(x int32) (edge.Kind, int) {
// The "parent" field of a pop node holds the
// edge Kind in the lower 7 bits and the index+1

View File

@@ -217,7 +217,7 @@ func typeOf(n ast.Node) uint64 {
return 0
}
//go:linkname maskOf
//go:linkname maskOf golang.org/x/tools/go/ast/inspector.maskOf
func maskOf(nodes []ast.Node) uint64 {
if len(nodes) == 0 {
return math.MaxUint64 // match all node types

View File

@@ -56,7 +56,7 @@ go.uber.org/automaxprocs
go.uber.org/automaxprocs/internal/cgroups
go.uber.org/automaxprocs/internal/runtime
go.uber.org/automaxprocs/maxprocs
# golang.org/x/crypto v0.38.0
# golang.org/x/crypto v0.39.0
## explicit; go 1.23.0
golang.org/x/crypto/blowfish
golang.org/x/crypto/chacha20
@@ -65,7 +65,7 @@ golang.org/x/crypto/internal/alias
golang.org/x/crypto/internal/poly1305
golang.org/x/crypto/ssh
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
# golang.org/x/net v0.38.0
# golang.org/x/net v0.40.0
## explicit; go 1.23.0
golang.org/x/net/html
golang.org/x/net/html/atom
@@ -74,7 +74,7 @@ golang.org/x/net/html/charset
## explicit; go 1.23.0
golang.org/x/sys/cpu
golang.org/x/sys/unix
# golang.org/x/text v0.25.0
# golang.org/x/text v0.26.0
## explicit; go 1.23.0
golang.org/x/text/encoding
golang.org/x/text/encoding/charmap
@@ -93,7 +93,7 @@ golang.org/x/text/internal/utf8internal
golang.org/x/text/language
golang.org/x/text/runes
golang.org/x/text/transform
# golang.org/x/tools v0.31.0
# golang.org/x/tools v0.33.0
## explicit; go 1.23.0
golang.org/x/tools/cover
golang.org/x/tools/go/ast/inspector

View File

@@ -89,6 +89,10 @@ func (d *device) GetArchitectureAsString() (string, error) {
return "Ada Lovelace", nil
case nvml.DEVICE_ARCH_HOPPER:
return "Hopper", nil
case nvml.DEVICE_ARCH_BLACKWELL:
return "Blackwell", nil
case nvml.DEVICE_ARCH_T23X:
return "Orin", nil
case nvml.DEVICE_ARCH_UNKNOWN:
return "Unknown", nil
}

View File

@@ -52,6 +52,10 @@ const (
MAX_PHYSICAL_BRIDGE = 128
// MAX_THERMAL_SENSORS_PER_GPU as defined in nvml/nvml.h
MAX_THERMAL_SENSORS_PER_GPU = 3
// DEVICE_UUID_ASCII_LEN as defined in nvml/nvml.h
DEVICE_UUID_ASCII_LEN = 41
// DEVICE_UUID_BINARY_LEN as defined in nvml/nvml.h
DEVICE_UUID_BINARY_LEN = 16
// FlagDefault as defined in nvml/nvml.h
FlagDefault = 0
// FlagForce as defined in nvml/nvml.h
@@ -62,54 +66,8 @@ const (
DOUBLE_BIT_ECC = 0
// MAX_GPU_PERF_PSTATES as defined in nvml/nvml.h
MAX_GPU_PERF_PSTATES = 16
// GRID_LICENSE_EXPIRY_NOT_AVAILABLE as defined in nvml/nvml.h
GRID_LICENSE_EXPIRY_NOT_AVAILABLE = 0
// GRID_LICENSE_EXPIRY_INVALID as defined in nvml/nvml.h
GRID_LICENSE_EXPIRY_INVALID = 1
// GRID_LICENSE_EXPIRY_VALID as defined in nvml/nvml.h
GRID_LICENSE_EXPIRY_VALID = 2
// GRID_LICENSE_EXPIRY_NOT_APPLICABLE as defined in nvml/nvml.h
GRID_LICENSE_EXPIRY_NOT_APPLICABLE = 3
// GRID_LICENSE_EXPIRY_PERMANENT as defined in nvml/nvml.h
GRID_LICENSE_EXPIRY_PERMANENT = 4
// GRID_LICENSE_BUFFER_SIZE as defined in nvml/nvml.h
GRID_LICENSE_BUFFER_SIZE = 128
// VGPU_NAME_BUFFER_SIZE as defined in nvml/nvml.h
VGPU_NAME_BUFFER_SIZE = 64
// GRID_LICENSE_FEATURE_MAX_COUNT as defined in nvml/nvml.h
GRID_LICENSE_FEATURE_MAX_COUNT = 3
// INVALID_VGPU_PLACEMENT_ID as defined in nvml/nvml.h
INVALID_VGPU_PLACEMENT_ID = 65535
// VGPU_SCHEDULER_POLICY_UNKNOWN as defined in nvml/nvml.h
VGPU_SCHEDULER_POLICY_UNKNOWN = 0
// VGPU_SCHEDULER_POLICY_BEST_EFFORT as defined in nvml/nvml.h
VGPU_SCHEDULER_POLICY_BEST_EFFORT = 1
// VGPU_SCHEDULER_POLICY_EQUAL_SHARE as defined in nvml/nvml.h
VGPU_SCHEDULER_POLICY_EQUAL_SHARE = 2
// VGPU_SCHEDULER_POLICY_FIXED_SHARE as defined in nvml/nvml.h
VGPU_SCHEDULER_POLICY_FIXED_SHARE = 3
// SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT as defined in nvml/nvml.h
SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT = 3
// SCHEDULER_SW_MAX_LOG_ENTRIES as defined in nvml/nvml.h
SCHEDULER_SW_MAX_LOG_ENTRIES = 200
// VGPU_SCHEDULER_ARR_DEFAULT as defined in nvml/nvml.h
VGPU_SCHEDULER_ARR_DEFAULT = 0
// VGPU_SCHEDULER_ARR_DISABLE as defined in nvml/nvml.h
VGPU_SCHEDULER_ARR_DISABLE = 1
// VGPU_SCHEDULER_ARR_ENABLE as defined in nvml/nvml.h
VGPU_SCHEDULER_ARR_ENABLE = 2
// GRID_LICENSE_STATE_UNKNOWN as defined in nvml/nvml.h
GRID_LICENSE_STATE_UNKNOWN = 0
// GRID_LICENSE_STATE_UNINITIALIZED as defined in nvml/nvml.h
GRID_LICENSE_STATE_UNINITIALIZED = 1
// GRID_LICENSE_STATE_UNLICENSED_UNRESTRICTED as defined in nvml/nvml.h
GRID_LICENSE_STATE_UNLICENSED_UNRESTRICTED = 2
// GRID_LICENSE_STATE_UNLICENSED_RESTRICTED as defined in nvml/nvml.h
GRID_LICENSE_STATE_UNLICENSED_RESTRICTED = 3
// GRID_LICENSE_STATE_UNLICENSED as defined in nvml/nvml.h
GRID_LICENSE_STATE_UNLICENSED = 4
// GRID_LICENSE_STATE_LICENSED as defined in nvml/nvml.h
GRID_LICENSE_STATE_LICENSED = 5
// PERF_MODES_BUFFER_SIZE as defined in nvml/nvml.h
PERF_MODES_BUFFER_SIZE = 2048
// GSP_FIRMWARE_VERSION_BUF_SIZE as defined in nvml/nvml.h
GSP_FIRMWARE_VERSION_BUF_SIZE = 64
// DEVICE_ARCH_KEPLER as defined in nvml/nvml.h
@@ -128,6 +86,10 @@ const (
DEVICE_ARCH_ADA = 8
// DEVICE_ARCH_HOPPER as defined in nvml/nvml.h
DEVICE_ARCH_HOPPER = 9
// DEVICE_ARCH_BLACKWELL as defined in nvml/nvml.h
DEVICE_ARCH_BLACKWELL = 10
// DEVICE_ARCH_T23X as defined in nvml/nvml.h
DEVICE_ARCH_T23X = 11
// DEVICE_ARCH_UNKNOWN as defined in nvml/nvml.h
DEVICE_ARCH_UNKNOWN = 4294967295
// BUS_TYPE_UNKNOWN as defined in nvml/nvml.h
@@ -170,6 +132,82 @@ const (
ADAPTIVE_CLOCKING_INFO_STATUS_ENABLED = 1
// MAX_GPU_UTILIZATIONS as defined in nvml/nvml.h
MAX_GPU_UTILIZATIONS = 8
// PCIE_ATOMICS_CAP_FETCHADD32 as defined in nvml/nvml.h
PCIE_ATOMICS_CAP_FETCHADD32 = 1
// PCIE_ATOMICS_CAP_FETCHADD64 as defined in nvml/nvml.h
PCIE_ATOMICS_CAP_FETCHADD64 = 2
// PCIE_ATOMICS_CAP_SWAP32 as defined in nvml/nvml.h
PCIE_ATOMICS_CAP_SWAP32 = 4
// PCIE_ATOMICS_CAP_SWAP64 as defined in nvml/nvml.h
PCIE_ATOMICS_CAP_SWAP64 = 8
// PCIE_ATOMICS_CAP_CAS32 as defined in nvml/nvml.h
PCIE_ATOMICS_CAP_CAS32 = 16
// PCIE_ATOMICS_CAP_CAS64 as defined in nvml/nvml.h
PCIE_ATOMICS_CAP_CAS64 = 32
// PCIE_ATOMICS_CAP_CAS128 as defined in nvml/nvml.h
PCIE_ATOMICS_CAP_CAS128 = 64
// PCIE_ATOMICS_OPS_MAX as defined in nvml/nvml.h
PCIE_ATOMICS_OPS_MAX = 7
// POWER_SCOPE_GPU as defined in nvml/nvml.h
POWER_SCOPE_GPU = 0
// POWER_SCOPE_MODULE as defined in nvml/nvml.h
POWER_SCOPE_MODULE = 1
// POWER_SCOPE_MEMORY as defined in nvml/nvml.h
POWER_SCOPE_MEMORY = 2
// GRID_LICENSE_EXPIRY_NOT_AVAILABLE as defined in nvml/nvml.h
GRID_LICENSE_EXPIRY_NOT_AVAILABLE = 0
// GRID_LICENSE_EXPIRY_INVALID as defined in nvml/nvml.h
GRID_LICENSE_EXPIRY_INVALID = 1
// GRID_LICENSE_EXPIRY_VALID as defined in nvml/nvml.h
GRID_LICENSE_EXPIRY_VALID = 2
// GRID_LICENSE_EXPIRY_NOT_APPLICABLE as defined in nvml/nvml.h
GRID_LICENSE_EXPIRY_NOT_APPLICABLE = 3
// GRID_LICENSE_EXPIRY_PERMANENT as defined in nvml/nvml.h
GRID_LICENSE_EXPIRY_PERMANENT = 4
// GRID_LICENSE_BUFFER_SIZE as defined in nvml/nvml.h
GRID_LICENSE_BUFFER_SIZE = 128
// VGPU_NAME_BUFFER_SIZE as defined in nvml/nvml.h
VGPU_NAME_BUFFER_SIZE = 64
// GRID_LICENSE_FEATURE_MAX_COUNT as defined in nvml/nvml.h
GRID_LICENSE_FEATURE_MAX_COUNT = 3
// INVALID_VGPU_PLACEMENT_ID as defined in nvml/nvml.h
INVALID_VGPU_PLACEMENT_ID = 65535
// VGPU_PGPU_HETEROGENEOUS_MODE as defined in nvml/nvml.h
VGPU_PGPU_HETEROGENEOUS_MODE = 0
// VGPU_PGPU_HOMOGENEOUS_MODE as defined in nvml/nvml.h
VGPU_PGPU_HOMOGENEOUS_MODE = 1
// VGPU_SCHEDULER_POLICY_UNKNOWN as defined in nvml/nvml.h
VGPU_SCHEDULER_POLICY_UNKNOWN = 0
// VGPU_SCHEDULER_POLICY_BEST_EFFORT as defined in nvml/nvml.h
VGPU_SCHEDULER_POLICY_BEST_EFFORT = 1
// VGPU_SCHEDULER_POLICY_EQUAL_SHARE as defined in nvml/nvml.h
VGPU_SCHEDULER_POLICY_EQUAL_SHARE = 2
// VGPU_SCHEDULER_POLICY_FIXED_SHARE as defined in nvml/nvml.h
VGPU_SCHEDULER_POLICY_FIXED_SHARE = 3
// SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT as defined in nvml/nvml.h
SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT = 3
// SCHEDULER_SW_MAX_LOG_ENTRIES as defined in nvml/nvml.h
SCHEDULER_SW_MAX_LOG_ENTRIES = 200
// VGPU_SCHEDULER_ARR_DEFAULT as defined in nvml/nvml.h
VGPU_SCHEDULER_ARR_DEFAULT = 0
// VGPU_SCHEDULER_ARR_DISABLE as defined in nvml/nvml.h
VGPU_SCHEDULER_ARR_DISABLE = 1
// VGPU_SCHEDULER_ARR_ENABLE as defined in nvml/nvml.h
VGPU_SCHEDULER_ARR_ENABLE = 2
// VGPU_SCHEDULER_ENGINE_TYPE_GRAPHICS as defined in nvml/nvml.h
VGPU_SCHEDULER_ENGINE_TYPE_GRAPHICS = 1
// GRID_LICENSE_STATE_UNKNOWN as defined in nvml/nvml.h
GRID_LICENSE_STATE_UNKNOWN = 0
// GRID_LICENSE_STATE_UNINITIALIZED as defined in nvml/nvml.h
GRID_LICENSE_STATE_UNINITIALIZED = 1
// GRID_LICENSE_STATE_UNLICENSED_UNRESTRICTED as defined in nvml/nvml.h
GRID_LICENSE_STATE_UNLICENSED_UNRESTRICTED = 2
// GRID_LICENSE_STATE_UNLICENSED_RESTRICTED as defined in nvml/nvml.h
GRID_LICENSE_STATE_UNLICENSED_RESTRICTED = 3
// GRID_LICENSE_STATE_UNLICENSED as defined in nvml/nvml.h
GRID_LICENSE_STATE_UNLICENSED = 4
// GRID_LICENSE_STATE_LICENSED as defined in nvml/nvml.h
GRID_LICENSE_STATE_LICENSED = 5
// FI_DEV_ECC_CURRENT as defined in nvml/nvml.h
FI_DEV_ECC_CURRENT = 1
// FI_DEV_ECC_PENDING as defined in nvml/nvml.h
@@ -562,10 +600,188 @@ const (
FI_DEV_TEMPERATURE_MEM_MAX_TLIMIT = 195
// FI_DEV_TEMPERATURE_GPU_MAX_TLIMIT as defined in nvml/nvml.h
FI_DEV_TEMPERATURE_GPU_MAX_TLIMIT = 196
// FI_DEV_PCIE_COUNT_TX_BYTES as defined in nvml/nvml.h
FI_DEV_PCIE_COUNT_TX_BYTES = 197
// FI_DEV_PCIE_COUNT_RX_BYTES as defined in nvml/nvml.h
FI_DEV_PCIE_COUNT_RX_BYTES = 198
// FI_DEV_IS_MIG_MODE_INDEPENDENT_MIG_QUERY_CAPABLE as defined in nvml/nvml.h
FI_DEV_IS_MIG_MODE_INDEPENDENT_MIG_QUERY_CAPABLE = 199
// FI_DEV_NVLINK_GET_POWER_THRESHOLD_MAX as defined in nvml/nvml.h
FI_DEV_NVLINK_GET_POWER_THRESHOLD_MAX = 200
// FI_DEV_NVLINK_COUNT_XMIT_PACKETS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_XMIT_PACKETS = 201
// FI_DEV_NVLINK_COUNT_XMIT_BYTES as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_XMIT_BYTES = 202
// FI_DEV_NVLINK_COUNT_RCV_PACKETS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_RCV_PACKETS = 203
// FI_DEV_NVLINK_COUNT_RCV_BYTES as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_RCV_BYTES = 204
// FI_DEV_NVLINK_COUNT_VL15_DROPPED as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_VL15_DROPPED = 205
// FI_DEV_NVLINK_COUNT_MALFORMED_PACKET_ERRORS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_MALFORMED_PACKET_ERRORS = 206
// FI_DEV_NVLINK_COUNT_BUFFER_OVERRUN_ERRORS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_BUFFER_OVERRUN_ERRORS = 207
// FI_DEV_NVLINK_COUNT_RCV_ERRORS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_RCV_ERRORS = 208
// FI_DEV_NVLINK_COUNT_RCV_REMOTE_ERRORS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_RCV_REMOTE_ERRORS = 209
// FI_DEV_NVLINK_COUNT_RCV_GENERAL_ERRORS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_RCV_GENERAL_ERRORS = 210
// FI_DEV_NVLINK_COUNT_LOCAL_LINK_INTEGRITY_ERRORS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_LOCAL_LINK_INTEGRITY_ERRORS = 211
// FI_DEV_NVLINK_COUNT_XMIT_DISCARDS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_XMIT_DISCARDS = 212
// FI_DEV_NVLINK_COUNT_LINK_RECOVERY_SUCCESSFUL_EVENTS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_LINK_RECOVERY_SUCCESSFUL_EVENTS = 213
// FI_DEV_NVLINK_COUNT_LINK_RECOVERY_FAILED_EVENTS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_LINK_RECOVERY_FAILED_EVENTS = 214
// FI_DEV_NVLINK_COUNT_LINK_RECOVERY_EVENTS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_LINK_RECOVERY_EVENTS = 215
// FI_DEV_NVLINK_COUNT_RAW_BER_LANE0 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_RAW_BER_LANE0 = 216
// FI_DEV_NVLINK_COUNT_RAW_BER_LANE1 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_RAW_BER_LANE1 = 217
// FI_DEV_NVLINK_COUNT_RAW_BER as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_RAW_BER = 218
// FI_DEV_NVLINK_COUNT_EFFECTIVE_ERRORS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_EFFECTIVE_ERRORS = 219
// FI_DEV_NVLINK_COUNT_EFFECTIVE_BER as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_EFFECTIVE_BER = 220
// FI_DEV_NVLINK_COUNT_SYMBOL_ERRORS as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_SYMBOL_ERRORS = 221
// FI_DEV_NVLINK_COUNT_SYMBOL_BER as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_SYMBOL_BER = 222
// FI_DEV_NVLINK_GET_POWER_THRESHOLD_MIN as defined in nvml/nvml.h
FI_DEV_NVLINK_GET_POWER_THRESHOLD_MIN = 223
// FI_DEV_NVLINK_GET_POWER_THRESHOLD_UNITS as defined in nvml/nvml.h
FI_DEV_NVLINK_GET_POWER_THRESHOLD_UNITS = 224
// FI_DEV_NVLINK_GET_POWER_THRESHOLD_SUPPORTED as defined in nvml/nvml.h
FI_DEV_NVLINK_GET_POWER_THRESHOLD_SUPPORTED = 225
// FI_DEV_RESET_STATUS as defined in nvml/nvml.h
FI_DEV_RESET_STATUS = 226
// FI_DEV_DRAIN_AND_RESET_STATUS as defined in nvml/nvml.h
FI_DEV_DRAIN_AND_RESET_STATUS = 227
// FI_DEV_PCIE_OUTBOUND_ATOMICS_MASK as defined in nvml/nvml.h
FI_DEV_PCIE_OUTBOUND_ATOMICS_MASK = 228
// FI_DEV_PCIE_INBOUND_ATOMICS_MASK as defined in nvml/nvml.h
FI_DEV_PCIE_INBOUND_ATOMICS_MASK = 229
// FI_DEV_GET_GPU_RECOVERY_ACTION as defined in nvml/nvml.h
FI_DEV_GET_GPU_RECOVERY_ACTION = 230
// FI_DEV_C2C_LINK_ERROR_INTR as defined in nvml/nvml.h
FI_DEV_C2C_LINK_ERROR_INTR = 231
// FI_DEV_C2C_LINK_ERROR_REPLAY as defined in nvml/nvml.h
FI_DEV_C2C_LINK_ERROR_REPLAY = 232
// FI_DEV_C2C_LINK_ERROR_REPLAY_B2B as defined in nvml/nvml.h
FI_DEV_C2C_LINK_ERROR_REPLAY_B2B = 233
// FI_DEV_C2C_LINK_POWER_STATE as defined in nvml/nvml.h
FI_DEV_C2C_LINK_POWER_STATE = 234
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_0 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_0 = 235
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_1 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_1 = 236
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_2 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_2 = 237
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_3 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_3 = 238
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_4 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_4 = 239
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_5 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_5 = 240
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_6 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_6 = 241
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_7 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_7 = 242
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_8 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_8 = 243
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_9 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_9 = 244
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_10 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_10 = 245
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_11 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_11 = 246
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_12 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_12 = 247
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_13 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_13 = 248
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_14 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_14 = 249
// FI_DEV_NVLINK_COUNT_FEC_HISTORY_15 as defined in nvml/nvml.h
FI_DEV_NVLINK_COUNT_FEC_HISTORY_15 = 250
// FI_DEV_CLOCKS_EVENT_REASON_SW_POWER_CAP as defined in nvml/nvml.h
FI_DEV_CLOCKS_EVENT_REASON_SW_POWER_CAP = 74
// FI_DEV_CLOCKS_EVENT_REASON_SYNC_BOOST as defined in nvml/nvml.h
FI_DEV_CLOCKS_EVENT_REASON_SYNC_BOOST = 76
// FI_DEV_CLOCKS_EVENT_REASON_SW_THERM_SLOWDOWN as defined in nvml/nvml.h
FI_DEV_CLOCKS_EVENT_REASON_SW_THERM_SLOWDOWN = 251
// FI_DEV_CLOCKS_EVENT_REASON_HW_THERM_SLOWDOWN as defined in nvml/nvml.h
FI_DEV_CLOCKS_EVENT_REASON_HW_THERM_SLOWDOWN = 252
// FI_DEV_CLOCKS_EVENT_REASON_HW_POWER_BRAKE_SLOWDOWN as defined in nvml/nvml.h
FI_DEV_CLOCKS_EVENT_REASON_HW_POWER_BRAKE_SLOWDOWN = 253
// FI_DEV_POWER_SYNC_BALANCING_FREQ as defined in nvml/nvml.h
FI_DEV_POWER_SYNC_BALANCING_FREQ = 254
// FI_DEV_POWER_SYNC_BALANCING_AF as defined in nvml/nvml.h
FI_DEV_POWER_SYNC_BALANCING_AF = 255
// FI_PWR_SMOOTHING_ENABLED as defined in nvml/nvml.h
FI_PWR_SMOOTHING_ENABLED = 256
// FI_PWR_SMOOTHING_PRIV_LVL as defined in nvml/nvml.h
FI_PWR_SMOOTHING_PRIV_LVL = 257
// FI_PWR_SMOOTHING_IMM_RAMP_DOWN_ENABLED as defined in nvml/nvml.h
FI_PWR_SMOOTHING_IMM_RAMP_DOWN_ENABLED = 258
// FI_PWR_SMOOTHING_APPLIED_TMP_CEIL as defined in nvml/nvml.h
FI_PWR_SMOOTHING_APPLIED_TMP_CEIL = 259
// FI_PWR_SMOOTHING_APPLIED_TMP_FLOOR as defined in nvml/nvml.h
FI_PWR_SMOOTHING_APPLIED_TMP_FLOOR = 260
// FI_PWR_SMOOTHING_MAX_PERCENT_TMP_FLOOR_SETTING as defined in nvml/nvml.h
FI_PWR_SMOOTHING_MAX_PERCENT_TMP_FLOOR_SETTING = 261
// FI_PWR_SMOOTHING_MIN_PERCENT_TMP_FLOOR_SETTING as defined in nvml/nvml.h
FI_PWR_SMOOTHING_MIN_PERCENT_TMP_FLOOR_SETTING = 262
// FI_PWR_SMOOTHING_HW_CIRCUITRY_PERCENT_LIFETIME_REMAINING as defined in nvml/nvml.h
FI_PWR_SMOOTHING_HW_CIRCUITRY_PERCENT_LIFETIME_REMAINING = 263
// FI_PWR_SMOOTHING_MAX_NUM_PRESET_PROFILES as defined in nvml/nvml.h
FI_PWR_SMOOTHING_MAX_NUM_PRESET_PROFILES = 264
// FI_PWR_SMOOTHING_PROFILE_PERCENT_TMP_FLOOR as defined in nvml/nvml.h
FI_PWR_SMOOTHING_PROFILE_PERCENT_TMP_FLOOR = 265
// FI_PWR_SMOOTHING_PROFILE_RAMP_UP_RATE as defined in nvml/nvml.h
FI_PWR_SMOOTHING_PROFILE_RAMP_UP_RATE = 266
// FI_PWR_SMOOTHING_PROFILE_RAMP_DOWN_RATE as defined in nvml/nvml.h
FI_PWR_SMOOTHING_PROFILE_RAMP_DOWN_RATE = 267
// FI_PWR_SMOOTHING_PROFILE_RAMP_DOWN_HYST_VAL as defined in nvml/nvml.h
FI_PWR_SMOOTHING_PROFILE_RAMP_DOWN_HYST_VAL = 268
// FI_PWR_SMOOTHING_ACTIVE_PRESET_PROFILE as defined in nvml/nvml.h
FI_PWR_SMOOTHING_ACTIVE_PRESET_PROFILE = 269
// FI_PWR_SMOOTHING_ADMIN_OVERRIDE_PERCENT_TMP_FLOOR as defined in nvml/nvml.h
FI_PWR_SMOOTHING_ADMIN_OVERRIDE_PERCENT_TMP_FLOOR = 270
// FI_PWR_SMOOTHING_ADMIN_OVERRIDE_RAMP_UP_RATE as defined in nvml/nvml.h
FI_PWR_SMOOTHING_ADMIN_OVERRIDE_RAMP_UP_RATE = 271
// FI_PWR_SMOOTHING_ADMIN_OVERRIDE_RAMP_DOWN_RATE as defined in nvml/nvml.h
FI_PWR_SMOOTHING_ADMIN_OVERRIDE_RAMP_DOWN_RATE = 272
// FI_PWR_SMOOTHING_ADMIN_OVERRIDE_RAMP_DOWN_HYST_VAL as defined in nvml/nvml.h
FI_PWR_SMOOTHING_ADMIN_OVERRIDE_RAMP_DOWN_HYST_VAL = 273
// FI_MAX as defined in nvml/nvml.h
FI_MAX = 200
FI_MAX = 274
// NVLINK_LOW_POWER_THRESHOLD_UNIT_100US as defined in nvml/nvml.h
NVLINK_LOW_POWER_THRESHOLD_UNIT_100US = 0
// NVLINK_LOW_POWER_THRESHOLD_UNIT_50US as defined in nvml/nvml.h
NVLINK_LOW_POWER_THRESHOLD_UNIT_50US = 1
// NVLINK_POWER_STATE_HIGH_SPEED as defined in nvml/nvml.h
NVLINK_POWER_STATE_HIGH_SPEED = 0
// NVLINK_POWER_STATE_LOW as defined in nvml/nvml.h
NVLINK_POWER_STATE_LOW = 1
// NVLINK_LOW_POWER_THRESHOLD_MIN as defined in nvml/nvml.h
NVLINK_LOW_POWER_THRESHOLD_MIN = 1
// NVLINK_LOW_POWER_THRESHOLD_MAX as defined in nvml/nvml.h
NVLINK_LOW_POWER_THRESHOLD_MAX = 8191
// NVLINK_LOW_POWER_THRESHOLD_RESET as defined in nvml/nvml.h
NVLINK_LOW_POWER_THRESHOLD_RESET = 4294967295
// NVLINK_LOW_POWER_THRESHOLD_DEFAULT as defined in nvml/nvml.h
NVLINK_LOW_POWER_THRESHOLD_DEFAULT = 4294967295
// C2C_POWER_STATE_FULL_POWER as defined in nvml/nvml.h
C2C_POWER_STATE_FULL_POWER = 0
// C2C_POWER_STATE_LOW_POWER as defined in nvml/nvml.h
C2C_POWER_STATE_LOW_POWER = 1
// EventTypeNone as defined in nvml/nvml.h
EventTypeNone = 0
// EventTypeSingleBitEccError as defined in nvml/nvml.h
EventTypeSingleBitEccError = 1
// EventTypeDoubleBitEccError as defined in nvml/nvml.h
@@ -580,10 +796,28 @@ const (
EventTypePowerSourceChange = 128
// EventMigConfigChange as defined in nvml/nvml.h
EventMigConfigChange = 256
// EventTypeNone as defined in nvml/nvml.h
EventTypeNone = 0
// EventTypeSingleBitEccErrorStorm as defined in nvml/nvml.h
EventTypeSingleBitEccErrorStorm = 512
// EventTypeDramRetirementEvent as defined in nvml/nvml.h
EventTypeDramRetirementEvent = 1024
// EventTypeDramRetirementFailure as defined in nvml/nvml.h
EventTypeDramRetirementFailure = 2048
// EventTypeNonFatalPoisonError as defined in nvml/nvml.h
EventTypeNonFatalPoisonError = 4096
// EventTypeFatalPoisonError as defined in nvml/nvml.h
EventTypeFatalPoisonError = 8192
// EventTypeGpuUnavailableError as defined in nvml/nvml.h
EventTypeGpuUnavailableError = 16384
// EventTypeGpuRecoveryAction as defined in nvml/nvml.h
EventTypeGpuRecoveryAction = 32768
// EventTypeAll as defined in nvml/nvml.h
EventTypeAll = 415
EventTypeAll = 65439
// SystemEventTypeGpuDriverUnbind as defined in nvml/nvml.h
SystemEventTypeGpuDriverUnbind = 1
// SystemEventTypeGpuDriverBind as defined in nvml/nvml.h
SystemEventTypeGpuDriverBind = 2
// SystemEventTypeCount as defined in nvml/nvml.h
SystemEventTypeCount = 2
// ClocksEventReasonGpuIdle as defined in nvml/nvml.h
ClocksEventReasonGpuIdle = 1
// ClocksEventReasonApplicationsClocksSetting as defined in nvml/nvml.h
@@ -640,6 +874,10 @@ const (
CC_SYSTEM_CPU_CAPS_AMD_SEV = 1
// CC_SYSTEM_CPU_CAPS_INTEL_TDX as defined in nvml/nvml.h
CC_SYSTEM_CPU_CAPS_INTEL_TDX = 2
// CC_SYSTEM_CPU_CAPS_AMD_SEV_SNP as defined in nvml/nvml.h
CC_SYSTEM_CPU_CAPS_AMD_SEV_SNP = 3
// CC_SYSTEM_CPU_CAPS_AMD_SNP_VTOM as defined in nvml/nvml.h
CC_SYSTEM_CPU_CAPS_AMD_SNP_VTOM = 4
// CC_SYSTEM_GPUS_CC_NOT_CAPABLE as defined in nvml/nvml.h
CC_SYSTEM_GPUS_CC_NOT_CAPABLE = 0
// CC_SYSTEM_GPUS_CC_CAPABLE as defined in nvml/nvml.h
@@ -683,7 +921,7 @@ const (
// CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MIN as defined in nvml/nvml.h
CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MIN = 50
// CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MAX as defined in nvml/nvml.h
CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MAX = 75
CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MAX = 65
// GPU_FABRIC_UUID_LEN as defined in nvml/nvml.h
GPU_FABRIC_UUID_LEN = 16
// GPU_FABRIC_STATE_NOT_SUPPORTED as defined in nvml/nvml.h
@@ -703,13 +941,37 @@ const (
// GPU_FABRIC_HEALTH_MASK_SHIFT_DEGRADED_BW as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_SHIFT_DEGRADED_BW = 0
// GPU_FABRIC_HEALTH_MASK_WIDTH_DEGRADED_BW as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_WIDTH_DEGRADED_BW = 17
// POWER_SCOPE_GPU as defined in nvml/nvml.h
POWER_SCOPE_GPU = 0
// POWER_SCOPE_MODULE as defined in nvml/nvml.h
POWER_SCOPE_MODULE = 1
// POWER_SCOPE_MEMORY as defined in nvml/nvml.h
POWER_SCOPE_MEMORY = 2
GPU_FABRIC_HEALTH_MASK_WIDTH_DEGRADED_BW = 3
// GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_NOT_SUPPORTED as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_NOT_SUPPORTED = 0
// GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_TRUE as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_TRUE = 1
// GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_FALSE as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_FALSE = 2
// GPU_FABRIC_HEALTH_MASK_SHIFT_ROUTE_RECOVERY as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_SHIFT_ROUTE_RECOVERY = 2
// GPU_FABRIC_HEALTH_MASK_WIDTH_ROUTE_RECOVERY as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_WIDTH_ROUTE_RECOVERY = 3
// GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_NOT_SUPPORTED as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_NOT_SUPPORTED = 0
// GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_TRUE as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_TRUE = 1
// GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_FALSE as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_FALSE = 2
// GPU_FABRIC_HEALTH_MASK_SHIFT_ROUTE_UNHEALTHY as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_SHIFT_ROUTE_UNHEALTHY = 4
// GPU_FABRIC_HEALTH_MASK_WIDTH_ROUTE_UNHEALTHY as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_WIDTH_ROUTE_UNHEALTHY = 3
// GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_NOT_SUPPORTED as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_NOT_SUPPORTED = 0
// GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_TRUE as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_TRUE = 1
// GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_FALSE as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_FALSE = 2
// GPU_FABRIC_HEALTH_MASK_SHIFT_ACCESS_TIMEOUT_RECOVERY as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_SHIFT_ACCESS_TIMEOUT_RECOVERY = 6
// GPU_FABRIC_HEALTH_MASK_WIDTH_ACCESS_TIMEOUT_RECOVERY as defined in nvml/nvml.h
GPU_FABRIC_HEALTH_MASK_WIDTH_ACCESS_TIMEOUT_RECOVERY = 3
// INIT_FLAG_NO_GPUS as defined in nvml/nvml.h
INIT_FLAG_NO_GPUS = 1
// INIT_FLAG_NO_ATTACH as defined in nvml/nvml.h
@@ -738,6 +1000,22 @@ const (
AFFINITY_SCOPE_NODE = 0
// AFFINITY_SCOPE_SOCKET as defined in nvml/nvml.h
AFFINITY_SCOPE_SOCKET = 1
// NVLINK_BER_MANTISSA_SHIFT as defined in nvml/nvml.h
NVLINK_BER_MANTISSA_SHIFT = 8
// NVLINK_BER_MANTISSA_WIDTH as defined in nvml/nvml.h
NVLINK_BER_MANTISSA_WIDTH = 15
// NVLINK_BER_EXP_SHIFT as defined in nvml/nvml.h
NVLINK_BER_EXP_SHIFT = 0
// NVLINK_BER_EXP_WIDTH as defined in nvml/nvml.h
NVLINK_BER_EXP_WIDTH = 255
// NVLINK_STATE_INACTIVE as defined in nvml/nvml.h
NVLINK_STATE_INACTIVE = 0
// NVLINK_STATE_ACTIVE as defined in nvml/nvml.h
NVLINK_STATE_ACTIVE = 1
// NVLINK_STATE_SLEEP as defined in nvml/nvml.h
NVLINK_STATE_SLEEP = 2
// NVLINK_TOTAL_SUPPORTED_BW_MODES as defined in nvml/nvml.h
NVLINK_TOTAL_SUPPORTED_BW_MODES = 23
// DEVICE_MIG_DISABLE as defined in nvml/nvml.h
DEVICE_MIG_DISABLE = 0
// DEVICE_MIG_ENABLE as defined in nvml/nvml.h
@@ -762,10 +1040,30 @@ const (
GPU_INSTANCE_PROFILE_2_SLICE_REV1 = 8
// GPU_INSTANCE_PROFILE_1_SLICE_REV2 as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_1_SLICE_REV2 = 9
// GPU_INSTANCE_PROFILE_1_SLICE_GFX as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_1_SLICE_GFX = 10
// GPU_INSTANCE_PROFILE_2_SLICE_GFX as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_2_SLICE_GFX = 11
// GPU_INSTANCE_PROFILE_4_SLICE_GFX as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_4_SLICE_GFX = 12
// GPU_INSTANCE_PROFILE_1_SLICE_NO_ME as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_1_SLICE_NO_ME = 13
// GPU_INSTANCE_PROFILE_2_SLICE_NO_ME as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_2_SLICE_NO_ME = 14
// GPU_INSTANCE_PROFILE_1_SLICE_ALL_ME as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_1_SLICE_ALL_ME = 15
// GPU_INSTANCE_PROFILE_2_SLICE_ALL_ME as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_2_SLICE_ALL_ME = 16
// GPU_INSTANCE_PROFILE_COUNT as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_COUNT = 10
GPU_INSTANCE_PROFILE_COUNT = 17
// GPU_INSTANCE_PROFILE_CAPS_P2P as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_CAPS_P2P = 1
// GPU_INTSTANCE_PROFILE_CAPS_P2P as defined in nvml/nvml.h
GPU_INTSTANCE_PROFILE_CAPS_P2P = 1
// GPU_INSTANCE_PROFILE_CAPS_GFX as defined in nvml/nvml.h
GPU_INSTANCE_PROFILE_CAPS_GFX = 2
// COMPUTE_INSTANCE_PROFILE_CAPS_GFX as defined in nvml/nvml.h
COMPUTE_INSTANCE_PROFILE_CAPS_GFX = 1
// COMPUTE_INSTANCE_PROFILE_1_SLICE as defined in nvml/nvml.h
COMPUTE_INSTANCE_PROFILE_1_SLICE = 0
// COMPUTE_INSTANCE_PROFILE_2_SLICE as defined in nvml/nvml.h
@@ -792,16 +1090,24 @@ const (
GPM_METRICS_GET_VERSION = 1
// GPM_SUPPORT_VERSION as defined in nvml/nvml.h
GPM_SUPPORT_VERSION = 1
// NVLINK_POWER_STATE_HIGH_SPEED as defined in nvml/nvml.h
NVLINK_POWER_STATE_HIGH_SPEED = 0
// NVLINK_POWER_STATE_LOW as defined in nvml/nvml.h
NVLINK_POWER_STATE_LOW = 1
// NVLINK_LOW_POWER_THRESHOLD_MIN as defined in nvml/nvml.h
NVLINK_LOW_POWER_THRESHOLD_MIN = 1
// NVLINK_LOW_POWER_THRESHOLD_MAX as defined in nvml/nvml.h
NVLINK_LOW_POWER_THRESHOLD_MAX = 8191
// NVLINK_LOW_POWER_THRESHOLD_RESET as defined in nvml/nvml.h
NVLINK_LOW_POWER_THRESHOLD_RESET = 4294967295
// DEV_CAP_EGM as defined in nvml/nvml.h
DEV_CAP_EGM = 1
// WORKLOAD_POWER_MAX_PROFILES as defined in nvml/nvml.h
WORKLOAD_POWER_MAX_PROFILES = 255
// POWER_SMOOTHING_MAX_NUM_PROFILES as defined in nvml/nvml.h
POWER_SMOOTHING_MAX_NUM_PROFILES = 5
// POWER_SMOOTHING_NUM_PROFILE_PARAMS as defined in nvml/nvml.h
POWER_SMOOTHING_NUM_PROFILE_PARAMS = 4
// POWER_SMOOTHING_ADMIN_OVERRIDE_NOT_SET as defined in nvml/nvml.h
POWER_SMOOTHING_ADMIN_OVERRIDE_NOT_SET = 4294967295
// POWER_SMOOTHING_PROFILE_PARAM_PERCENT_TMP_FLOOR as defined in nvml/nvml.h
POWER_SMOOTHING_PROFILE_PARAM_PERCENT_TMP_FLOOR = 0
// POWER_SMOOTHING_PROFILE_PARAM_RAMP_UP_RATE as defined in nvml/nvml.h
POWER_SMOOTHING_PROFILE_PARAM_RAMP_UP_RATE = 1
// POWER_SMOOTHING_PROFILE_PARAM_RAMP_DOWN_RATE as defined in nvml/nvml.h
POWER_SMOOTHING_PROFILE_PARAM_RAMP_DOWN_RATE = 2
// POWER_SMOOTHING_PROFILE_PARAM_RAMP_DOWN_HYSTERESIS as defined in nvml/nvml.h
POWER_SMOOTHING_PROFILE_PARAM_RAMP_DOWN_HYSTERESIS = 3
)
// BridgeChipType as declared in nvml/nvml.h
@@ -960,7 +1266,8 @@ const (
VALUE_TYPE_UNSIGNED_LONG_LONG ValueType = 3
VALUE_TYPE_SIGNED_LONG_LONG ValueType = 4
VALUE_TYPE_SIGNED_INT ValueType = 5
VALUE_TYPE_COUNT ValueType = 6
VALUE_TYPE_UNSIGNED_SHORT ValueType = 6
VALUE_TYPE_COUNT ValueType = 7
)
// PerfPolicyType as declared in nvml/nvml.h
@@ -979,6 +1286,29 @@ const (
PERF_POLICY_COUNT PerfPolicyType = 12
)
// CoolerControl as declared in nvml/nvml.h
type CoolerControl int32
// CoolerControl enumeration from nvml/nvml.h
const (
THERMAL_COOLER_SIGNAL_NONE CoolerControl = iota
THERMAL_COOLER_SIGNAL_TOGGLE CoolerControl = 1
THERMAL_COOLER_SIGNAL_VARIABLE CoolerControl = 2
THERMAL_COOLER_SIGNAL_COUNT CoolerControl = 3
)
// CoolerTarget as declared in nvml/nvml.h
type CoolerTarget int32
// CoolerTarget enumeration from nvml/nvml.h
const (
THERMAL_COOLER_TARGET_NONE CoolerTarget = 1
THERMAL_COOLER_TARGET_GPU CoolerTarget = 2
THERMAL_COOLER_TARGET_MEMORY CoolerTarget = 4
THERMAL_COOLER_TARGET_POWER_SUPPLY CoolerTarget = 8
THERMAL_COOLER_TARGET_GPU_RELATED CoolerTarget = 14
)
// EnableState as declared in nvml/nvml.h
type EnableState int32
@@ -1026,7 +1356,8 @@ const (
TEMPERATURE_THRESHOLD_ACOUSTIC_MIN TemperatureThresholds = 4
TEMPERATURE_THRESHOLD_ACOUSTIC_CURR TemperatureThresholds = 5
TEMPERATURE_THRESHOLD_ACOUSTIC_MAX TemperatureThresholds = 6
TEMPERATURE_THRESHOLD_COUNT TemperatureThresholds = 7
TEMPERATURE_THRESHOLD_GPS_CURR TemperatureThresholds = 7
TEMPERATURE_THRESHOLD_COUNT TemperatureThresholds = 8
)
// TemperatureSensors as declared in nvml/nvml.h
@@ -1060,6 +1391,21 @@ const (
MEMORY_ERROR_TYPE_COUNT MemoryErrorType = 2
)
// NvlinkVersion as declared in nvml/nvml.h
type NvlinkVersion int32
// NvlinkVersion enumeration from nvml/nvml.h
const (
NVLINK_VERSION_INVALID NvlinkVersion = iota
NVLINK_VERSION_1_0 NvlinkVersion = 1
NVLINK_VERSION_2_0 NvlinkVersion = 2
NVLINK_VERSION_2_2 NvlinkVersion = 3
NVLINK_VERSION_3_0 NvlinkVersion = 4
NVLINK_VERSION_3_1 NvlinkVersion = 5
NVLINK_VERSION_4_0 NvlinkVersion = 6
NVLINK_VERSION_5_0 NvlinkVersion = 7
)
// EccCounterType as declared in nvml/nvml.h
type EccCounterType int32
@@ -1101,6 +1447,7 @@ type DriverModel int32
const (
DRIVER_WDDM DriverModel = iota
DRIVER_WDM DriverModel = 1
DRIVER_MCDM DriverModel = 2
)
// Pstates as declared in nvml/nvml.h
@@ -1145,7 +1492,8 @@ const (
INFOROM_OEM InforomObject = iota
INFOROM_ECC InforomObject = 1
INFOROM_POWER InforomObject = 2
INFOROM_COUNT InforomObject = 3
INFOROM_DEN InforomObject = 3
INFOROM_COUNT InforomObject = 4
)
// Return as declared in nvml/nvml.h
@@ -1223,6 +1571,17 @@ const (
RESTRICTED_API_COUNT RestrictedAPI = 2
)
// GpuUtilizationDomainId as declared in nvml/nvml.h
type GpuUtilizationDomainId int32
// GpuUtilizationDomainId enumeration from nvml/nvml.h
const (
GPU_UTILIZATION_DOMAIN_GPU GpuUtilizationDomainId = iota
GPU_UTILIZATION_DOMAIN_FB GpuUtilizationDomainId = 1
GPU_UTILIZATION_DOMAIN_VID GpuUtilizationDomainId = 2
GPU_UTILIZATION_DOMAIN_BUS GpuUtilizationDomainId = 3
)
// GpuVirtualizationMode as declared in nvml/nvml.h
type GpuVirtualizationMode int32
@@ -1281,7 +1640,8 @@ type VgpuDriverCapability int32
// VgpuDriverCapability enumeration from nvml/nvml.h
const (
VGPU_DRIVER_CAP_HETEROGENEOUS_MULTI_VGPU VgpuDriverCapability = iota
VGPU_DRIVER_CAP_COUNT VgpuDriverCapability = 1
VGPU_DRIVER_CAP_WARM_UPDATE VgpuDriverCapability = 1
VGPU_DRIVER_CAP_COUNT VgpuDriverCapability = 2
)
// DeviceVgpuCapability as declared in nvml/nvml.h
@@ -1297,18 +1657,23 @@ const (
DEVICE_VGPU_CAP_DEVICE_STREAMING DeviceVgpuCapability = 5
DEVICE_VGPU_CAP_MINI_QUARTER_GPU DeviceVgpuCapability = 6
DEVICE_VGPU_CAP_COMPUTE_MEDIA_ENGINE_GPU DeviceVgpuCapability = 7
DEVICE_VGPU_CAP_COUNT DeviceVgpuCapability = 8
DEVICE_VGPU_CAP_WARM_UPDATE DeviceVgpuCapability = 8
DEVICE_VGPU_CAP_HOMOGENEOUS_PLACEMENTS DeviceVgpuCapability = 9
DEVICE_VGPU_CAP_MIG_TIMESLICING_SUPPORTED DeviceVgpuCapability = 10
DEVICE_VGPU_CAP_MIG_TIMESLICING_ENABLED DeviceVgpuCapability = 11
DEVICE_VGPU_CAP_COUNT DeviceVgpuCapability = 12
)
// GpuUtilizationDomainId as declared in nvml/nvml.h
type GpuUtilizationDomainId int32
// DeviceGpuRecoveryAction as declared in nvml/nvml.h
type DeviceGpuRecoveryAction int32
// GpuUtilizationDomainId enumeration from nvml/nvml.h
// DeviceGpuRecoveryAction enumeration from nvml/nvml.h
const (
GPU_UTILIZATION_DOMAIN_GPU GpuUtilizationDomainId = iota
GPU_UTILIZATION_DOMAIN_FB GpuUtilizationDomainId = 1
GPU_UTILIZATION_DOMAIN_VID GpuUtilizationDomainId = 2
GPU_UTILIZATION_DOMAIN_BUS GpuUtilizationDomainId = 3
GPU_RECOVERY_ACTION_NONE DeviceGpuRecoveryAction = iota
GPU_RECOVERY_ACTION_GPU_RESET DeviceGpuRecoveryAction = 1
GPU_RECOVERY_ACTION_NODE_REBOOT DeviceGpuRecoveryAction = 2
GPU_RECOVERY_ACTION_DRAIN_P2P DeviceGpuRecoveryAction = 3
GPU_RECOVERY_ACTION_DRAIN_AND_RESET DeviceGpuRecoveryAction = 4
)
// FanState as declared in nvml/nvml.h
@@ -1447,6 +1812,16 @@ const (
THERMAL_CONTROLLER_UNKNOWN ThermalController = -1
)
// UUIDType as declared in nvml/nvml.h
type UUIDType int32
// UUIDType enumeration from nvml/nvml.h
const (
UUID_TYPE_NONE UUIDType = iota
UUID_TYPE_ASCII UUIDType = 1
UUID_TYPE_BINARY UUIDType = 2
)
// GridLicenseFeatureCode as declared in nvml/nvml.h
type GridLicenseFeatureCode int32
@@ -1465,74 +1840,208 @@ type GpmMetricId int32
// GpmMetricId enumeration from nvml/nvml.h
const (
GPM_METRIC_GRAPHICS_UTIL GpmMetricId = 1
GPM_METRIC_SM_UTIL GpmMetricId = 2
GPM_METRIC_SM_OCCUPANCY GpmMetricId = 3
GPM_METRIC_INTEGER_UTIL GpmMetricId = 4
GPM_METRIC_ANY_TENSOR_UTIL GpmMetricId = 5
GPM_METRIC_DFMA_TENSOR_UTIL GpmMetricId = 6
GPM_METRIC_HMMA_TENSOR_UTIL GpmMetricId = 7
GPM_METRIC_IMMA_TENSOR_UTIL GpmMetricId = 9
GPM_METRIC_DRAM_BW_UTIL GpmMetricId = 10
GPM_METRIC_FP64_UTIL GpmMetricId = 11
GPM_METRIC_FP32_UTIL GpmMetricId = 12
GPM_METRIC_FP16_UTIL GpmMetricId = 13
GPM_METRIC_PCIE_TX_PER_SEC GpmMetricId = 20
GPM_METRIC_PCIE_RX_PER_SEC GpmMetricId = 21
GPM_METRIC_NVDEC_0_UTIL GpmMetricId = 30
GPM_METRIC_NVDEC_1_UTIL GpmMetricId = 31
GPM_METRIC_NVDEC_2_UTIL GpmMetricId = 32
GPM_METRIC_NVDEC_3_UTIL GpmMetricId = 33
GPM_METRIC_NVDEC_4_UTIL GpmMetricId = 34
GPM_METRIC_NVDEC_5_UTIL GpmMetricId = 35
GPM_METRIC_NVDEC_6_UTIL GpmMetricId = 36
GPM_METRIC_NVDEC_7_UTIL GpmMetricId = 37
GPM_METRIC_NVJPG_0_UTIL GpmMetricId = 40
GPM_METRIC_NVJPG_1_UTIL GpmMetricId = 41
GPM_METRIC_NVJPG_2_UTIL GpmMetricId = 42
GPM_METRIC_NVJPG_3_UTIL GpmMetricId = 43
GPM_METRIC_NVJPG_4_UTIL GpmMetricId = 44
GPM_METRIC_NVJPG_5_UTIL GpmMetricId = 45
GPM_METRIC_NVJPG_6_UTIL GpmMetricId = 46
GPM_METRIC_NVJPG_7_UTIL GpmMetricId = 47
GPM_METRIC_NVOFA_0_UTIL GpmMetricId = 50
GPM_METRIC_NVLINK_TOTAL_RX_PER_SEC GpmMetricId = 60
GPM_METRIC_NVLINK_TOTAL_TX_PER_SEC GpmMetricId = 61
GPM_METRIC_NVLINK_L0_RX_PER_SEC GpmMetricId = 62
GPM_METRIC_NVLINK_L0_TX_PER_SEC GpmMetricId = 63
GPM_METRIC_NVLINK_L1_RX_PER_SEC GpmMetricId = 64
GPM_METRIC_NVLINK_L1_TX_PER_SEC GpmMetricId = 65
GPM_METRIC_NVLINK_L2_RX_PER_SEC GpmMetricId = 66
GPM_METRIC_NVLINK_L2_TX_PER_SEC GpmMetricId = 67
GPM_METRIC_NVLINK_L3_RX_PER_SEC GpmMetricId = 68
GPM_METRIC_NVLINK_L3_TX_PER_SEC GpmMetricId = 69
GPM_METRIC_NVLINK_L4_RX_PER_SEC GpmMetricId = 70
GPM_METRIC_NVLINK_L4_TX_PER_SEC GpmMetricId = 71
GPM_METRIC_NVLINK_L5_RX_PER_SEC GpmMetricId = 72
GPM_METRIC_NVLINK_L5_TX_PER_SEC GpmMetricId = 73
GPM_METRIC_NVLINK_L6_RX_PER_SEC GpmMetricId = 74
GPM_METRIC_NVLINK_L6_TX_PER_SEC GpmMetricId = 75
GPM_METRIC_NVLINK_L7_RX_PER_SEC GpmMetricId = 76
GPM_METRIC_NVLINK_L7_TX_PER_SEC GpmMetricId = 77
GPM_METRIC_NVLINK_L8_RX_PER_SEC GpmMetricId = 78
GPM_METRIC_NVLINK_L8_TX_PER_SEC GpmMetricId = 79
GPM_METRIC_NVLINK_L9_RX_PER_SEC GpmMetricId = 80
GPM_METRIC_NVLINK_L9_TX_PER_SEC GpmMetricId = 81
GPM_METRIC_NVLINK_L10_RX_PER_SEC GpmMetricId = 82
GPM_METRIC_NVLINK_L10_TX_PER_SEC GpmMetricId = 83
GPM_METRIC_NVLINK_L11_RX_PER_SEC GpmMetricId = 84
GPM_METRIC_NVLINK_L11_TX_PER_SEC GpmMetricId = 85
GPM_METRIC_NVLINK_L12_RX_PER_SEC GpmMetricId = 86
GPM_METRIC_NVLINK_L12_TX_PER_SEC GpmMetricId = 87
GPM_METRIC_NVLINK_L13_RX_PER_SEC GpmMetricId = 88
GPM_METRIC_NVLINK_L13_TX_PER_SEC GpmMetricId = 89
GPM_METRIC_NVLINK_L14_RX_PER_SEC GpmMetricId = 90
GPM_METRIC_NVLINK_L14_TX_PER_SEC GpmMetricId = 91
GPM_METRIC_NVLINK_L15_RX_PER_SEC GpmMetricId = 92
GPM_METRIC_NVLINK_L15_TX_PER_SEC GpmMetricId = 93
GPM_METRIC_NVLINK_L16_RX_PER_SEC GpmMetricId = 94
GPM_METRIC_NVLINK_L16_TX_PER_SEC GpmMetricId = 95
GPM_METRIC_NVLINK_L17_RX_PER_SEC GpmMetricId = 96
GPM_METRIC_NVLINK_L17_TX_PER_SEC GpmMetricId = 97
GPM_METRIC_MAX GpmMetricId = 98
GPM_METRIC_GRAPHICS_UTIL GpmMetricId = 1
GPM_METRIC_SM_UTIL GpmMetricId = 2
GPM_METRIC_SM_OCCUPANCY GpmMetricId = 3
GPM_METRIC_INTEGER_UTIL GpmMetricId = 4
GPM_METRIC_ANY_TENSOR_UTIL GpmMetricId = 5
GPM_METRIC_DFMA_TENSOR_UTIL GpmMetricId = 6
GPM_METRIC_HMMA_TENSOR_UTIL GpmMetricId = 7
GPM_METRIC_IMMA_TENSOR_UTIL GpmMetricId = 9
GPM_METRIC_DRAM_BW_UTIL GpmMetricId = 10
GPM_METRIC_FP64_UTIL GpmMetricId = 11
GPM_METRIC_FP32_UTIL GpmMetricId = 12
GPM_METRIC_FP16_UTIL GpmMetricId = 13
GPM_METRIC_PCIE_TX_PER_SEC GpmMetricId = 20
GPM_METRIC_PCIE_RX_PER_SEC GpmMetricId = 21
GPM_METRIC_NVDEC_0_UTIL GpmMetricId = 30
GPM_METRIC_NVDEC_1_UTIL GpmMetricId = 31
GPM_METRIC_NVDEC_2_UTIL GpmMetricId = 32
GPM_METRIC_NVDEC_3_UTIL GpmMetricId = 33
GPM_METRIC_NVDEC_4_UTIL GpmMetricId = 34
GPM_METRIC_NVDEC_5_UTIL GpmMetricId = 35
GPM_METRIC_NVDEC_6_UTIL GpmMetricId = 36
GPM_METRIC_NVDEC_7_UTIL GpmMetricId = 37
GPM_METRIC_NVJPG_0_UTIL GpmMetricId = 40
GPM_METRIC_NVJPG_1_UTIL GpmMetricId = 41
GPM_METRIC_NVJPG_2_UTIL GpmMetricId = 42
GPM_METRIC_NVJPG_3_UTIL GpmMetricId = 43
GPM_METRIC_NVJPG_4_UTIL GpmMetricId = 44
GPM_METRIC_NVJPG_5_UTIL GpmMetricId = 45
GPM_METRIC_NVJPG_6_UTIL GpmMetricId = 46
GPM_METRIC_NVJPG_7_UTIL GpmMetricId = 47
GPM_METRIC_NVOFA_0_UTIL GpmMetricId = 50
GPM_METRIC_NVOFA_1_UTIL GpmMetricId = 51
GPM_METRIC_NVLINK_TOTAL_RX_PER_SEC GpmMetricId = 60
GPM_METRIC_NVLINK_TOTAL_TX_PER_SEC GpmMetricId = 61
GPM_METRIC_NVLINK_L0_RX_PER_SEC GpmMetricId = 62
GPM_METRIC_NVLINK_L0_TX_PER_SEC GpmMetricId = 63
GPM_METRIC_NVLINK_L1_RX_PER_SEC GpmMetricId = 64
GPM_METRIC_NVLINK_L1_TX_PER_SEC GpmMetricId = 65
GPM_METRIC_NVLINK_L2_RX_PER_SEC GpmMetricId = 66
GPM_METRIC_NVLINK_L2_TX_PER_SEC GpmMetricId = 67
GPM_METRIC_NVLINK_L3_RX_PER_SEC GpmMetricId = 68
GPM_METRIC_NVLINK_L3_TX_PER_SEC GpmMetricId = 69
GPM_METRIC_NVLINK_L4_RX_PER_SEC GpmMetricId = 70
GPM_METRIC_NVLINK_L4_TX_PER_SEC GpmMetricId = 71
GPM_METRIC_NVLINK_L5_RX_PER_SEC GpmMetricId = 72
GPM_METRIC_NVLINK_L5_TX_PER_SEC GpmMetricId = 73
GPM_METRIC_NVLINK_L6_RX_PER_SEC GpmMetricId = 74
GPM_METRIC_NVLINK_L6_TX_PER_SEC GpmMetricId = 75
GPM_METRIC_NVLINK_L7_RX_PER_SEC GpmMetricId = 76
GPM_METRIC_NVLINK_L7_TX_PER_SEC GpmMetricId = 77
GPM_METRIC_NVLINK_L8_RX_PER_SEC GpmMetricId = 78
GPM_METRIC_NVLINK_L8_TX_PER_SEC GpmMetricId = 79
GPM_METRIC_NVLINK_L9_RX_PER_SEC GpmMetricId = 80
GPM_METRIC_NVLINK_L9_TX_PER_SEC GpmMetricId = 81
GPM_METRIC_NVLINK_L10_RX_PER_SEC GpmMetricId = 82
GPM_METRIC_NVLINK_L10_TX_PER_SEC GpmMetricId = 83
GPM_METRIC_NVLINK_L11_RX_PER_SEC GpmMetricId = 84
GPM_METRIC_NVLINK_L11_TX_PER_SEC GpmMetricId = 85
GPM_METRIC_NVLINK_L12_RX_PER_SEC GpmMetricId = 86
GPM_METRIC_NVLINK_L12_TX_PER_SEC GpmMetricId = 87
GPM_METRIC_NVLINK_L13_RX_PER_SEC GpmMetricId = 88
GPM_METRIC_NVLINK_L13_TX_PER_SEC GpmMetricId = 89
GPM_METRIC_NVLINK_L14_RX_PER_SEC GpmMetricId = 90
GPM_METRIC_NVLINK_L14_TX_PER_SEC GpmMetricId = 91
GPM_METRIC_NVLINK_L15_RX_PER_SEC GpmMetricId = 92
GPM_METRIC_NVLINK_L15_TX_PER_SEC GpmMetricId = 93
GPM_METRIC_NVLINK_L16_RX_PER_SEC GpmMetricId = 94
GPM_METRIC_NVLINK_L16_TX_PER_SEC GpmMetricId = 95
GPM_METRIC_NVLINK_L17_RX_PER_SEC GpmMetricId = 96
GPM_METRIC_NVLINK_L17_TX_PER_SEC GpmMetricId = 97
GPM_METRIC_C2C_TOTAL_TX_PER_SEC GpmMetricId = 100
GPM_METRIC_C2C_TOTAL_RX_PER_SEC GpmMetricId = 101
GPM_METRIC_C2C_DATA_TX_PER_SEC GpmMetricId = 102
GPM_METRIC_C2C_DATA_RX_PER_SEC GpmMetricId = 103
GPM_METRIC_C2C_LINK0_TOTAL_TX_PER_SEC GpmMetricId = 104
GPM_METRIC_C2C_LINK0_TOTAL_RX_PER_SEC GpmMetricId = 105
GPM_METRIC_C2C_LINK0_DATA_TX_PER_SEC GpmMetricId = 106
GPM_METRIC_C2C_LINK0_DATA_RX_PER_SEC GpmMetricId = 107
GPM_METRIC_C2C_LINK1_TOTAL_TX_PER_SEC GpmMetricId = 108
GPM_METRIC_C2C_LINK1_TOTAL_RX_PER_SEC GpmMetricId = 109
GPM_METRIC_C2C_LINK1_DATA_TX_PER_SEC GpmMetricId = 110
GPM_METRIC_C2C_LINK1_DATA_RX_PER_SEC GpmMetricId = 111
GPM_METRIC_C2C_LINK2_TOTAL_TX_PER_SEC GpmMetricId = 112
GPM_METRIC_C2C_LINK2_TOTAL_RX_PER_SEC GpmMetricId = 113
GPM_METRIC_C2C_LINK2_DATA_TX_PER_SEC GpmMetricId = 114
GPM_METRIC_C2C_LINK2_DATA_RX_PER_SEC GpmMetricId = 115
GPM_METRIC_C2C_LINK3_TOTAL_TX_PER_SEC GpmMetricId = 116
GPM_METRIC_C2C_LINK3_TOTAL_RX_PER_SEC GpmMetricId = 117
GPM_METRIC_C2C_LINK3_DATA_TX_PER_SEC GpmMetricId = 118
GPM_METRIC_C2C_LINK3_DATA_RX_PER_SEC GpmMetricId = 119
GPM_METRIC_C2C_LINK4_TOTAL_TX_PER_SEC GpmMetricId = 120
GPM_METRIC_C2C_LINK4_TOTAL_RX_PER_SEC GpmMetricId = 121
GPM_METRIC_C2C_LINK4_DATA_TX_PER_SEC GpmMetricId = 122
GPM_METRIC_C2C_LINK4_DATA_RX_PER_SEC GpmMetricId = 123
GPM_METRIC_C2C_LINK5_TOTAL_TX_PER_SEC GpmMetricId = 124
GPM_METRIC_C2C_LINK5_TOTAL_RX_PER_SEC GpmMetricId = 125
GPM_METRIC_C2C_LINK5_DATA_TX_PER_SEC GpmMetricId = 126
GPM_METRIC_C2C_LINK5_DATA_RX_PER_SEC GpmMetricId = 127
GPM_METRIC_C2C_LINK6_TOTAL_TX_PER_SEC GpmMetricId = 128
GPM_METRIC_C2C_LINK6_TOTAL_RX_PER_SEC GpmMetricId = 129
GPM_METRIC_C2C_LINK6_DATA_TX_PER_SEC GpmMetricId = 130
GPM_METRIC_C2C_LINK6_DATA_RX_PER_SEC GpmMetricId = 131
GPM_METRIC_C2C_LINK7_TOTAL_TX_PER_SEC GpmMetricId = 132
GPM_METRIC_C2C_LINK7_TOTAL_RX_PER_SEC GpmMetricId = 133
GPM_METRIC_C2C_LINK7_DATA_TX_PER_SEC GpmMetricId = 134
GPM_METRIC_C2C_LINK7_DATA_RX_PER_SEC GpmMetricId = 135
GPM_METRIC_C2C_LINK8_TOTAL_TX_PER_SEC GpmMetricId = 136
GPM_METRIC_C2C_LINK8_TOTAL_RX_PER_SEC GpmMetricId = 137
GPM_METRIC_C2C_LINK8_DATA_TX_PER_SEC GpmMetricId = 138
GPM_METRIC_C2C_LINK8_DATA_RX_PER_SEC GpmMetricId = 139
GPM_METRIC_C2C_LINK9_TOTAL_TX_PER_SEC GpmMetricId = 140
GPM_METRIC_C2C_LINK9_TOTAL_RX_PER_SEC GpmMetricId = 141
GPM_METRIC_C2C_LINK9_DATA_TX_PER_SEC GpmMetricId = 142
GPM_METRIC_C2C_LINK9_DATA_RX_PER_SEC GpmMetricId = 143
GPM_METRIC_C2C_LINK10_TOTAL_TX_PER_SEC GpmMetricId = 144
GPM_METRIC_C2C_LINK10_TOTAL_RX_PER_SEC GpmMetricId = 145
GPM_METRIC_C2C_LINK10_DATA_TX_PER_SEC GpmMetricId = 146
GPM_METRIC_C2C_LINK10_DATA_RX_PER_SEC GpmMetricId = 147
GPM_METRIC_C2C_LINK11_TOTAL_TX_PER_SEC GpmMetricId = 148
GPM_METRIC_C2C_LINK11_TOTAL_RX_PER_SEC GpmMetricId = 149
GPM_METRIC_C2C_LINK11_DATA_TX_PER_SEC GpmMetricId = 150
GPM_METRIC_C2C_LINK11_DATA_RX_PER_SEC GpmMetricId = 151
GPM_METRIC_C2C_LINK12_TOTAL_TX_PER_SEC GpmMetricId = 152
GPM_METRIC_C2C_LINK12_TOTAL_RX_PER_SEC GpmMetricId = 153
GPM_METRIC_C2C_LINK12_DATA_TX_PER_SEC GpmMetricId = 154
GPM_METRIC_C2C_LINK12_DATA_RX_PER_SEC GpmMetricId = 155
GPM_METRIC_C2C_LINK13_TOTAL_TX_PER_SEC GpmMetricId = 156
GPM_METRIC_C2C_LINK13_TOTAL_RX_PER_SEC GpmMetricId = 157
GPM_METRIC_C2C_LINK13_DATA_TX_PER_SEC GpmMetricId = 158
GPM_METRIC_C2C_LINK13_DATA_RX_PER_SEC GpmMetricId = 159
GPM_METRIC_HOSTMEM_CACHE_HIT GpmMetricId = 160
GPM_METRIC_HOSTMEM_CACHE_MISS GpmMetricId = 161
GPM_METRIC_PEERMEM_CACHE_HIT GpmMetricId = 162
GPM_METRIC_PEERMEM_CACHE_MISS GpmMetricId = 163
GPM_METRIC_DRAM_CACHE_HIT GpmMetricId = 164
GPM_METRIC_DRAM_CACHE_MISS GpmMetricId = 165
GPM_METRIC_NVENC_0_UTIL GpmMetricId = 166
GPM_METRIC_NVENC_1_UTIL GpmMetricId = 167
GPM_METRIC_NVENC_2_UTIL GpmMetricId = 168
GPM_METRIC_NVENC_3_UTIL GpmMetricId = 169
GPM_METRIC_GR0_CTXSW_CYCLES_ELAPSED GpmMetricId = 170
GPM_METRIC_GR0_CTXSW_CYCLES_ACTIVE GpmMetricId = 171
GPM_METRIC_GR0_CTXSW_REQUESTS GpmMetricId = 172
GPM_METRIC_GR0_CTXSW_CYCLES_PER_REQ GpmMetricId = 173
GPM_METRIC_GR0_CTXSW_ACTIVE_PCT GpmMetricId = 174
GPM_METRIC_GR1_CTXSW_CYCLES_ELAPSED GpmMetricId = 175
GPM_METRIC_GR1_CTXSW_CYCLES_ACTIVE GpmMetricId = 176
GPM_METRIC_GR1_CTXSW_REQUESTS GpmMetricId = 177
GPM_METRIC_GR1_CTXSW_CYCLES_PER_REQ GpmMetricId = 178
GPM_METRIC_GR1_CTXSW_ACTIVE_PCT GpmMetricId = 179
GPM_METRIC_GR2_CTXSW_CYCLES_ELAPSED GpmMetricId = 180
GPM_METRIC_GR2_CTXSW_CYCLES_ACTIVE GpmMetricId = 181
GPM_METRIC_GR2_CTXSW_REQUESTS GpmMetricId = 182
GPM_METRIC_GR2_CTXSW_CYCLES_PER_REQ GpmMetricId = 183
GPM_METRIC_GR2_CTXSW_ACTIVE_PCT GpmMetricId = 184
GPM_METRIC_GR3_CTXSW_CYCLES_ELAPSED GpmMetricId = 185
GPM_METRIC_GR3_CTXSW_CYCLES_ACTIVE GpmMetricId = 186
GPM_METRIC_GR3_CTXSW_REQUESTS GpmMetricId = 187
GPM_METRIC_GR3_CTXSW_CYCLES_PER_REQ GpmMetricId = 188
GPM_METRIC_GR3_CTXSW_ACTIVE_PCT GpmMetricId = 189
GPM_METRIC_GR4_CTXSW_CYCLES_ELAPSED GpmMetricId = 190
GPM_METRIC_GR4_CTXSW_CYCLES_ACTIVE GpmMetricId = 191
GPM_METRIC_GR4_CTXSW_REQUESTS GpmMetricId = 192
GPM_METRIC_GR4_CTXSW_CYCLES_PER_REQ GpmMetricId = 193
GPM_METRIC_GR4_CTXSW_ACTIVE_PCT GpmMetricId = 194
GPM_METRIC_GR5_CTXSW_CYCLES_ELAPSED GpmMetricId = 195
GPM_METRIC_GR5_CTXSW_CYCLES_ACTIVE GpmMetricId = 196
GPM_METRIC_GR5_CTXSW_REQUESTS GpmMetricId = 197
GPM_METRIC_GR5_CTXSW_CYCLES_PER_REQ GpmMetricId = 198
GPM_METRIC_GR5_CTXSW_ACTIVE_PCT GpmMetricId = 199
GPM_METRIC_GR6_CTXSW_CYCLES_ELAPSED GpmMetricId = 200
GPM_METRIC_GR6_CTXSW_CYCLES_ACTIVE GpmMetricId = 201
GPM_METRIC_GR6_CTXSW_REQUESTS GpmMetricId = 202
GPM_METRIC_GR6_CTXSW_CYCLES_PER_REQ GpmMetricId = 203
GPM_METRIC_GR6_CTXSW_ACTIVE_PCT GpmMetricId = 204
GPM_METRIC_GR7_CTXSW_CYCLES_ELAPSED GpmMetricId = 205
GPM_METRIC_GR7_CTXSW_CYCLES_ACTIVE GpmMetricId = 206
GPM_METRIC_GR7_CTXSW_REQUESTS GpmMetricId = 207
GPM_METRIC_GR7_CTXSW_CYCLES_PER_REQ GpmMetricId = 208
GPM_METRIC_GR7_CTXSW_ACTIVE_PCT GpmMetricId = 209
GPM_METRIC_MAX GpmMetricId = 210
)
// PowerProfileType as declared in nvml/nvml.h
type PowerProfileType int32
// PowerProfileType enumeration from nvml/nvml.h
const (
POWER_PROFILE_MAX_P PowerProfileType = iota
POWER_PROFILE_MAX_Q PowerProfileType = 1
POWER_PROFILE_COMPUTE PowerProfileType = 2
POWER_PROFILE_MEMORY_BOUND PowerProfileType = 3
POWER_PROFILE_NETWORK PowerProfileType = 4
POWER_PROFILE_BALANCED PowerProfileType = 5
POWER_PROFILE_LLM_INFERENCE PowerProfileType = 6
POWER_PROFILE_LLM_TRAINING PowerProfileType = 7
POWER_PROFILE_RBM PowerProfileType = 8
POWER_PROFILE_DCPCIE PowerProfileType = 9
POWER_PROFILE_HMMA_SPARSE PowerProfileType = 10
POWER_PROFILE_HMMA_DENSE PowerProfileType = 11
POWER_PROFILE_SYNC_BALANCED PowerProfileType = 12
POWER_PROFILE_HPC PowerProfileType = 13
POWER_PROFILE_MIG PowerProfileType = 14
POWER_PROFILE_MAX PowerProfileType = 15
)

View File

@@ -68,16 +68,6 @@ type GpuInstanceInfo struct {
Placement GpuInstancePlacement
}
func (g GpuInstanceInfo) convert() nvmlGpuInstanceInfo {
out := nvmlGpuInstanceInfo{
Device: g.Device.(nvmlDevice),
Id: g.Id,
ProfileId: g.ProfileId,
Placement: g.Placement,
}
return out
}
func (g nvmlGpuInstanceInfo) convert() GpuInstanceInfo {
out := GpuInstanceInfo{
Device: g.Device,
@@ -97,17 +87,6 @@ type ComputeInstanceInfo struct {
Placement ComputeInstancePlacement
}
func (c ComputeInstanceInfo) convert() nvmlComputeInstanceInfo {
out := nvmlComputeInstanceInfo{
Device: c.Device.(nvmlDevice),
GpuInstance: c.GpuInstance.(nvmlGpuInstance),
Id: c.Id,
ProfileId: c.ProfileId,
Placement: c.Placement,
}
return out
}
func (c nvmlComputeInstanceInfo) convert() ComputeInstanceInfo {
out := ComputeInstanceInfo{
Device: c.Device,
@@ -147,6 +126,13 @@ func (l *library) DeviceGetHandleByUUID(uuid string) (Device, Return) {
return device, ret
}
// nvml.DeviceGetHandleByUUIDV()
func (l *library) DeviceGetHandleByUUIDV(uuid *UUID) (Device, Return) {
var device nvmlDevice
ret := nvmlDeviceGetHandleByUUIDV(uuid, &device)
return device, ret
}
// nvml.DeviceGetHandleByPciBusId()
func (l *library) DeviceGetHandleByPciBusId(pciBusId string) (Device, Return) {
var device nvmlDevice
@@ -2101,6 +2087,13 @@ func (handler GpuInstanceProfileInfoHandler) V2() (GpuInstanceProfileInfo_v2, Re
return info, ret
}
func (handler GpuInstanceProfileInfoHandler) V3() (GpuInstanceProfileInfo_v3, Return) {
var info GpuInstanceProfileInfo_v3
info.Version = STRUCT_VERSION(info, 3)
ret := nvmlDeviceGetGpuInstanceProfileInfoV(handler.device, uint32(handler.profile), (*GpuInstanceProfileInfo_v2)(unsafe.Pointer(&info)))
return info, ret
}
func (l *library) DeviceGetGpuInstanceProfileInfoV(device Device, profile int) GpuInstanceProfileInfoHandler {
return device.GetGpuInstanceProfileInfoV(profile)
}
@@ -2191,7 +2184,7 @@ func (device nvmlDevice) GetGpuInstances(info *GpuInstanceProfileInfo) ([]GpuIns
if info == nil {
return nil, ERROR_INVALID_ARGUMENT
}
var count uint32 = info.InstanceCount
var count = info.InstanceCount
gpuInstances := make([]nvmlGpuInstance, count)
ret := nvmlDeviceGetGpuInstances(device, info.Id, &gpuInstances[0], &count)
return convertSlice[nvmlGpuInstance, GpuInstance](gpuInstances[:count]), ret
@@ -2248,6 +2241,13 @@ func (handler ComputeInstanceProfileInfoHandler) V2() (ComputeInstanceProfileInf
return info, ret
}
func (handler ComputeInstanceProfileInfoHandler) V3() (ComputeInstanceProfileInfo_v3, Return) {
var info ComputeInstanceProfileInfo_v3
info.Version = STRUCT_VERSION(info, 3)
ret := nvmlGpuInstanceGetComputeInstanceProfileInfoV(handler.gpuInstance, uint32(handler.profile), uint32(handler.engProfile), (*ComputeInstanceProfileInfo_v2)(unsafe.Pointer(&info)))
return info, ret
}
func (l *library) GpuInstanceGetComputeInstanceProfileInfoV(gpuInstance GpuInstance, profile int, engProfile int) ComputeInstanceProfileInfoHandler {
return gpuInstance.GetComputeInstanceProfileInfoV(profile, engProfile)
}
@@ -2302,7 +2302,7 @@ func (gpuInstance nvmlGpuInstance) GetComputeInstances(info *ComputeInstanceProf
if info == nil {
return nil, ERROR_INVALID_ARGUMENT
}
var count uint32 = info.InstanceCount
var count = info.InstanceCount
computeInstances := make([]nvmlComputeInstance, count)
ret := nvmlGpuInstanceGetComputeInstances(gpuInstance, info.Id, &computeInstances[0], &count)
return convertSlice[nvmlComputeInstance, ComputeInstance](computeInstances[:count]), ret
@@ -3062,3 +3062,353 @@ func (device nvmlDevice) GetSramEccErrorStatus() (EccSramErrorStatus, Return) {
ret := nvmlDeviceGetSramEccErrorStatus(device, &status)
return status, ret
}
// nvml.DeviceGetClockOffsets()
func (l *library) DeviceGetClockOffsets(device Device) (ClockOffset, Return) {
return device.GetClockOffsets()
}
func (device nvmlDevice) GetClockOffsets() (ClockOffset, Return) {
var info ClockOffset
info.Version = STRUCT_VERSION(info, 1)
ret := nvmlDeviceGetClockOffsets(device, &info)
return info, ret
}
// nvml.DeviceSetClockOffsets()
func (l *library) DeviceSetClockOffsets(device Device, info ClockOffset) Return {
return device.SetClockOffsets(info)
}
func (device nvmlDevice) SetClockOffsets(info ClockOffset) Return {
return nvmlDeviceSetClockOffsets(device, &info)
}
// nvml.DeviceGetDriverModel_v2()
func (l *library) DeviceGetDriverModel_v2(device Device) (DriverModel, DriverModel, Return) {
return device.GetDriverModel_v2()
}
func (device nvmlDevice) GetDriverModel_v2() (DriverModel, DriverModel, Return) {
var current, pending DriverModel
ret := nvmlDeviceGetDriverModel_v2(device, &current, &pending)
return current, pending, ret
}
// nvml.DeviceGetCapabilities()
func (l *library) DeviceGetCapabilities(device Device) (DeviceCapabilities, Return) {
return device.GetCapabilities()
}
func (device nvmlDevice) GetCapabilities() (DeviceCapabilities, Return) {
var caps DeviceCapabilities
caps.Version = STRUCT_VERSION(caps, 1)
ret := nvmlDeviceGetCapabilities(device, &caps)
return caps, ret
}
// nvml.DeviceGetFanSpeedRPM()
func (l *library) DeviceGetFanSpeedRPM(device Device) (FanSpeedInfo, Return) {
return device.GetFanSpeedRPM()
}
func (device nvmlDevice) GetFanSpeedRPM() (FanSpeedInfo, Return) {
var fanSpeed FanSpeedInfo
fanSpeed.Version = STRUCT_VERSION(fanSpeed, 1)
ret := nvmlDeviceGetFanSpeedRPM(device, &fanSpeed)
return fanSpeed, ret
}
// nvml.DeviceGetCoolerInfo()
func (l *library) DeviceGetCoolerInfo(device Device) (CoolerInfo, Return) {
return device.GetCoolerInfo()
}
func (device nvmlDevice) GetCoolerInfo() (CoolerInfo, Return) {
var coolerInfo CoolerInfo
coolerInfo.Version = STRUCT_VERSION(coolerInfo, 1)
ret := nvmlDeviceGetCoolerInfo(device, &coolerInfo)
return coolerInfo, ret
}
// nvml.DeviceGetTemperatureV()
type TemperatureHandler struct {
device nvmlDevice
}
func (handler TemperatureHandler) V1() (Temperature, Return) {
var temperature Temperature
temperature.Version = STRUCT_VERSION(temperature, 1)
ret := nvmlDeviceGetTemperatureV(handler.device, &temperature)
return temperature, ret
}
func (l *library) DeviceGetTemperatureV(device Device) TemperatureHandler {
return device.GetTemperatureV()
}
func (device nvmlDevice) GetTemperatureV() TemperatureHandler {
return TemperatureHandler{device}
}
// nvml.DeviceGetMarginTemperature()
func (l *library) DeviceGetMarginTemperature(device Device) (MarginTemperature, Return) {
return device.GetMarginTemperature()
}
func (device nvmlDevice) GetMarginTemperature() (MarginTemperature, Return) {
var marginTemp MarginTemperature
marginTemp.Version = STRUCT_VERSION(marginTemp, 1)
ret := nvmlDeviceGetMarginTemperature(device, &marginTemp)
return marginTemp, ret
}
// nvml.DeviceGetPerformanceModes()
func (l *library) DeviceGetPerformanceModes(device Device) (DevicePerfModes, Return) {
return device.GetPerformanceModes()
}
func (device nvmlDevice) GetPerformanceModes() (DevicePerfModes, Return) {
var perfModes DevicePerfModes
perfModes.Version = STRUCT_VERSION(perfModes, 1)
ret := nvmlDeviceGetPerformanceModes(device, &perfModes)
return perfModes, ret
}
// nvml.DeviceGetCurrentClockFreqs()
func (l *library) DeviceGetCurrentClockFreqs(device Device) (DeviceCurrentClockFreqs, Return) {
return device.GetCurrentClockFreqs()
}
func (device nvmlDevice) GetCurrentClockFreqs() (DeviceCurrentClockFreqs, Return) {
var currentClockFreqs DeviceCurrentClockFreqs
currentClockFreqs.Version = STRUCT_VERSION(currentClockFreqs, 1)
ret := nvmlDeviceGetCurrentClockFreqs(device, &currentClockFreqs)
return currentClockFreqs, ret
}
// nvml.DeviceGetDramEncryptionMode()
func (l *library) DeviceGetDramEncryptionMode(device Device) (DramEncryptionInfo, DramEncryptionInfo, Return) {
return device.GetDramEncryptionMode()
}
func (device nvmlDevice) GetDramEncryptionMode() (DramEncryptionInfo, DramEncryptionInfo, Return) {
var current, pending DramEncryptionInfo
current.Version = STRUCT_VERSION(current, 1)
pending.Version = STRUCT_VERSION(pending, 1)
ret := nvmlDeviceGetDramEncryptionMode(device, &current, &pending)
return current, pending, ret
}
// nvml.DeviceSetDramEncryptionMode()
func (l *library) DeviceSetDramEncryptionMode(device Device, dramEncryption *DramEncryptionInfo) Return {
return device.SetDramEncryptionMode(dramEncryption)
}
func (device nvmlDevice) SetDramEncryptionMode(dramEncryption *DramEncryptionInfo) Return {
return nvmlDeviceSetDramEncryptionMode(device, dramEncryption)
}
// nvml.DeviceGetPlatformInfo()
func (l *library) DeviceGetPlatformInfo(device Device) (PlatformInfo, Return) {
return device.GetPlatformInfo()
}
func (device nvmlDevice) GetPlatformInfo() (PlatformInfo, Return) {
var platformInfo PlatformInfo
platformInfo.Version = STRUCT_VERSION(platformInfo, 1)
ret := nvmlDeviceGetPlatformInfo(device, &platformInfo)
return platformInfo, ret
}
// nvml.DeviceGetNvlinkSupportedBwModes()
func (l *library) DeviceGetNvlinkSupportedBwModes(device Device) (NvlinkSupportedBwModes, Return) {
return device.GetNvlinkSupportedBwModes()
}
func (device nvmlDevice) GetNvlinkSupportedBwModes() (NvlinkSupportedBwModes, Return) {
var supportedBwMode NvlinkSupportedBwModes
supportedBwMode.Version = STRUCT_VERSION(supportedBwMode, 1)
ret := nvmlDeviceGetNvlinkSupportedBwModes(device, &supportedBwMode)
return supportedBwMode, ret
}
// nvml.DeviceGetNvlinkBwMode()
func (l *library) DeviceGetNvlinkBwMode(device Device) (NvlinkGetBwMode, Return) {
return device.GetNvlinkBwMode()
}
func (device nvmlDevice) GetNvlinkBwMode() (NvlinkGetBwMode, Return) {
var getBwMode NvlinkGetBwMode
getBwMode.Version = STRUCT_VERSION(getBwMode, 1)
ret := nvmlDeviceGetNvlinkBwMode(device, &getBwMode)
return getBwMode, ret
}
// nvml.DeviceSetNvlinkBwMode()
func (l *library) DeviceSetNvlinkBwMode(device Device, setBwMode *NvlinkSetBwMode) Return {
return device.SetNvlinkBwMode(setBwMode)
}
func (device nvmlDevice) SetNvlinkBwMode(setBwMode *NvlinkSetBwMode) Return {
return nvmlDeviceSetNvlinkBwMode(device, setBwMode)
}
// nvml.DeviceWorkloadPowerProfileGetProfilesInfo()
func (l *library) DeviceWorkloadPowerProfileGetProfilesInfo(device Device) (WorkloadPowerProfileProfilesInfo, Return) {
return device.WorkloadPowerProfileGetProfilesInfo()
}
func (device nvmlDevice) WorkloadPowerProfileGetProfilesInfo() (WorkloadPowerProfileProfilesInfo, Return) {
var profilesInfo WorkloadPowerProfileProfilesInfo
profilesInfo.Version = STRUCT_VERSION(profilesInfo, 1)
ret := nvmlDeviceWorkloadPowerProfileGetProfilesInfo(device, &profilesInfo)
return profilesInfo, ret
}
// nvml.DeviceWorkloadPowerProfileGetCurrentProfiles()
func (l *library) DeviceWorkloadPowerProfileGetCurrentProfiles(device Device) (WorkloadPowerProfileCurrentProfiles, Return) {
return device.WorkloadPowerProfileGetCurrentProfiles()
}
func (device nvmlDevice) WorkloadPowerProfileGetCurrentProfiles() (WorkloadPowerProfileCurrentProfiles, Return) {
var currentProfiles WorkloadPowerProfileCurrentProfiles
currentProfiles.Version = STRUCT_VERSION(currentProfiles, 1)
ret := nvmlDeviceWorkloadPowerProfileGetCurrentProfiles(device, &currentProfiles)
return currentProfiles, ret
}
// nvml.DeviceWorkloadPowerProfileSetRequestedProfiles()
func (l *library) DeviceWorkloadPowerProfileSetRequestedProfiles(device Device, requestedProfiles *WorkloadPowerProfileRequestedProfiles) Return {
return device.WorkloadPowerProfileSetRequestedProfiles(requestedProfiles)
}
func (device nvmlDevice) WorkloadPowerProfileSetRequestedProfiles(requestedProfiles *WorkloadPowerProfileRequestedProfiles) Return {
return nvmlDeviceWorkloadPowerProfileSetRequestedProfiles(device, requestedProfiles)
}
// nvml.DeviceWorkloadPowerProfileClearRequestedProfiles()
func (l *library) DeviceWorkloadPowerProfileClearRequestedProfiles(device Device, requestedProfiles *WorkloadPowerProfileRequestedProfiles) Return {
return device.WorkloadPowerProfileClearRequestedProfiles(requestedProfiles)
}
func (device nvmlDevice) WorkloadPowerProfileClearRequestedProfiles(requestedProfiles *WorkloadPowerProfileRequestedProfiles) Return {
return nvmlDeviceWorkloadPowerProfileClearRequestedProfiles(device, requestedProfiles)
}
// nvml.DevicePowerSmoothingActivatePresetProfile()
func (l *library) DevicePowerSmoothingActivatePresetProfile(device Device, profile *PowerSmoothingProfile) Return {
return device.PowerSmoothingActivatePresetProfile(profile)
}
func (device nvmlDevice) PowerSmoothingActivatePresetProfile(profile *PowerSmoothingProfile) Return {
return nvmlDevicePowerSmoothingActivatePresetProfile(device, profile)
}
// nvml.DevicePowerSmoothingUpdatePresetProfileParam()
func (l *library) DevicePowerSmoothingUpdatePresetProfileParam(device Device, profile *PowerSmoothingProfile) Return {
return device.PowerSmoothingUpdatePresetProfileParam(profile)
}
func (device nvmlDevice) PowerSmoothingUpdatePresetProfileParam(profile *PowerSmoothingProfile) Return {
return nvmlDevicePowerSmoothingUpdatePresetProfileParam(device, profile)
}
// nvml.DevicePowerSmoothingSetState()
func (l *library) DevicePowerSmoothingSetState(device Device, state *PowerSmoothingState) Return {
return device.PowerSmoothingSetState(state)
}
func (device nvmlDevice) PowerSmoothingSetState(state *PowerSmoothingState) Return {
return nvmlDevicePowerSmoothingSetState(device, state)
}
// nvml.GpuInstanceGetCreatableVgpus()
func (l *library) GpuInstanceGetCreatableVgpus(gpuInstance GpuInstance) (VgpuTypeIdInfo, Return) {
return gpuInstance.GetCreatableVgpus()
}
func (gpuInstance nvmlGpuInstance) GetCreatableVgpus() (VgpuTypeIdInfo, Return) {
var vgpuTypeIdInfo VgpuTypeIdInfo
vgpuTypeIdInfo.Version = STRUCT_VERSION(vgpuTypeIdInfo, 1)
ret := nvmlGpuInstanceGetCreatableVgpus(gpuInstance, &vgpuTypeIdInfo)
return vgpuTypeIdInfo, ret
}
// nvml.GpuInstanceGetActiveVgpus()
func (l *library) GpuInstanceGetActiveVgpus(gpuInstance GpuInstance) (ActiveVgpuInstanceInfo, Return) {
return gpuInstance.GetActiveVgpus()
}
func (gpuInstance nvmlGpuInstance) GetActiveVgpus() (ActiveVgpuInstanceInfo, Return) {
var activeVgpuInstanceInfo ActiveVgpuInstanceInfo
activeVgpuInstanceInfo.Version = STRUCT_VERSION(activeVgpuInstanceInfo, 1)
ret := nvmlGpuInstanceGetActiveVgpus(gpuInstance, &activeVgpuInstanceInfo)
return activeVgpuInstanceInfo, ret
}
// nvml.GpuInstanceSetVgpuSchedulerState()
func (l *library) GpuInstanceSetVgpuSchedulerState(gpuInstance GpuInstance, scheduler *VgpuSchedulerState) Return {
return gpuInstance.SetVgpuSchedulerState(scheduler)
}
func (gpuInstance nvmlGpuInstance) SetVgpuSchedulerState(scheduler *VgpuSchedulerState) Return {
return nvmlGpuInstanceSetVgpuSchedulerState(gpuInstance, scheduler)
}
// nvml.GpuInstanceGetVgpuSchedulerState()
func (l *library) GpuInstanceGetVgpuSchedulerState(gpuInstance GpuInstance) (VgpuSchedulerStateInfo, Return) {
return gpuInstance.GetVgpuSchedulerState()
}
func (gpuInstance nvmlGpuInstance) GetVgpuSchedulerState() (VgpuSchedulerStateInfo, Return) {
var schedulerStateInfo VgpuSchedulerStateInfo
schedulerStateInfo.Version = STRUCT_VERSION(schedulerStateInfo, 1)
ret := nvmlGpuInstanceGetVgpuSchedulerState(gpuInstance, &schedulerStateInfo)
return schedulerStateInfo, ret
}
// nvml.GpuInstanceGetVgpuSchedulerLog()
func (l *library) GpuInstanceGetVgpuSchedulerLog(gpuInstance GpuInstance) (VgpuSchedulerLogInfo, Return) {
return gpuInstance.GetVgpuSchedulerLog()
}
func (gpuInstance nvmlGpuInstance) GetVgpuSchedulerLog() (VgpuSchedulerLogInfo, Return) {
var schedulerLogInfo VgpuSchedulerLogInfo
schedulerLogInfo.Version = STRUCT_VERSION(schedulerLogInfo, 1)
ret := nvmlGpuInstanceGetVgpuSchedulerLog(gpuInstance, &schedulerLogInfo)
return schedulerLogInfo, ret
}
// nvml.GpuInstanceGetVgpuTypeCreatablePlacements()
func (l *library) GpuInstanceGetVgpuTypeCreatablePlacements(gpuInstance GpuInstance) (VgpuCreatablePlacementInfo, Return) {
return gpuInstance.GetVgpuTypeCreatablePlacements()
}
func (gpuInstance nvmlGpuInstance) GetVgpuTypeCreatablePlacements() (VgpuCreatablePlacementInfo, Return) {
var creatablePlacementInfo VgpuCreatablePlacementInfo
creatablePlacementInfo.Version = STRUCT_VERSION(creatablePlacementInfo, 1)
ret := nvmlGpuInstanceGetVgpuTypeCreatablePlacements(gpuInstance, &creatablePlacementInfo)
return creatablePlacementInfo, ret
}
// nvml.GpuInstanceGetVgpuHeterogeneousMode()
func (l *library) GpuInstanceGetVgpuHeterogeneousMode(gpuInstance GpuInstance) (VgpuHeterogeneousMode, Return) {
return gpuInstance.GetVgpuHeterogeneousMode()
}
func (gpuInstance nvmlGpuInstance) GetVgpuHeterogeneousMode() (VgpuHeterogeneousMode, Return) {
var heterogeneousMode VgpuHeterogeneousMode
heterogeneousMode.Version = STRUCT_VERSION(heterogeneousMode, 1)
ret := nvmlGpuInstanceGetVgpuHeterogeneousMode(gpuInstance, &heterogeneousMode)
return heterogeneousMode, ret
}
// nvml.GpuInstanceSetVgpuHeterogeneousMode()
func (l *library) GpuInstanceSetVgpuHeterogeneousMode(gpuInstance GpuInstance, heterogeneousMode *VgpuHeterogeneousMode) Return {
return gpuInstance.SetVgpuHeterogeneousMode(heterogeneousMode)
}
func (gpuInstance nvmlGpuInstance) SetVgpuHeterogeneousMode(heterogeneousMode *VgpuHeterogeneousMode) Return {
return nvmlGpuInstanceSetVgpuHeterogeneousMode(gpuInstance, heterogeneousMode)
}

View File

@@ -23,17 +23,6 @@ type EventData struct {
ComputeInstanceId uint32
}
func (e EventData) convert() nvmlEventData {
out := nvmlEventData{
Device: e.Device.(nvmlDevice),
EventType: e.EventType,
EventData: e.EventData,
GpuInstanceId: e.GpuInstanceId,
ComputeInstanceId: e.ComputeInstanceId,
}
return out
}
func (e nvmlEventData) convert() EventData {
out := EventData{
Device: e.Device,
@@ -71,3 +60,23 @@ func (l *library) EventSetFree(set EventSet) Return {
func (set nvmlEventSet) Free() Return {
return nvmlEventSetFree(set)
}
// nvml.SystemEventSetCreate()
func (l *library) SystemEventSetCreate(request *SystemEventSetCreateRequest) Return {
return nvmlSystemEventSetCreate(request)
}
// nvml.SystemEventSetFree()
func (l *library) SystemEventSetFree(request *SystemEventSetFreeRequest) Return {
return nvmlSystemEventSetFree(request)
}
// nvml.SystemRegisterEvents()
func (l *library) SystemRegisterEvents(request *SystemRegisterEventRequest) Return {
return nvmlSystemRegisterEvents(request)
}
// nvml.SystemEventSetWait()
func (l *library) SystemEventSetWait(request *SystemEventSetWaitRequest) Return {
return nvmlSystemEventSetWait(request)
}

View File

@@ -20,7 +20,7 @@ type GpmMetricsGetType struct {
NumMetrics uint32
Sample1 GpmSample
Sample2 GpmSample
Metrics [98]GpmMetric
Metrics [210]GpmMetric
}
func (g *GpmMetricsGetType) convert() *nvmlGpmMetricsGetType {
@@ -30,9 +30,8 @@ func (g *GpmMetricsGetType) convert() *nvmlGpmMetricsGetType {
Sample1: g.Sample1.(nvmlGpmSample),
Sample2: g.Sample2.(nvmlGpmSample),
}
for i := range g.Metrics {
out.Metrics[i] = g.Metrics[i]
}
copy(out.Metrics[:], g.Metrics[:])
return out
}
@@ -43,9 +42,8 @@ func (g *nvmlGpmMetricsGetType) convert() *GpmMetricsGetType {
Sample1: g.Sample1,
Sample2: g.Sample2,
}
for i := range g.Metrics {
out.Metrics[i] = g.Metrics[i]
}
copy(out.Metrics[:], g.Metrics[:])
return out
}

View File

@@ -163,6 +163,7 @@ var GetBlacklistDeviceCount = GetExcludedDeviceCount
var GetBlacklistDeviceInfoByIndex = GetExcludedDeviceInfoByIndex
var nvmlDeviceGetGpuInstancePossiblePlacements = nvmlDeviceGetGpuInstancePossiblePlacements_v1
var nvmlVgpuInstanceGetLicenseInfo = nvmlVgpuInstanceGetLicenseInfo_v1
var nvmlDeviceGetDriverModel = nvmlDeviceGetDriverModel_v1
// BlacklistDeviceInfo was replaced by ExcludedDeviceInfo
type BlacklistDeviceInfo = ExcludedDeviceInfo
@@ -288,4 +289,8 @@ func (l *library) updateVersionedSymbols() {
if err == nil {
nvmlVgpuInstanceGetLicenseInfo = nvmlVgpuInstanceGetLicenseInfo_v2
}
err = l.dl.Lookup("nvmlDeviceGetDriverModel_v2")
if err == nil {
nvmlDeviceGetDriverModel = nvmlDeviceGetDriverModel_v2
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -20,9 +20,10 @@ import (
"fmt"
"sync"
"github.com/google/uuid"
"github.com/NVIDIA/go-nvml/pkg/nvml"
"github.com/NVIDIA/go-nvml/pkg/nvml/mock"
"github.com/google/uuid"
)
type Server struct {
@@ -108,7 +109,7 @@ func NewDevice(index int) *Device {
},
GpuInstances: make(map[*GpuInstance]struct{}),
GpuInstanceCounter: 0,
MemoryInfo: nvml.Memory{42949672960, 0, 0},
MemoryInfo: nvml.Memory{Total: 42949672960, Free: 0, Used: 0},
}
device.setMockFuncs()
return device

View File

@@ -27,6 +27,9 @@ var _ nvml.GpuInstance = &GpuInstance{}
// DestroyFunc: func() nvml.Return {
// panic("mock out the Destroy method")
// },
// GetActiveVgpusFunc: func() (nvml.ActiveVgpuInstanceInfo, nvml.Return) {
// panic("mock out the GetActiveVgpus method")
// },
// GetComputeInstanceByIdFunc: func(n int) (nvml.ComputeInstance, nvml.Return) {
// panic("mock out the GetComputeInstanceById method")
// },
@@ -45,9 +48,30 @@ var _ nvml.GpuInstance = &GpuInstance{}
// GetComputeInstancesFunc: func(computeInstanceProfileInfo *nvml.ComputeInstanceProfileInfo) ([]nvml.ComputeInstance, nvml.Return) {
// panic("mock out the GetComputeInstances method")
// },
// GetCreatableVgpusFunc: func() (nvml.VgpuTypeIdInfo, nvml.Return) {
// panic("mock out the GetCreatableVgpus method")
// },
// GetInfoFunc: func() (nvml.GpuInstanceInfo, nvml.Return) {
// panic("mock out the GetInfo method")
// },
// GetVgpuHeterogeneousModeFunc: func() (nvml.VgpuHeterogeneousMode, nvml.Return) {
// panic("mock out the GetVgpuHeterogeneousMode method")
// },
// GetVgpuSchedulerLogFunc: func() (nvml.VgpuSchedulerLogInfo, nvml.Return) {
// panic("mock out the GetVgpuSchedulerLog method")
// },
// GetVgpuSchedulerStateFunc: func() (nvml.VgpuSchedulerStateInfo, nvml.Return) {
// panic("mock out the GetVgpuSchedulerState method")
// },
// GetVgpuTypeCreatablePlacementsFunc: func() (nvml.VgpuCreatablePlacementInfo, nvml.Return) {
// panic("mock out the GetVgpuTypeCreatablePlacements method")
// },
// SetVgpuHeterogeneousModeFunc: func(vgpuHeterogeneousMode *nvml.VgpuHeterogeneousMode) nvml.Return {
// panic("mock out the SetVgpuHeterogeneousMode method")
// },
// SetVgpuSchedulerStateFunc: func(vgpuSchedulerState *nvml.VgpuSchedulerState) nvml.Return {
// panic("mock out the SetVgpuSchedulerState method")
// },
// }
//
// // use mockedGpuInstance in code that requires nvml.GpuInstance
@@ -64,6 +88,9 @@ type GpuInstance struct {
// DestroyFunc mocks the Destroy method.
DestroyFunc func() nvml.Return
// GetActiveVgpusFunc mocks the GetActiveVgpus method.
GetActiveVgpusFunc func() (nvml.ActiveVgpuInstanceInfo, nvml.Return)
// GetComputeInstanceByIdFunc mocks the GetComputeInstanceById method.
GetComputeInstanceByIdFunc func(n int) (nvml.ComputeInstance, nvml.Return)
@@ -82,9 +109,30 @@ type GpuInstance struct {
// GetComputeInstancesFunc mocks the GetComputeInstances method.
GetComputeInstancesFunc func(computeInstanceProfileInfo *nvml.ComputeInstanceProfileInfo) ([]nvml.ComputeInstance, nvml.Return)
// GetCreatableVgpusFunc mocks the GetCreatableVgpus method.
GetCreatableVgpusFunc func() (nvml.VgpuTypeIdInfo, nvml.Return)
// GetInfoFunc mocks the GetInfo method.
GetInfoFunc func() (nvml.GpuInstanceInfo, nvml.Return)
// GetVgpuHeterogeneousModeFunc mocks the GetVgpuHeterogeneousMode method.
GetVgpuHeterogeneousModeFunc func() (nvml.VgpuHeterogeneousMode, nvml.Return)
// GetVgpuSchedulerLogFunc mocks the GetVgpuSchedulerLog method.
GetVgpuSchedulerLogFunc func() (nvml.VgpuSchedulerLogInfo, nvml.Return)
// GetVgpuSchedulerStateFunc mocks the GetVgpuSchedulerState method.
GetVgpuSchedulerStateFunc func() (nvml.VgpuSchedulerStateInfo, nvml.Return)
// GetVgpuTypeCreatablePlacementsFunc mocks the GetVgpuTypeCreatablePlacements method.
GetVgpuTypeCreatablePlacementsFunc func() (nvml.VgpuCreatablePlacementInfo, nvml.Return)
// SetVgpuHeterogeneousModeFunc mocks the SetVgpuHeterogeneousMode method.
SetVgpuHeterogeneousModeFunc func(vgpuHeterogeneousMode *nvml.VgpuHeterogeneousMode) nvml.Return
// SetVgpuSchedulerStateFunc mocks the SetVgpuSchedulerState method.
SetVgpuSchedulerStateFunc func(vgpuSchedulerState *nvml.VgpuSchedulerState) nvml.Return
// calls tracks calls to the methods.
calls struct {
// CreateComputeInstance holds details about calls to the CreateComputeInstance method.
@@ -102,6 +150,9 @@ type GpuInstance struct {
// Destroy holds details about calls to the Destroy method.
Destroy []struct {
}
// GetActiveVgpus holds details about calls to the GetActiveVgpus method.
GetActiveVgpus []struct {
}
// GetComputeInstanceById holds details about calls to the GetComputeInstanceById method.
GetComputeInstanceById []struct {
// N is the n argument value.
@@ -136,20 +187,53 @@ type GpuInstance struct {
// ComputeInstanceProfileInfo is the computeInstanceProfileInfo argument value.
ComputeInstanceProfileInfo *nvml.ComputeInstanceProfileInfo
}
// GetCreatableVgpus holds details about calls to the GetCreatableVgpus method.
GetCreatableVgpus []struct {
}
// GetInfo holds details about calls to the GetInfo method.
GetInfo []struct {
}
// GetVgpuHeterogeneousMode holds details about calls to the GetVgpuHeterogeneousMode method.
GetVgpuHeterogeneousMode []struct {
}
// GetVgpuSchedulerLog holds details about calls to the GetVgpuSchedulerLog method.
GetVgpuSchedulerLog []struct {
}
// GetVgpuSchedulerState holds details about calls to the GetVgpuSchedulerState method.
GetVgpuSchedulerState []struct {
}
// GetVgpuTypeCreatablePlacements holds details about calls to the GetVgpuTypeCreatablePlacements method.
GetVgpuTypeCreatablePlacements []struct {
}
// SetVgpuHeterogeneousMode holds details about calls to the SetVgpuHeterogeneousMode method.
SetVgpuHeterogeneousMode []struct {
// VgpuHeterogeneousMode is the vgpuHeterogeneousMode argument value.
VgpuHeterogeneousMode *nvml.VgpuHeterogeneousMode
}
// SetVgpuSchedulerState holds details about calls to the SetVgpuSchedulerState method.
SetVgpuSchedulerState []struct {
// VgpuSchedulerState is the vgpuSchedulerState argument value.
VgpuSchedulerState *nvml.VgpuSchedulerState
}
}
lockCreateComputeInstance sync.RWMutex
lockCreateComputeInstanceWithPlacement sync.RWMutex
lockDestroy sync.RWMutex
lockGetActiveVgpus sync.RWMutex
lockGetComputeInstanceById sync.RWMutex
lockGetComputeInstancePossiblePlacements sync.RWMutex
lockGetComputeInstanceProfileInfo sync.RWMutex
lockGetComputeInstanceProfileInfoV sync.RWMutex
lockGetComputeInstanceRemainingCapacity sync.RWMutex
lockGetComputeInstances sync.RWMutex
lockGetCreatableVgpus sync.RWMutex
lockGetInfo sync.RWMutex
lockGetVgpuHeterogeneousMode sync.RWMutex
lockGetVgpuSchedulerLog sync.RWMutex
lockGetVgpuSchedulerState sync.RWMutex
lockGetVgpuTypeCreatablePlacements sync.RWMutex
lockSetVgpuHeterogeneousMode sync.RWMutex
lockSetVgpuSchedulerState sync.RWMutex
}
// CreateComputeInstance calls CreateComputeInstanceFunc.
@@ -247,6 +331,33 @@ func (mock *GpuInstance) DestroyCalls() []struct {
return calls
}
// GetActiveVgpus calls GetActiveVgpusFunc.
func (mock *GpuInstance) GetActiveVgpus() (nvml.ActiveVgpuInstanceInfo, nvml.Return) {
if mock.GetActiveVgpusFunc == nil {
panic("GpuInstance.GetActiveVgpusFunc: method is nil but GpuInstance.GetActiveVgpus was just called")
}
callInfo := struct {
}{}
mock.lockGetActiveVgpus.Lock()
mock.calls.GetActiveVgpus = append(mock.calls.GetActiveVgpus, callInfo)
mock.lockGetActiveVgpus.Unlock()
return mock.GetActiveVgpusFunc()
}
// GetActiveVgpusCalls gets all the calls that were made to GetActiveVgpus.
// Check the length with:
//
// len(mockedGpuInstance.GetActiveVgpusCalls())
func (mock *GpuInstance) GetActiveVgpusCalls() []struct {
} {
var calls []struct {
}
mock.lockGetActiveVgpus.RLock()
calls = mock.calls.GetActiveVgpus
mock.lockGetActiveVgpus.RUnlock()
return calls
}
// GetComputeInstanceById calls GetComputeInstanceByIdFunc.
func (mock *GpuInstance) GetComputeInstanceById(n int) (nvml.ComputeInstance, nvml.Return) {
if mock.GetComputeInstanceByIdFunc == nil {
@@ -447,6 +558,33 @@ func (mock *GpuInstance) GetComputeInstancesCalls() []struct {
return calls
}
// GetCreatableVgpus calls GetCreatableVgpusFunc.
func (mock *GpuInstance) GetCreatableVgpus() (nvml.VgpuTypeIdInfo, nvml.Return) {
if mock.GetCreatableVgpusFunc == nil {
panic("GpuInstance.GetCreatableVgpusFunc: method is nil but GpuInstance.GetCreatableVgpus was just called")
}
callInfo := struct {
}{}
mock.lockGetCreatableVgpus.Lock()
mock.calls.GetCreatableVgpus = append(mock.calls.GetCreatableVgpus, callInfo)
mock.lockGetCreatableVgpus.Unlock()
return mock.GetCreatableVgpusFunc()
}
// GetCreatableVgpusCalls gets all the calls that were made to GetCreatableVgpus.
// Check the length with:
//
// len(mockedGpuInstance.GetCreatableVgpusCalls())
func (mock *GpuInstance) GetCreatableVgpusCalls() []struct {
} {
var calls []struct {
}
mock.lockGetCreatableVgpus.RLock()
calls = mock.calls.GetCreatableVgpus
mock.lockGetCreatableVgpus.RUnlock()
return calls
}
// GetInfo calls GetInfoFunc.
func (mock *GpuInstance) GetInfo() (nvml.GpuInstanceInfo, nvml.Return) {
if mock.GetInfoFunc == nil {
@@ -473,3 +611,175 @@ func (mock *GpuInstance) GetInfoCalls() []struct {
mock.lockGetInfo.RUnlock()
return calls
}
// GetVgpuHeterogeneousMode calls GetVgpuHeterogeneousModeFunc.
func (mock *GpuInstance) GetVgpuHeterogeneousMode() (nvml.VgpuHeterogeneousMode, nvml.Return) {
if mock.GetVgpuHeterogeneousModeFunc == nil {
panic("GpuInstance.GetVgpuHeterogeneousModeFunc: method is nil but GpuInstance.GetVgpuHeterogeneousMode was just called")
}
callInfo := struct {
}{}
mock.lockGetVgpuHeterogeneousMode.Lock()
mock.calls.GetVgpuHeterogeneousMode = append(mock.calls.GetVgpuHeterogeneousMode, callInfo)
mock.lockGetVgpuHeterogeneousMode.Unlock()
return mock.GetVgpuHeterogeneousModeFunc()
}
// GetVgpuHeterogeneousModeCalls gets all the calls that were made to GetVgpuHeterogeneousMode.
// Check the length with:
//
// len(mockedGpuInstance.GetVgpuHeterogeneousModeCalls())
func (mock *GpuInstance) GetVgpuHeterogeneousModeCalls() []struct {
} {
var calls []struct {
}
mock.lockGetVgpuHeterogeneousMode.RLock()
calls = mock.calls.GetVgpuHeterogeneousMode
mock.lockGetVgpuHeterogeneousMode.RUnlock()
return calls
}
// GetVgpuSchedulerLog calls GetVgpuSchedulerLogFunc.
func (mock *GpuInstance) GetVgpuSchedulerLog() (nvml.VgpuSchedulerLogInfo, nvml.Return) {
if mock.GetVgpuSchedulerLogFunc == nil {
panic("GpuInstance.GetVgpuSchedulerLogFunc: method is nil but GpuInstance.GetVgpuSchedulerLog was just called")
}
callInfo := struct {
}{}
mock.lockGetVgpuSchedulerLog.Lock()
mock.calls.GetVgpuSchedulerLog = append(mock.calls.GetVgpuSchedulerLog, callInfo)
mock.lockGetVgpuSchedulerLog.Unlock()
return mock.GetVgpuSchedulerLogFunc()
}
// GetVgpuSchedulerLogCalls gets all the calls that were made to GetVgpuSchedulerLog.
// Check the length with:
//
// len(mockedGpuInstance.GetVgpuSchedulerLogCalls())
func (mock *GpuInstance) GetVgpuSchedulerLogCalls() []struct {
} {
var calls []struct {
}
mock.lockGetVgpuSchedulerLog.RLock()
calls = mock.calls.GetVgpuSchedulerLog
mock.lockGetVgpuSchedulerLog.RUnlock()
return calls
}
// GetVgpuSchedulerState calls GetVgpuSchedulerStateFunc.
func (mock *GpuInstance) GetVgpuSchedulerState() (nvml.VgpuSchedulerStateInfo, nvml.Return) {
if mock.GetVgpuSchedulerStateFunc == nil {
panic("GpuInstance.GetVgpuSchedulerStateFunc: method is nil but GpuInstance.GetVgpuSchedulerState was just called")
}
callInfo := struct {
}{}
mock.lockGetVgpuSchedulerState.Lock()
mock.calls.GetVgpuSchedulerState = append(mock.calls.GetVgpuSchedulerState, callInfo)
mock.lockGetVgpuSchedulerState.Unlock()
return mock.GetVgpuSchedulerStateFunc()
}
// GetVgpuSchedulerStateCalls gets all the calls that were made to GetVgpuSchedulerState.
// Check the length with:
//
// len(mockedGpuInstance.GetVgpuSchedulerStateCalls())
func (mock *GpuInstance) GetVgpuSchedulerStateCalls() []struct {
} {
var calls []struct {
}
mock.lockGetVgpuSchedulerState.RLock()
calls = mock.calls.GetVgpuSchedulerState
mock.lockGetVgpuSchedulerState.RUnlock()
return calls
}
// GetVgpuTypeCreatablePlacements calls GetVgpuTypeCreatablePlacementsFunc.
func (mock *GpuInstance) GetVgpuTypeCreatablePlacements() (nvml.VgpuCreatablePlacementInfo, nvml.Return) {
if mock.GetVgpuTypeCreatablePlacementsFunc == nil {
panic("GpuInstance.GetVgpuTypeCreatablePlacementsFunc: method is nil but GpuInstance.GetVgpuTypeCreatablePlacements was just called")
}
callInfo := struct {
}{}
mock.lockGetVgpuTypeCreatablePlacements.Lock()
mock.calls.GetVgpuTypeCreatablePlacements = append(mock.calls.GetVgpuTypeCreatablePlacements, callInfo)
mock.lockGetVgpuTypeCreatablePlacements.Unlock()
return mock.GetVgpuTypeCreatablePlacementsFunc()
}
// GetVgpuTypeCreatablePlacementsCalls gets all the calls that were made to GetVgpuTypeCreatablePlacements.
// Check the length with:
//
// len(mockedGpuInstance.GetVgpuTypeCreatablePlacementsCalls())
func (mock *GpuInstance) GetVgpuTypeCreatablePlacementsCalls() []struct {
} {
var calls []struct {
}
mock.lockGetVgpuTypeCreatablePlacements.RLock()
calls = mock.calls.GetVgpuTypeCreatablePlacements
mock.lockGetVgpuTypeCreatablePlacements.RUnlock()
return calls
}
// SetVgpuHeterogeneousMode calls SetVgpuHeterogeneousModeFunc.
func (mock *GpuInstance) SetVgpuHeterogeneousMode(vgpuHeterogeneousMode *nvml.VgpuHeterogeneousMode) nvml.Return {
if mock.SetVgpuHeterogeneousModeFunc == nil {
panic("GpuInstance.SetVgpuHeterogeneousModeFunc: method is nil but GpuInstance.SetVgpuHeterogeneousMode was just called")
}
callInfo := struct {
VgpuHeterogeneousMode *nvml.VgpuHeterogeneousMode
}{
VgpuHeterogeneousMode: vgpuHeterogeneousMode,
}
mock.lockSetVgpuHeterogeneousMode.Lock()
mock.calls.SetVgpuHeterogeneousMode = append(mock.calls.SetVgpuHeterogeneousMode, callInfo)
mock.lockSetVgpuHeterogeneousMode.Unlock()
return mock.SetVgpuHeterogeneousModeFunc(vgpuHeterogeneousMode)
}
// SetVgpuHeterogeneousModeCalls gets all the calls that were made to SetVgpuHeterogeneousMode.
// Check the length with:
//
// len(mockedGpuInstance.SetVgpuHeterogeneousModeCalls())
func (mock *GpuInstance) SetVgpuHeterogeneousModeCalls() []struct {
VgpuHeterogeneousMode *nvml.VgpuHeterogeneousMode
} {
var calls []struct {
VgpuHeterogeneousMode *nvml.VgpuHeterogeneousMode
}
mock.lockSetVgpuHeterogeneousMode.RLock()
calls = mock.calls.SetVgpuHeterogeneousMode
mock.lockSetVgpuHeterogeneousMode.RUnlock()
return calls
}
// SetVgpuSchedulerState calls SetVgpuSchedulerStateFunc.
func (mock *GpuInstance) SetVgpuSchedulerState(vgpuSchedulerState *nvml.VgpuSchedulerState) nvml.Return {
if mock.SetVgpuSchedulerStateFunc == nil {
panic("GpuInstance.SetVgpuSchedulerStateFunc: method is nil but GpuInstance.SetVgpuSchedulerState was just called")
}
callInfo := struct {
VgpuSchedulerState *nvml.VgpuSchedulerState
}{
VgpuSchedulerState: vgpuSchedulerState,
}
mock.lockSetVgpuSchedulerState.Lock()
mock.calls.SetVgpuSchedulerState = append(mock.calls.SetVgpuSchedulerState, callInfo)
mock.lockSetVgpuSchedulerState.Unlock()
return mock.SetVgpuSchedulerStateFunc(vgpuSchedulerState)
}
// SetVgpuSchedulerStateCalls gets all the calls that were made to SetVgpuSchedulerState.
// Check the length with:
//
// len(mockedGpuInstance.SetVgpuSchedulerStateCalls())
func (mock *GpuInstance) SetVgpuSchedulerStateCalls() []struct {
VgpuSchedulerState *nvml.VgpuSchedulerState
} {
var calls []struct {
VgpuSchedulerState *nvml.VgpuSchedulerState
}
mock.lockSetVgpuSchedulerState.RLock()
calls = mock.calls.SetVgpuSchedulerState
mock.lockSetVgpuSchedulerState.RUnlock()
return calls
}

File diff suppressed because it is too large Load Diff

View File

@@ -72,6 +72,9 @@ var _ nvml.VgpuInstance = &VgpuInstance{}
// GetMetadataFunc: func() (nvml.VgpuMetadata, nvml.Return) {
// panic("mock out the GetMetadata method")
// },
// GetRuntimeStateSizeFunc: func() (nvml.VgpuRuntimeState, nvml.Return) {
// panic("mock out the GetRuntimeStateSize method")
// },
// GetTypeFunc: func() (nvml.VgpuTypeId, nvml.Return) {
// panic("mock out the GetType method")
// },
@@ -148,6 +151,9 @@ type VgpuInstance struct {
// GetMetadataFunc mocks the GetMetadata method.
GetMetadataFunc func() (nvml.VgpuMetadata, nvml.Return)
// GetRuntimeStateSizeFunc mocks the GetRuntimeStateSize method.
GetRuntimeStateSizeFunc func() (nvml.VgpuRuntimeState, nvml.Return)
// GetTypeFunc mocks the GetType method.
GetTypeFunc func() (nvml.VgpuTypeId, nvml.Return)
@@ -221,6 +227,9 @@ type VgpuInstance struct {
// GetMetadata holds details about calls to the GetMetadata method.
GetMetadata []struct {
}
// GetRuntimeStateSize holds details about calls to the GetRuntimeStateSize method.
GetRuntimeStateSize []struct {
}
// GetType holds details about calls to the GetType method.
GetType []struct {
}
@@ -257,6 +266,7 @@ type VgpuInstance struct {
lockGetLicenseStatus sync.RWMutex
lockGetMdevUUID sync.RWMutex
lockGetMetadata sync.RWMutex
lockGetRuntimeStateSize sync.RWMutex
lockGetType sync.RWMutex
lockGetUUID sync.RWMutex
lockGetVmDriverVersion sync.RWMutex
@@ -755,6 +765,33 @@ func (mock *VgpuInstance) GetMetadataCalls() []struct {
return calls
}
// GetRuntimeStateSize calls GetRuntimeStateSizeFunc.
func (mock *VgpuInstance) GetRuntimeStateSize() (nvml.VgpuRuntimeState, nvml.Return) {
if mock.GetRuntimeStateSizeFunc == nil {
panic("VgpuInstance.GetRuntimeStateSizeFunc: method is nil but VgpuInstance.GetRuntimeStateSize was just called")
}
callInfo := struct {
}{}
mock.lockGetRuntimeStateSize.Lock()
mock.calls.GetRuntimeStateSize = append(mock.calls.GetRuntimeStateSize, callInfo)
mock.lockGetRuntimeStateSize.Unlock()
return mock.GetRuntimeStateSizeFunc()
}
// GetRuntimeStateSizeCalls gets all the calls that were made to GetRuntimeStateSize.
// Check the length with:
//
// len(mockedVgpuInstance.GetRuntimeStateSizeCalls())
func (mock *VgpuInstance) GetRuntimeStateSizeCalls() []struct {
} {
var calls []struct {
}
mock.lockGetRuntimeStateSize.RLock()
calls = mock.calls.GetRuntimeStateSize
mock.lockGetRuntimeStateSize.RUnlock()
return calls
}
// GetType calls GetTypeFunc.
func (mock *VgpuInstance) GetType() (nvml.VgpuTypeId, nvml.Return) {
if mock.GetTypeFunc == nil {

View File

@@ -18,6 +18,9 @@ var _ nvml.VgpuTypeId = &VgpuTypeId{}
//
// // make and configure a mocked nvml.VgpuTypeId
// mockedVgpuTypeId := &VgpuTypeId{
// GetBAR1InfoFunc: func() (nvml.VgpuTypeBar1Info, nvml.Return) {
// panic("mock out the GetBAR1Info method")
// },
// GetCapabilitiesFunc: func(vgpuCapability nvml.VgpuCapability) (bool, nvml.Return) {
// panic("mock out the GetCapabilities method")
// },
@@ -67,6 +70,9 @@ var _ nvml.VgpuTypeId = &VgpuTypeId{}
//
// }
type VgpuTypeId struct {
// GetBAR1InfoFunc mocks the GetBAR1Info method.
GetBAR1InfoFunc func() (nvml.VgpuTypeBar1Info, nvml.Return)
// GetCapabilitiesFunc mocks the GetCapabilities method.
GetCapabilitiesFunc func(vgpuCapability nvml.VgpuCapability) (bool, nvml.Return)
@@ -111,6 +117,9 @@ type VgpuTypeId struct {
// calls tracks calls to the methods.
calls struct {
// GetBAR1Info holds details about calls to the GetBAR1Info method.
GetBAR1Info []struct {
}
// GetCapabilities holds details about calls to the GetCapabilities method.
GetCapabilities []struct {
// VgpuCapability is the vgpuCapability argument value.
@@ -164,6 +173,7 @@ type VgpuTypeId struct {
Device nvml.Device
}
}
lockGetBAR1Info sync.RWMutex
lockGetCapabilities sync.RWMutex
lockGetClass sync.RWMutex
lockGetCreatablePlacements sync.RWMutex
@@ -180,6 +190,33 @@ type VgpuTypeId struct {
lockGetSupportedPlacements sync.RWMutex
}
// GetBAR1Info calls GetBAR1InfoFunc.
func (mock *VgpuTypeId) GetBAR1Info() (nvml.VgpuTypeBar1Info, nvml.Return) {
if mock.GetBAR1InfoFunc == nil {
panic("VgpuTypeId.GetBAR1InfoFunc: method is nil but VgpuTypeId.GetBAR1Info was just called")
}
callInfo := struct {
}{}
mock.lockGetBAR1Info.Lock()
mock.calls.GetBAR1Info = append(mock.calls.GetBAR1Info, callInfo)
mock.lockGetBAR1Info.Unlock()
return mock.GetBAR1InfoFunc()
}
// GetBAR1InfoCalls gets all the calls that were made to GetBAR1Info.
// Check the length with:
//
// len(mockedVgpuTypeId.GetBAR1InfoCalls())
func (mock *VgpuTypeId) GetBAR1InfoCalls() []struct {
} {
var calls []struct {
}
mock.lockGetBAR1Info.RLock()
calls = mock.calls.GetBAR1Info
mock.lockGetBAR1Info.RUnlock()
return calls
}
// GetCapabilities calls GetCapabilitiesFunc.
func (mock *VgpuTypeId) GetCapabilities(vgpuCapability nvml.VgpuCapability) (bool, nvml.Return) {
if mock.GetCapabilitiesFunc == nil {

View File

@@ -121,6 +121,15 @@ func nvmlSystemGetTopologyGpuSet(CpuNumber uint32, Count *uint32, DeviceArray *n
return __v
}
// nvmlSystemGetDriverBranch function as declared in nvml/nvml.h
func nvmlSystemGetDriverBranch(BranchInfo *SystemDriverBranchInfo, Length uint32) Return {
cBranchInfo, _ := (*C.nvmlSystemDriverBranchInfo_t)(unsafe.Pointer(BranchInfo)), cgoAllocsUnknown
cLength, _ := (C.uint)(Length), cgoAllocsUnknown
__ret := C.nvmlSystemGetDriverBranch(cBranchInfo, cLength)
__v := (Return)(__ret)
return __v
}
// nvmlUnitGetCount function as declared in nvml/nvml.h
func nvmlUnitGetCount(UnitCount *uint32) Return {
cUnitCount, _ := (*C.uint)(unsafe.Pointer(UnitCount)), cgoAllocsUnknown
@@ -238,6 +247,15 @@ func nvmlDeviceGetHandleByUUID(Uuid string, nvmlDevice *nvmlDevice) Return {
return __v
}
// nvmlDeviceGetHandleByUUIDV function as declared in nvml/nvml.h
func nvmlDeviceGetHandleByUUIDV(Uuid *UUID, nvmlDevice *nvmlDevice) Return {
cUuid, _ := (*C.nvmlUUID_t)(unsafe.Pointer(Uuid)), cgoAllocsUnknown
cnvmlDevice, _ := (*C.nvmlDevice_t)(unsafe.Pointer(nvmlDevice)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetHandleByUUIDV(cUuid, cnvmlDevice)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetHandleByPciBusId_v2 function as declared in nvml/nvml.h
func nvmlDeviceGetHandleByPciBusId_v2(PciBusId string, nvmlDevice *nvmlDevice) Return {
cPciBusId, _ := unpackPCharString(PciBusId)
@@ -698,6 +716,15 @@ func nvmlDeviceGetFanSpeed_v2(nvmlDevice nvmlDevice, Fan uint32, Speed *uint32)
return __v
}
// nvmlDeviceGetFanSpeedRPM function as declared in nvml/nvml.h
func nvmlDeviceGetFanSpeedRPM(nvmlDevice nvmlDevice, FanSpeed *FanSpeedInfo) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cFanSpeed, _ := (*C.nvmlFanSpeedInfo_t)(unsafe.Pointer(FanSpeed)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetFanSpeedRPM(cnvmlDevice, cFanSpeed)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetTargetFanSpeed function as declared in nvml/nvml.h
func nvmlDeviceGetTargetFanSpeed(nvmlDevice nvmlDevice, Fan uint32, TargetSpeed *uint32) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
@@ -747,6 +774,24 @@ func nvmlDeviceGetTemperature(nvmlDevice nvmlDevice, SensorType TemperatureSenso
return __v
}
// nvmlDeviceGetCoolerInfo function as declared in nvml/nvml.h
func nvmlDeviceGetCoolerInfo(nvmlDevice nvmlDevice, CoolerInfo *CoolerInfo) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cCoolerInfo, _ := (*C.nvmlCoolerInfo_t)(unsafe.Pointer(CoolerInfo)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetCoolerInfo(cnvmlDevice, cCoolerInfo)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetTemperatureV function as declared in nvml/nvml.h
func nvmlDeviceGetTemperatureV(nvmlDevice nvmlDevice, Temperature *Temperature) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cTemperature, _ := (*C.nvmlTemperature_t)(unsafe.Pointer(Temperature)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetTemperatureV(cnvmlDevice, cTemperature)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetTemperatureThreshold function as declared in nvml/nvml.h
func nvmlDeviceGetTemperatureThreshold(nvmlDevice nvmlDevice, ThresholdType TemperatureThresholds, Temp *uint32) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
@@ -757,6 +802,15 @@ func nvmlDeviceGetTemperatureThreshold(nvmlDevice nvmlDevice, ThresholdType Temp
return __v
}
// nvmlDeviceGetMarginTemperature function as declared in nvml/nvml.h
func nvmlDeviceGetMarginTemperature(nvmlDevice nvmlDevice, MarginTempInfo *MarginTemperature) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cMarginTempInfo, _ := (*C.nvmlMarginTemperature_t)(unsafe.Pointer(MarginTempInfo)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetMarginTemperature(cnvmlDevice, cMarginTempInfo)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetThermalSettings function as declared in nvml/nvml.h
func nvmlDeviceGetThermalSettings(nvmlDevice nvmlDevice, SensorIndex uint32, PThermalSettings *GpuThermalSettings) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
@@ -881,6 +935,42 @@ func nvmlDeviceGetMemClkMinMaxVfOffset(nvmlDevice nvmlDevice, MinOffset *int32,
return __v
}
// nvmlDeviceGetClockOffsets function as declared in nvml/nvml.h
func nvmlDeviceGetClockOffsets(nvmlDevice nvmlDevice, Info *ClockOffset) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cInfo, _ := (*C.nvmlClockOffset_t)(unsafe.Pointer(Info)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetClockOffsets(cnvmlDevice, cInfo)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceSetClockOffsets function as declared in nvml/nvml.h
func nvmlDeviceSetClockOffsets(nvmlDevice nvmlDevice, Info *ClockOffset) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cInfo, _ := (*C.nvmlClockOffset_t)(unsafe.Pointer(Info)), cgoAllocsUnknown
__ret := C.nvmlDeviceSetClockOffsets(cnvmlDevice, cInfo)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetPerformanceModes function as declared in nvml/nvml.h
func nvmlDeviceGetPerformanceModes(nvmlDevice nvmlDevice, PerfModes *DevicePerfModes) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cPerfModes, _ := (*C.nvmlDevicePerfModes_t)(unsafe.Pointer(PerfModes)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetPerformanceModes(cnvmlDevice, cPerfModes)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetCurrentClockFreqs function as declared in nvml/nvml.h
func nvmlDeviceGetCurrentClockFreqs(nvmlDevice nvmlDevice, CurrentClockFreqs *DeviceCurrentClockFreqs) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cCurrentClockFreqs, _ := (*C.nvmlDeviceCurrentClockFreqs_t)(unsafe.Pointer(CurrentClockFreqs)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetCurrentClockFreqs(cnvmlDevice, cCurrentClockFreqs)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetPowerManagementMode function as declared in nvml/nvml.h
func nvmlDeviceGetPowerManagementMode(nvmlDevice nvmlDevice, Mode *EnableState) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
@@ -992,6 +1082,25 @@ func nvmlDeviceGetCudaComputeCapability(nvmlDevice nvmlDevice, Major *int32, Min
return __v
}
// nvmlDeviceGetDramEncryptionMode function as declared in nvml/nvml.h
func nvmlDeviceGetDramEncryptionMode(nvmlDevice nvmlDevice, Current *DramEncryptionInfo, Pending *DramEncryptionInfo) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cCurrent, _ := (*C.nvmlDramEncryptionInfo_t)(unsafe.Pointer(Current)), cgoAllocsUnknown
cPending, _ := (*C.nvmlDramEncryptionInfo_t)(unsafe.Pointer(Pending)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetDramEncryptionMode(cnvmlDevice, cCurrent, cPending)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceSetDramEncryptionMode function as declared in nvml/nvml.h
func nvmlDeviceSetDramEncryptionMode(nvmlDevice nvmlDevice, DramEncryption *DramEncryptionInfo) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cDramEncryption, _ := (*C.nvmlDramEncryptionInfo_t)(unsafe.Pointer(DramEncryption)), cgoAllocsUnknown
__ret := C.nvmlDeviceSetDramEncryptionMode(cnvmlDevice, cDramEncryption)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetEccMode function as declared in nvml/nvml.h
func nvmlDeviceGetEccMode(nvmlDevice nvmlDevice, Current *EnableState, Pending *EnableState) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
@@ -1162,12 +1271,12 @@ func nvmlDeviceGetFBCSessions(nvmlDevice nvmlDevice, SessionCount *uint32, Sessi
return __v
}
// nvmlDeviceGetDriverModel function as declared in nvml/nvml.h
func nvmlDeviceGetDriverModel(nvmlDevice nvmlDevice, Current *DriverModel, Pending *DriverModel) Return {
// nvmlDeviceGetDriverModel_v2 function as declared in nvml/nvml.h
func nvmlDeviceGetDriverModel_v2(nvmlDevice nvmlDevice, Current *DriverModel, Pending *DriverModel) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cCurrent, _ := (*C.nvmlDriverModel_t)(unsafe.Pointer(Current)), cgoAllocsUnknown
cPending, _ := (*C.nvmlDriverModel_t)(unsafe.Pointer(Pending)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetDriverModel(cnvmlDevice, cCurrent, cPending)
__ret := C.nvmlDeviceGetDriverModel_v2(cnvmlDevice, cCurrent, cPending)
__v := (Return)(__ret)
return __v
}
@@ -1440,6 +1549,31 @@ func nvmlSystemGetConfComputeKeyRotationThresholdInfo(PKeyRotationThrInfo *ConfC
return __v
}
// nvmlDeviceSetConfComputeUnprotectedMemSize function as declared in nvml/nvml.h
func nvmlDeviceSetConfComputeUnprotectedMemSize(nvmlDevice nvmlDevice, SizeKiB uint64) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cSizeKiB, _ := (C.ulonglong)(SizeKiB), cgoAllocsUnknown
__ret := C.nvmlDeviceSetConfComputeUnprotectedMemSize(cnvmlDevice, cSizeKiB)
__v := (Return)(__ret)
return __v
}
// nvmlSystemSetConfComputeGpusReadyState function as declared in nvml/nvml.h
func nvmlSystemSetConfComputeGpusReadyState(IsAcceptingWork uint32) Return {
cIsAcceptingWork, _ := (C.uint)(IsAcceptingWork), cgoAllocsUnknown
__ret := C.nvmlSystemSetConfComputeGpusReadyState(cIsAcceptingWork)
__v := (Return)(__ret)
return __v
}
// nvmlSystemSetConfComputeKeyRotationThresholdInfo function as declared in nvml/nvml.h
func nvmlSystemSetConfComputeKeyRotationThresholdInfo(PKeyRotationThrInfo *ConfComputeSetKeyRotationThresholdInfo) Return {
cPKeyRotationThrInfo, _ := (*C.nvmlConfComputeSetKeyRotationThresholdInfo_t)(unsafe.Pointer(PKeyRotationThrInfo)), cgoAllocsUnknown
__ret := C.nvmlSystemSetConfComputeKeyRotationThresholdInfo(cPKeyRotationThrInfo)
__v := (Return)(__ret)
return __v
}
// nvmlSystemGetConfComputeSettings function as declared in nvml/nvml.h
func nvmlSystemGetConfComputeSettings(Settings *SystemConfComputeSettings) Return {
cSettings, _ := (*C.nvmlSystemConfComputeSettings_t)(unsafe.Pointer(Settings)), cgoAllocsUnknown
@@ -1467,6 +1601,15 @@ func nvmlDeviceGetGspFirmwareMode(nvmlDevice nvmlDevice, IsEnabled *uint32, Defa
return __v
}
// nvmlDeviceGetSramEccErrorStatus function as declared in nvml/nvml.h
func nvmlDeviceGetSramEccErrorStatus(nvmlDevice nvmlDevice, Status *EccSramErrorStatus) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cStatus, _ := (*C.nvmlEccSramErrorStatus_t)(unsafe.Pointer(Status)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetSramEccErrorStatus(cnvmlDevice, cStatus)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetAccountingMode function as declared in nvml/nvml.h
func nvmlDeviceGetAccountingMode(nvmlDevice nvmlDevice, Mode *EnableState) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
@@ -1596,6 +1739,15 @@ func nvmlDeviceGetProcessesUtilizationInfo(nvmlDevice nvmlDevice, ProcesesUtilIn
return __v
}
// nvmlDeviceGetPlatformInfo function as declared in nvml/nvml.h
func nvmlDeviceGetPlatformInfo(nvmlDevice nvmlDevice, PlatformInfo *PlatformInfo) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cPlatformInfo, _ := (*C.nvmlPlatformInfo_t)(unsafe.Pointer(PlatformInfo)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetPlatformInfo(cnvmlDevice, cPlatformInfo)
__v := (Return)(__ret)
return __v
}
// nvmlUnitSetLedState function as declared in nvml/nvml.h
func nvmlUnitSetLedState(nvmlUnit nvmlUnit, Color LedColor) Return {
cnvmlUnit, _ := *(*C.nvmlUnit_t)(unsafe.Pointer(&nvmlUnit)), cgoAllocsUnknown
@@ -1809,31 +1961,6 @@ func nvmlDeviceSetMemClkVfOffset(nvmlDevice nvmlDevice, Offset int32) Return {
return __v
}
// nvmlDeviceSetConfComputeUnprotectedMemSize function as declared in nvml/nvml.h
func nvmlDeviceSetConfComputeUnprotectedMemSize(nvmlDevice nvmlDevice, SizeKiB uint64) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cSizeKiB, _ := (C.ulonglong)(SizeKiB), cgoAllocsUnknown
__ret := C.nvmlDeviceSetConfComputeUnprotectedMemSize(cnvmlDevice, cSizeKiB)
__v := (Return)(__ret)
return __v
}
// nvmlSystemSetConfComputeGpusReadyState function as declared in nvml/nvml.h
func nvmlSystemSetConfComputeGpusReadyState(IsAcceptingWork uint32) Return {
cIsAcceptingWork, _ := (C.uint)(IsAcceptingWork), cgoAllocsUnknown
__ret := C.nvmlSystemSetConfComputeGpusReadyState(cIsAcceptingWork)
__v := (Return)(__ret)
return __v
}
// nvmlSystemSetConfComputeKeyRotationThresholdInfo function as declared in nvml/nvml.h
func nvmlSystemSetConfComputeKeyRotationThresholdInfo(PKeyRotationThrInfo *ConfComputeSetKeyRotationThresholdInfo) Return {
cPKeyRotationThrInfo, _ := (*C.nvmlConfComputeSetKeyRotationThresholdInfo_t)(unsafe.Pointer(PKeyRotationThrInfo)), cgoAllocsUnknown
__ret := C.nvmlSystemSetConfComputeKeyRotationThresholdInfo(cPKeyRotationThrInfo)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceSetAccountingMode function as declared in nvml/nvml.h
func nvmlDeviceSetAccountingMode(nvmlDevice nvmlDevice, Mode EnableState) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
@@ -1851,6 +1978,15 @@ func nvmlDeviceClearAccountingPids(nvmlDevice nvmlDevice) Return {
return __v
}
// nvmlDeviceSetPowerManagementLimit_v2 function as declared in nvml/nvml.h
func nvmlDeviceSetPowerManagementLimit_v2(nvmlDevice nvmlDevice, PowerValue *PowerValue_v2) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cPowerValue, _ := (*C.nvmlPowerValue_v2_t)(unsafe.Pointer(PowerValue)), cgoAllocsUnknown
__ret := C.nvmlDeviceSetPowerManagementLimit_v2(cnvmlDevice, cPowerValue)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetNvLinkState function as declared in nvml/nvml.h
func nvmlDeviceGetNvLinkState(nvmlDevice nvmlDevice, Link uint32, IsActive *EnableState) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
@@ -1978,6 +2114,58 @@ func nvmlDeviceGetNvLinkRemoteDeviceType(nvmlDevice nvmlDevice, Link uint32, PNv
return __v
}
// nvmlDeviceSetNvLinkDeviceLowPowerThreshold function as declared in nvml/nvml.h
func nvmlDeviceSetNvLinkDeviceLowPowerThreshold(nvmlDevice nvmlDevice, Info *NvLinkPowerThres) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cInfo, _ := (*C.nvmlNvLinkPowerThres_t)(unsafe.Pointer(Info)), cgoAllocsUnknown
__ret := C.nvmlDeviceSetNvLinkDeviceLowPowerThreshold(cnvmlDevice, cInfo)
__v := (Return)(__ret)
return __v
}
// nvmlSystemSetNvlinkBwMode function as declared in nvml/nvml.h
func nvmlSystemSetNvlinkBwMode(NvlinkBwMode uint32) Return {
cNvlinkBwMode, _ := (C.uint)(NvlinkBwMode), cgoAllocsUnknown
__ret := C.nvmlSystemSetNvlinkBwMode(cNvlinkBwMode)
__v := (Return)(__ret)
return __v
}
// nvmlSystemGetNvlinkBwMode function as declared in nvml/nvml.h
func nvmlSystemGetNvlinkBwMode(NvlinkBwMode *uint32) Return {
cNvlinkBwMode, _ := (*C.uint)(unsafe.Pointer(NvlinkBwMode)), cgoAllocsUnknown
__ret := C.nvmlSystemGetNvlinkBwMode(cNvlinkBwMode)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetNvlinkSupportedBwModes function as declared in nvml/nvml.h
func nvmlDeviceGetNvlinkSupportedBwModes(nvmlDevice nvmlDevice, SupportedBwMode *NvlinkSupportedBwModes) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cSupportedBwMode, _ := (*C.nvmlNvlinkSupportedBwModes_t)(unsafe.Pointer(SupportedBwMode)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetNvlinkSupportedBwModes(cnvmlDevice, cSupportedBwMode)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetNvlinkBwMode function as declared in nvml/nvml.h
func nvmlDeviceGetNvlinkBwMode(nvmlDevice nvmlDevice, GetBwMode *NvlinkGetBwMode) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cGetBwMode, _ := (*C.nvmlNvlinkGetBwMode_t)(unsafe.Pointer(GetBwMode)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetNvlinkBwMode(cnvmlDevice, cGetBwMode)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceSetNvlinkBwMode function as declared in nvml/nvml.h
func nvmlDeviceSetNvlinkBwMode(nvmlDevice nvmlDevice, SetBwMode *NvlinkSetBwMode) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cSetBwMode, _ := (*C.nvmlNvlinkSetBwMode_t)(unsafe.Pointer(SetBwMode)), cgoAllocsUnknown
__ret := C.nvmlDeviceSetNvlinkBwMode(cnvmlDevice, cSetBwMode)
__v := (Return)(__ret)
return __v
}
// nvmlEventSetCreate function as declared in nvml/nvml.h
func nvmlEventSetCreate(Set *nvmlEventSet) Return {
cSet, _ := (*C.nvmlEventSet_t)(unsafe.Pointer(Set)), cgoAllocsUnknown
@@ -2023,6 +2211,38 @@ func nvmlEventSetFree(Set nvmlEventSet) Return {
return __v
}
// nvmlSystemEventSetCreate function as declared in nvml/nvml.h
func nvmlSystemEventSetCreate(Request *SystemEventSetCreateRequest) Return {
cRequest, _ := (*C.nvmlSystemEventSetCreateRequest_t)(unsafe.Pointer(Request)), cgoAllocsUnknown
__ret := C.nvmlSystemEventSetCreate(cRequest)
__v := (Return)(__ret)
return __v
}
// nvmlSystemEventSetFree function as declared in nvml/nvml.h
func nvmlSystemEventSetFree(Request *SystemEventSetFreeRequest) Return {
cRequest, _ := (*C.nvmlSystemEventSetFreeRequest_t)(unsafe.Pointer(Request)), cgoAllocsUnknown
__ret := C.nvmlSystemEventSetFree(cRequest)
__v := (Return)(__ret)
return __v
}
// nvmlSystemRegisterEvents function as declared in nvml/nvml.h
func nvmlSystemRegisterEvents(Request *SystemRegisterEventRequest) Return {
cRequest, _ := (*C.nvmlSystemRegisterEventRequest_t)(unsafe.Pointer(Request)), cgoAllocsUnknown
__ret := C.nvmlSystemRegisterEvents(cRequest)
__v := (Return)(__ret)
return __v
}
// nvmlSystemEventSetWait function as declared in nvml/nvml.h
func nvmlSystemEventSetWait(Request *SystemEventSetWaitRequest) Return {
cRequest, _ := (*C.nvmlSystemEventSetWaitRequest_t)(unsafe.Pointer(Request)), cgoAllocsUnknown
__ret := C.nvmlSystemEventSetWait(cRequest)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceModifyDrainState function as declared in nvml/nvml.h
func nvmlDeviceModifyDrainState(PciInfo *PciInfo, NewState EnableState) Return {
cPciInfo, _ := (*C.nvmlPciInfo_t)(unsafe.Pointer(PciInfo)), cgoAllocsUnknown
@@ -2171,6 +2391,15 @@ func nvmlVgpuTypeGetFbReservation(nvmlVgpuTypeId nvmlVgpuTypeId, FbReservation *
return __v
}
// nvmlVgpuInstanceGetRuntimeStateSize function as declared in nvml/nvml.h
func nvmlVgpuInstanceGetRuntimeStateSize(nvmlVgpuInstance nvmlVgpuInstance, PState *VgpuRuntimeState) Return {
cnvmlVgpuInstance, _ := (C.nvmlVgpuInstance_t)(nvmlVgpuInstance), cgoAllocsUnknown
cPState, _ := (*C.nvmlVgpuRuntimeState_t)(unsafe.Pointer(PState)), cgoAllocsUnknown
__ret := C.nvmlVgpuInstanceGetRuntimeStateSize(cnvmlVgpuInstance, cPState)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceSetVgpuCapabilities function as declared in nvml/nvml.h
func nvmlDeviceSetVgpuCapabilities(nvmlDevice nvmlDevice, Capability DeviceVgpuCapability, State EnableState) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
@@ -2335,6 +2564,15 @@ func nvmlVgpuTypeGetMaxInstancesPerVm(nvmlVgpuTypeId nvmlVgpuTypeId, VgpuInstanc
return __v
}
// nvmlVgpuTypeGetBAR1Info function as declared in nvml/nvml.h
func nvmlVgpuTypeGetBAR1Info(nvmlVgpuTypeId nvmlVgpuTypeId, Bar1Info *VgpuTypeBar1Info) Return {
cnvmlVgpuTypeId, _ := (C.nvmlVgpuTypeId_t)(nvmlVgpuTypeId), cgoAllocsUnknown
cBar1Info, _ := (*C.nvmlVgpuTypeBar1Info_t)(unsafe.Pointer(Bar1Info)), cgoAllocsUnknown
__ret := C.nvmlVgpuTypeGetBAR1Info(cnvmlVgpuTypeId, cBar1Info)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetActiveVgpus function as declared in nvml/nvml.h
func nvmlDeviceGetActiveVgpus(nvmlDevice nvmlDevice, VgpuCount *uint32, VgpuInstances *nvmlVgpuInstance) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
@@ -2518,6 +2756,86 @@ func nvmlVgpuInstanceGetMdevUUID(nvmlVgpuInstance nvmlVgpuInstance, MdevUuid *by
return __v
}
// nvmlGpuInstanceGetCreatableVgpus function as declared in nvml/nvml.h
func nvmlGpuInstanceGetCreatableVgpus(nvmlGpuInstance nvmlGpuInstance, PVgpus *VgpuTypeIdInfo) Return {
cnvmlGpuInstance, _ := *(*C.nvmlGpuInstance_t)(unsafe.Pointer(&nvmlGpuInstance)), cgoAllocsUnknown
cPVgpus, _ := (*C.nvmlVgpuTypeIdInfo_t)(unsafe.Pointer(PVgpus)), cgoAllocsUnknown
__ret := C.nvmlGpuInstanceGetCreatableVgpus(cnvmlGpuInstance, cPVgpus)
__v := (Return)(__ret)
return __v
}
// nvmlVgpuTypeGetMaxInstancesPerGpuInstance function as declared in nvml/nvml.h
func nvmlVgpuTypeGetMaxInstancesPerGpuInstance(PMaxInstance *VgpuTypeMaxInstance) Return {
cPMaxInstance, _ := (*C.nvmlVgpuTypeMaxInstance_t)(unsafe.Pointer(PMaxInstance)), cgoAllocsUnknown
__ret := C.nvmlVgpuTypeGetMaxInstancesPerGpuInstance(cPMaxInstance)
__v := (Return)(__ret)
return __v
}
// nvmlGpuInstanceGetActiveVgpus function as declared in nvml/nvml.h
func nvmlGpuInstanceGetActiveVgpus(nvmlGpuInstance nvmlGpuInstance, PVgpuInstanceInfo *ActiveVgpuInstanceInfo) Return {
cnvmlGpuInstance, _ := *(*C.nvmlGpuInstance_t)(unsafe.Pointer(&nvmlGpuInstance)), cgoAllocsUnknown
cPVgpuInstanceInfo, _ := (*C.nvmlActiveVgpuInstanceInfo_t)(unsafe.Pointer(PVgpuInstanceInfo)), cgoAllocsUnknown
__ret := C.nvmlGpuInstanceGetActiveVgpus(cnvmlGpuInstance, cPVgpuInstanceInfo)
__v := (Return)(__ret)
return __v
}
// nvmlGpuInstanceSetVgpuSchedulerState function as declared in nvml/nvml.h
func nvmlGpuInstanceSetVgpuSchedulerState(nvmlGpuInstance nvmlGpuInstance, PScheduler *VgpuSchedulerState) Return {
cnvmlGpuInstance, _ := *(*C.nvmlGpuInstance_t)(unsafe.Pointer(&nvmlGpuInstance)), cgoAllocsUnknown
cPScheduler, _ := (*C.nvmlVgpuSchedulerState_t)(unsafe.Pointer(PScheduler)), cgoAllocsUnknown
__ret := C.nvmlGpuInstanceSetVgpuSchedulerState(cnvmlGpuInstance, cPScheduler)
__v := (Return)(__ret)
return __v
}
// nvmlGpuInstanceGetVgpuSchedulerState function as declared in nvml/nvml.h
func nvmlGpuInstanceGetVgpuSchedulerState(nvmlGpuInstance nvmlGpuInstance, PSchedulerStateInfo *VgpuSchedulerStateInfo) Return {
cnvmlGpuInstance, _ := *(*C.nvmlGpuInstance_t)(unsafe.Pointer(&nvmlGpuInstance)), cgoAllocsUnknown
cPSchedulerStateInfo, _ := (*C.nvmlVgpuSchedulerStateInfo_t)(unsafe.Pointer(PSchedulerStateInfo)), cgoAllocsUnknown
__ret := C.nvmlGpuInstanceGetVgpuSchedulerState(cnvmlGpuInstance, cPSchedulerStateInfo)
__v := (Return)(__ret)
return __v
}
// nvmlGpuInstanceGetVgpuSchedulerLog function as declared in nvml/nvml.h
func nvmlGpuInstanceGetVgpuSchedulerLog(nvmlGpuInstance nvmlGpuInstance, PSchedulerLogInfo *VgpuSchedulerLogInfo) Return {
cnvmlGpuInstance, _ := *(*C.nvmlGpuInstance_t)(unsafe.Pointer(&nvmlGpuInstance)), cgoAllocsUnknown
cPSchedulerLogInfo, _ := (*C.nvmlVgpuSchedulerLogInfo_t)(unsafe.Pointer(PSchedulerLogInfo)), cgoAllocsUnknown
__ret := C.nvmlGpuInstanceGetVgpuSchedulerLog(cnvmlGpuInstance, cPSchedulerLogInfo)
__v := (Return)(__ret)
return __v
}
// nvmlGpuInstanceGetVgpuTypeCreatablePlacements function as declared in nvml/nvml.h
func nvmlGpuInstanceGetVgpuTypeCreatablePlacements(nvmlGpuInstance nvmlGpuInstance, PCreatablePlacementInfo *VgpuCreatablePlacementInfo) Return {
cnvmlGpuInstance, _ := *(*C.nvmlGpuInstance_t)(unsafe.Pointer(&nvmlGpuInstance)), cgoAllocsUnknown
cPCreatablePlacementInfo, _ := (*C.nvmlVgpuCreatablePlacementInfo_t)(unsafe.Pointer(PCreatablePlacementInfo)), cgoAllocsUnknown
__ret := C.nvmlGpuInstanceGetVgpuTypeCreatablePlacements(cnvmlGpuInstance, cPCreatablePlacementInfo)
__v := (Return)(__ret)
return __v
}
// nvmlGpuInstanceGetVgpuHeterogeneousMode function as declared in nvml/nvml.h
func nvmlGpuInstanceGetVgpuHeterogeneousMode(nvmlGpuInstance nvmlGpuInstance, PHeterogeneousMode *VgpuHeterogeneousMode) Return {
cnvmlGpuInstance, _ := *(*C.nvmlGpuInstance_t)(unsafe.Pointer(&nvmlGpuInstance)), cgoAllocsUnknown
cPHeterogeneousMode, _ := (*C.nvmlVgpuHeterogeneousMode_t)(unsafe.Pointer(PHeterogeneousMode)), cgoAllocsUnknown
__ret := C.nvmlGpuInstanceGetVgpuHeterogeneousMode(cnvmlGpuInstance, cPHeterogeneousMode)
__v := (Return)(__ret)
return __v
}
// nvmlGpuInstanceSetVgpuHeterogeneousMode function as declared in nvml/nvml.h
func nvmlGpuInstanceSetVgpuHeterogeneousMode(nvmlGpuInstance nvmlGpuInstance, PHeterogeneousMode *VgpuHeterogeneousMode) Return {
cnvmlGpuInstance, _ := *(*C.nvmlGpuInstance_t)(unsafe.Pointer(&nvmlGpuInstance)), cgoAllocsUnknown
cPHeterogeneousMode, _ := (*C.nvmlVgpuHeterogeneousMode_t)(unsafe.Pointer(PHeterogeneousMode)), cgoAllocsUnknown
__ret := C.nvmlGpuInstanceSetVgpuHeterogeneousMode(cnvmlGpuInstance, cPHeterogeneousMode)
__v := (Return)(__ret)
return __v
}
// nvmlVgpuInstanceGetMetadata function as declared in nvml/nvml.h
func nvmlVgpuInstanceGetMetadata(nvmlVgpuInstance nvmlVgpuInstance, nvmlVgpuMetadata *nvmlVgpuMetadata, BufferSize *uint32) Return {
cnvmlVgpuInstance, _ := (C.nvmlVgpuInstance_t)(nvmlVgpuInstance), cgoAllocsUnknown
@@ -3062,45 +3380,74 @@ func nvmlGpmSetStreamingEnabled(nvmlDevice nvmlDevice, State uint32) Return {
return __v
}
// nvmlDeviceSetNvLinkDeviceLowPowerThreshold function as declared in nvml/nvml.h
func nvmlDeviceSetNvLinkDeviceLowPowerThreshold(nvmlDevice nvmlDevice, Info *NvLinkPowerThres) Return {
// nvmlDeviceGetCapabilities function as declared in nvml/nvml.h
func nvmlDeviceGetCapabilities(nvmlDevice nvmlDevice, Caps *DeviceCapabilities) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cInfo, _ := (*C.nvmlNvLinkPowerThres_t)(unsafe.Pointer(Info)), cgoAllocsUnknown
__ret := C.nvmlDeviceSetNvLinkDeviceLowPowerThreshold(cnvmlDevice, cInfo)
cCaps, _ := (*C.nvmlDeviceCapabilities_t)(unsafe.Pointer(Caps)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetCapabilities(cnvmlDevice, cCaps)
__v := (Return)(__ret)
return __v
}
// nvmlSystemSetNvlinkBwMode function as declared in nvml/nvml.h
func nvmlSystemSetNvlinkBwMode(NvlinkBwMode uint32) Return {
cNvlinkBwMode, _ := (C.uint)(NvlinkBwMode), cgoAllocsUnknown
__ret := C.nvmlSystemSetNvlinkBwMode(cNvlinkBwMode)
__v := (Return)(__ret)
return __v
}
// nvmlSystemGetNvlinkBwMode function as declared in nvml/nvml.h
func nvmlSystemGetNvlinkBwMode(NvlinkBwMode *uint32) Return {
cNvlinkBwMode, _ := (*C.uint)(unsafe.Pointer(NvlinkBwMode)), cgoAllocsUnknown
__ret := C.nvmlSystemGetNvlinkBwMode(cNvlinkBwMode)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceSetPowerManagementLimit_v2 function as declared in nvml/nvml.h
func nvmlDeviceSetPowerManagementLimit_v2(nvmlDevice nvmlDevice, PowerValue *PowerValue_v2) Return {
// nvmlDeviceWorkloadPowerProfileGetProfilesInfo function as declared in nvml/nvml.h
func nvmlDeviceWorkloadPowerProfileGetProfilesInfo(nvmlDevice nvmlDevice, ProfilesInfo *WorkloadPowerProfileProfilesInfo) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cPowerValue, _ := (*C.nvmlPowerValue_v2_t)(unsafe.Pointer(PowerValue)), cgoAllocsUnknown
__ret := C.nvmlDeviceSetPowerManagementLimit_v2(cnvmlDevice, cPowerValue)
cProfilesInfo, _ := (*C.nvmlWorkloadPowerProfileProfilesInfo_t)(unsafe.Pointer(ProfilesInfo)), cgoAllocsUnknown
__ret := C.nvmlDeviceWorkloadPowerProfileGetProfilesInfo(cnvmlDevice, cProfilesInfo)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetSramEccErrorStatus function as declared in nvml/nvml.h
func nvmlDeviceGetSramEccErrorStatus(nvmlDevice nvmlDevice, Status *EccSramErrorStatus) Return {
// nvmlDeviceWorkloadPowerProfileGetCurrentProfiles function as declared in nvml/nvml.h
func nvmlDeviceWorkloadPowerProfileGetCurrentProfiles(nvmlDevice nvmlDevice, CurrentProfiles *WorkloadPowerProfileCurrentProfiles) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cStatus, _ := (*C.nvmlEccSramErrorStatus_t)(unsafe.Pointer(Status)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetSramEccErrorStatus(cnvmlDevice, cStatus)
cCurrentProfiles, _ := (*C.nvmlWorkloadPowerProfileCurrentProfiles_t)(unsafe.Pointer(CurrentProfiles)), cgoAllocsUnknown
__ret := C.nvmlDeviceWorkloadPowerProfileGetCurrentProfiles(cnvmlDevice, cCurrentProfiles)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceWorkloadPowerProfileSetRequestedProfiles function as declared in nvml/nvml.h
func nvmlDeviceWorkloadPowerProfileSetRequestedProfiles(nvmlDevice nvmlDevice, RequestedProfiles *WorkloadPowerProfileRequestedProfiles) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cRequestedProfiles, _ := (*C.nvmlWorkloadPowerProfileRequestedProfiles_t)(unsafe.Pointer(RequestedProfiles)), cgoAllocsUnknown
__ret := C.nvmlDeviceWorkloadPowerProfileSetRequestedProfiles(cnvmlDevice, cRequestedProfiles)
__v := (Return)(__ret)
return __v
}
// nvmlDeviceWorkloadPowerProfileClearRequestedProfiles function as declared in nvml/nvml.h
func nvmlDeviceWorkloadPowerProfileClearRequestedProfiles(nvmlDevice nvmlDevice, RequestedProfiles *WorkloadPowerProfileRequestedProfiles) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cRequestedProfiles, _ := (*C.nvmlWorkloadPowerProfileRequestedProfiles_t)(unsafe.Pointer(RequestedProfiles)), cgoAllocsUnknown
__ret := C.nvmlDeviceWorkloadPowerProfileClearRequestedProfiles(cnvmlDevice, cRequestedProfiles)
__v := (Return)(__ret)
return __v
}
// nvmlDevicePowerSmoothingActivatePresetProfile function as declared in nvml/nvml.h
func nvmlDevicePowerSmoothingActivatePresetProfile(nvmlDevice nvmlDevice, Profile *PowerSmoothingProfile) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cProfile, _ := (*C.nvmlPowerSmoothingProfile_t)(unsafe.Pointer(Profile)), cgoAllocsUnknown
__ret := C.nvmlDevicePowerSmoothingActivatePresetProfile(cnvmlDevice, cProfile)
__v := (Return)(__ret)
return __v
}
// nvmlDevicePowerSmoothingUpdatePresetProfileParam function as declared in nvml/nvml.h
func nvmlDevicePowerSmoothingUpdatePresetProfileParam(nvmlDevice nvmlDevice, Profile *PowerSmoothingProfile) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cProfile, _ := (*C.nvmlPowerSmoothingProfile_t)(unsafe.Pointer(Profile)), cgoAllocsUnknown
__ret := C.nvmlDevicePowerSmoothingUpdatePresetProfileParam(cnvmlDevice, cProfile)
__v := (Return)(__ret)
return __v
}
// nvmlDevicePowerSmoothingSetState function as declared in nvml/nvml.h
func nvmlDevicePowerSmoothingSetState(nvmlDevice nvmlDevice, State *PowerSmoothingState) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cState, _ := (*C.nvmlPowerSmoothingState_t)(unsafe.Pointer(State)), cgoAllocsUnknown
__ret := C.nvmlDevicePowerSmoothingSetState(cnvmlDevice, cState)
__v := (Return)(__ret)
return __v
}
@@ -3308,3 +3655,13 @@ func nvmlVgpuInstanceGetLicenseInfo_v1(nvmlVgpuInstance nvmlVgpuInstance, Licens
__v := (Return)(__ret)
return __v
}
// nvmlDeviceGetDriverModel_v1 function as declared in nvml/nvml.h
func nvmlDeviceGetDriverModel_v1(nvmlDevice nvmlDevice, Current *DriverModel, Pending *DriverModel) Return {
cnvmlDevice, _ := *(*C.nvmlDevice_t)(unsafe.Pointer(&nvmlDevice)), cgoAllocsUnknown
cCurrent, _ := (*C.nvmlDriverModel_t)(unsafe.Pointer(Current)), cgoAllocsUnknown
cPending, _ := (*C.nvmlDriverModel_t)(unsafe.Pointer(Pending)), cgoAllocsUnknown
__ret := C.nvmlDeviceGetDriverModel(cnvmlDevice, cCurrent, cPending)
__v := (Return)(__ret)
return __v
}

Some files were not shown because too many files have changed in this diff Show More