1717package main
1818
1919import (
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+
3340type 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+
403454func (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