Repository: prometheus/procfs
Pull request #306 (2020-06-06 09:58:42)

Add MIPS cpuinfo support
Add CPUInfo parsing for MIPS.

https://github.com/prometheus/node_exporter/pull/1735

Signed-off-by: Ben Kochie <superq@gmail.com>


Patch:
diff --git a/cpuinfo.go b/cpuinfo.go
index d19ce85..31d42f7 100644
--- a/cpuinfo.go
+++ b/cpuinfo.go
@@ -319,6 +319,49 @@ func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {
 	return cpuinfo, nil
 }
 
+func parseCPUInfoMips(info []byte) ([]CPUInfo, error) {
+	scanner := bufio.NewScanner(bytes.NewReader(info))
+
+	// find the first "processor" line
+	firstLine := firstNonEmptyLine(scanner)
+	if !strings.HasPrefix(firstLine, "system type") || !strings.Contains(firstLine, ":") {
+		return nil, errors.New("invalid cpuinfo file: " + firstLine)
+	}
+	field := strings.SplitN(firstLine, ": ", 2)
+	cpuinfo := []CPUInfo{}
+	systemType := field[1]
+
+	i := 0
+
+	for scanner.Scan() {
+		line := scanner.Text()
+		if !strings.Contains(line, ":") {
+			continue
+		}
+		field := strings.SplitN(line, ": ", 2)
+		switch strings.TrimSpace(field[0]) {
+		case "processor":
+			v, err := strconv.ParseUint(field[1], 0, 32)
+			if err != nil {
+				return nil, err
+			}
+			i = int(v)
+			cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor
+			cpuinfo[i].Processor = uint(v)
+			cpuinfo[i].VendorID = systemType
+		case "cpu model":
+			cpuinfo[i].ModelName = field[1]
+		case "BogoMIPS":
+			v, err := strconv.ParseFloat(field[1], 64)
+			if err != nil {
+				return nil, err
+			}
+			cpuinfo[i].BogoMips = v
+		}
+	}
+	return cpuinfo, nil
+}
+
 func parseCPUInfoPPC(info []byte) ([]CPUInfo, error) {
 	scanner := bufio.NewScanner(bytes.NewReader(info))
 
diff --git a/cpuinfo_mips.go b/cpuinfo_mips.go
new file mode 100644
index 0000000..22d93f8
--- /dev/null
+++ b/cpuinfo_mips.go
@@ -0,0 +1,18 @@
+// Copyright 2020 The Prometheus Authors
+// 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.
+
+// +build linux
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoMips


Test patch:
diff --git a/cpuinfo_test.go b/cpuinfo_test.go
index 17eefbe..a8536d2 100644
--- a/cpuinfo_test.go
+++ b/cpuinfo_test.go
@@ -129,6 +129,43 @@ cpu MHz static  : 5000
 cpu number      : 3
 cpu MHz dynamic : 5000
 cpu MHz static  : 5000
+`
+
+	cpuinfoMips = `
+system type		: UBNT_E100
+machine			: Unknown
+processor		: 0
+cpu model		: Cavium Octeon+ V0.1
+BogoMIPS		: 1000.00
+wait instruction	: yes
+microsecond timers	: yes
+tlb_entries		: 64
+extra interrupt vector	: yes
+hardware watchpoint	: yes, count: 2, address/irw mask: [0x0ffc, 0x0ffb]
+isa			: mips1 mips2 mips3 mips4 mips5 mips64r2
+ASEs implemented	:
+shadow register sets	: 1
+kscratch registers	: 0
+core			: 0
+VCED exceptions		: not available
+VCEI exceptions		: not available
+
+processor		: 1
+cpu model		: Cavium Octeon+ V0.1
+BogoMIPS		: 1000.00
+wait instruction	: yes
+microsecond timers	: yes
+tlb_entries		: 64
+extra interrupt vector	: yes
+hardware watchpoint	: yes, count: 2, address/irw mask: [0x0ffc, 0x0ffb]
+isa			: mips1 mips2 mips3 mips4 mips5 mips64r2
+ASEs implemented	:
+shadow register sets	: 1
+kscratch registers	: 0
+core			: 1
+VCED exceptions		: not available
+VCEI exceptions		: not available
+
 `
 
 	cpuinfoPpc64 = `
@@ -279,6 +316,22 @@ func TestCPUInfoParseS390X(t *testing.T) {
 	}
 }
 
+func TestCPUInfoParseMips(t *testing.T) {
+	cpuinfo, err := parseCPUInfoMips([]byte(cpuinfoMips))
+	if err != nil || cpuinfo == nil {
+		t.Fatalf("unable to parse mips cpu info: %v", err)
+	}
+	if want, have := 2, len(cpuinfo); want != have {
+		t.Errorf("want number of processors %v, have %v", want, have)
+	}
+	if want, have := 1000.00, cpuinfo[0].BogoMips; want != have {
+		t.Errorf("want BogoMIPS %v, have %v", want, have)
+	}
+	if want, have := "Cavium Octeon+ V0.1", cpuinfo[1].ModelName; want != have {
+		t.Errorf("want ModelName '%v', have '%v'", want, have)
+	}
+}
+
 func TestCPUInfoParsePPC(t *testing.T) {
 	cpuinfo, err := parseCPUInfoPPC([]byte(cpuinfoPpc64))
 	if err != nil || cpuinfo == nil {