Skip to content

Commit 6602179

Browse files
authored
Merge pull request #179 from klueska/discover-imex-major
Add function to discover IMEX major number rather than hard-coding it
2 parents 7ddfa53 + ebb9c42 commit 6602179

File tree

1 file changed

+56
-2
lines changed

1 file changed

+56
-2
lines changed

cmd/nvidia-dra-plugin/nvlib.go

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
package main
1818

1919
import (
20+
"bufio"
2021
"fmt"
2122
"os"
2223
"os/exec"
2324
"path/filepath"
25+
"strconv"
2426
"strings"
2527

2628
"golang.org/x/sys/unix"
@@ -30,6 +32,11 @@ import (
3032
"github.com/NVIDIA/go-nvml/pkg/nvml"
3133
)
3234

35+
const (
36+
procDevicesPath = "/proc/devices"
37+
nvidiaCapsImexChannelsDeviceName = "nvidia-caps-imex-channels"
38+
)
39+
3340
type deviceLib struct {
3441
nvdev.Interface
3542
nvmllib nvml.Interface
@@ -400,14 +407,61 @@ func (l deviceLib) getImexChannelCount() (int, error) {
400407
return 2048, nil
401408
}
402409

410+
func (l deviceLib) getImexChannelMajor() (int, error) {
411+
file, err := os.Open(procDevicesPath)
412+
if err != nil {
413+
return -1, err
414+
}
415+
defer file.Close()
416+
417+
scanner := bufio.NewScanner(file)
418+
foundCharDevices := false
419+
420+
for scanner.Scan() {
421+
line := scanner.Text()
422+
423+
// Ignore empty lines
424+
if line == "" {
425+
continue
426+
}
427+
428+
// Check for any line with text followed by a colon (header)
429+
if strings.Contains(line, ":") {
430+
// Stop if we've already found the character devices section and reached another section
431+
if foundCharDevices {
432+
break
433+
}
434+
// Check if we entered the character devices section
435+
if strings.HasSuffix(line, ":") && strings.HasPrefix(line, "Character") {
436+
foundCharDevices = true
437+
}
438+
// Continue to the next line, regardless
439+
continue
440+
}
441+
442+
// If we've passed the character devices section, check for nvidiaCapsImexChannelsDeviceName
443+
if foundCharDevices {
444+
parts := strings.Fields(line)
445+
if len(parts) == 2 && parts[1] == nvidiaCapsImexChannelsDeviceName {
446+
return strconv.Atoi(parts[0])
447+
}
448+
}
449+
}
450+
451+
return -1, scanner.Err()
452+
}
453+
403454
func (l deviceLib) createImexChannelDevice(channel int) error {
404455
// Construct the properties of the device node to create.
405456
path := fmt.Sprintf("/dev/nvidia-caps-imex-channels/channel%d", channel)
406457
path = filepath.Join(l.devRoot, path)
407458
mode := uint32(unix.S_IFCHR | 0666)
408459

409-
// TODO: Pull the major value from /proc/devices
410-
major := 236
460+
// Get the IMEX channel major and build a /dev device from it
461+
major, err := l.getImexChannelMajor()
462+
if err != nil {
463+
return fmt.Errorf("error getting IMEX channel major: %w", err)
464+
}
411465
dev := unix.Mkdev(uint32(major), uint32(channel))
412466

413467
// Recursively create any parent directories of the channel.

0 commit comments

Comments
 (0)