[lxc-devel] [lxd/master] Fall back to alternate way of detecting minor version of Nvidia drivers if needed

dankegel on Github lxc-bot at linuxcontainers.org
Fri Jun 1 22:57:21 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 523 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180601/645d68a1/attachment.bin>
-------------- next part --------------
From aec885049fd900f3dd77f821d821773f4c768c7e Mon Sep 17 00:00:00 2001
From: Dan Kegel <dank at kegel.com>
Date: Fri, 1 Jun 2018 14:40:18 -0700
Subject: [PATCH] Fall back to alternate way of detecting minor version of
 Nvidia driver if needed

findNvidiaMinorOld() only handles the most common case; it's a bit of a placeholder,
but should reduce user complaints.

Signed-off-by: Dan Kegel <dank at kegel.com>
---
 lxd/devices.go | 89 ++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 61 insertions(+), 28 deletions(-)

diff --git a/lxd/devices.go b/lxd/devices.go
index 91bb5df26..9f7f4e1fb 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -101,6 +101,65 @@ type cardIds struct {
 	pci string
 }
 
+// Fallback for old drivers which don't provide "Device Minor:"
+func findNvidiaMinorOld() (string, error) {
+	var minor string;
+
+	// Handle single nvidia card with driver too old to report device minor
+	ents, err := ioutil.ReadDir("/dev")
+	if err != nil {
+		return "", err
+	}
+	for _, ent := range ents {
+		rp := regexp.MustCompile("^nvidia([0-9]+)$")
+		matches := rp.FindStringSubmatch(ent.Name())
+		if matches == nil {
+			continue
+		}
+		if minor != "" {
+			return "", fmt.Errorf("No device minor index detected, and more than one Nvidia card present")
+		}
+		minor = matches[1]
+	}
+	if minor == "" {
+		return "", fmt.Errorf("No device minor index detected, and no Nvidia card present?!")
+	}
+	return minor, nil
+}
+
+// Return string for minor number of nvidia device corresponding to the given pci id
+func findNvidiaMinor(pci string) (string, error) {
+	nvidiaPath := fmt.Sprintf("/proc/driver/nvidia/gpus/%s/information", pci)
+	buf, err := ioutil.ReadFile(nvidiaPath)
+	if err != nil {
+		return "", err
+	}
+
+	strBuf := strings.TrimSpace(string(buf))
+	idx := strings.Index(strBuf, "Device Minor:")
+	if idx != -1 {
+		idx += len("Device Minor:")
+		strBuf = strBuf[idx:]
+		strBuf = strings.TrimSpace(strBuf)
+		idx = strings.Index(strBuf, " ")
+		if idx == -1 {
+			idx = strings.Index(strBuf, "\t")
+		}
+		if idx >= 1 {
+			minor := strBuf[:idx]
+			_, err = strconv.Atoi(minor)
+			if err == nil {
+				return minor, nil
+			}
+		}
+	}
+	minor, err := findNvidiaMinorOld()
+	if err == nil {
+		return minor, nil
+	}
+	return "", err
+}
+
 func deviceLoadGpu() ([]gpuDevice, []nvidiaGpuDevices, error) {
 	const DRI_PATH = "/sys/bus/pci/devices"
 	var gpus []gpuDevice
@@ -200,41 +259,15 @@ func deviceLoadGpu() ([]gpuDevice, []nvidiaGpuDevices, error) {
 					isNvidia = true
 				}
 
-				nvidiaPath := fmt.Sprintf("/proc/driver/nvidia/gpus/%s/information", tmpGpu.pci)
-				buf, err := ioutil.ReadFile(nvidiaPath)
+				minor, err := findNvidiaMinor(tmpGpu.pci)
 				if err != nil {
 					if os.IsNotExist(err) {
 						continue
 					}
-
-					return nil, nil, err
-				}
-				strBuf := strings.TrimSpace(string(buf))
-				idx := strings.Index(strBuf, "Device Minor:")
-				if idx == -1 {
-					return nil, nil, fmt.Errorf("No device minor index detected")
-				}
-				idx += len("Device Minor:")
-				strBuf = strBuf[idx:]
-				strBuf = strings.TrimSpace(strBuf)
-				idx = strings.Index(strBuf, " ")
-				if idx == -1 {
-					idx = strings.Index(strBuf, "\t")
-				}
-				if idx >= 1 {
-					strBuf = strBuf[:idx]
-				}
-
-				if strBuf == "" {
-					return nil, nil, fmt.Errorf("No device minor index detected")
-				}
-
-				_, err = strconv.Atoi(strBuf)
-				if err != nil {
 					return nil, nil, err
 				}
 
-				nvidiaPath = "/dev/nvidia" + strBuf
+				nvidiaPath := "/dev/nvidia" + minor
 				stat := syscall.Stat_t{}
 				err = syscall.Stat(nvidiaPath, &stat)
 				if err != nil {


More information about the lxc-devel mailing list