introduce basic fact collection
This commit is contained in:
121
client/vendor/github.com/zcalusic/sysinfo/memory.go
generated
vendored
Normal file
121
client/vendor/github.com/zcalusic/sysinfo/memory.go
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright © 2016 Zlatko Čalušić
|
||||
//
|
||||
// Use of this source code is governed by an MIT-style license that can be found in the LICENSE file.
|
||||
|
||||
package sysinfo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Memory information.
|
||||
type Memory struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Speed uint `json:"speed,omitempty"` // RAM data rate in MT/s
|
||||
Size uint `json:"size,omitempty"` // RAM size in MB
|
||||
}
|
||||
|
||||
func word(data []byte, index int) uint16 {
|
||||
return binary.LittleEndian.Uint16(data[index : index+2])
|
||||
}
|
||||
|
||||
func dword(data []byte, index int) uint32 {
|
||||
return binary.LittleEndian.Uint32(data[index : index+4])
|
||||
}
|
||||
|
||||
func qword(data []byte, index int) uint64 {
|
||||
return binary.LittleEndian.Uint64(data[index : index+8])
|
||||
}
|
||||
|
||||
func (si *SysInfo) getMemoryInfo() {
|
||||
dmi, err := os.ReadFile("/sys/firmware/dmi/tables/DMI")
|
||||
if err != nil {
|
||||
// Xen hypervisor
|
||||
if targetKB := slurpFile("/sys/devices/system/xen_memory/xen_memory0/target_kb"); targetKB != "" {
|
||||
si.Memory.Type = "DRAM"
|
||||
size, _ := strconv.ParseUint(targetKB, 10, 64)
|
||||
si.Memory.Size = uint(size) / 1024
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
si.Memory.Size = 0
|
||||
var memSizeAlt uint
|
||||
loop:
|
||||
for p := 0; p < len(dmi)-1; {
|
||||
recType := dmi[p]
|
||||
recLen := dmi[p+1]
|
||||
|
||||
switch recType {
|
||||
case 4:
|
||||
if si.CPU.Speed == 0 {
|
||||
si.CPU.Speed = uint(word(dmi, p+0x16))
|
||||
}
|
||||
case 17:
|
||||
size := uint(word(dmi, p+0x0c))
|
||||
if size == 0 || size == 0xffff || size&0x8000 == 0x8000 {
|
||||
break
|
||||
}
|
||||
if size == 0x7fff {
|
||||
if recLen >= 0x20 {
|
||||
size = uint(dword(dmi, p+0x1c))
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
si.Memory.Size += size
|
||||
|
||||
if si.Memory.Type == "" {
|
||||
// SMBIOS Reference Specification Version 3.0.0, page 92
|
||||
memTypes := [...]string{
|
||||
"Other", "Unknown", "DRAM", "EDRAM", "VRAM", "SRAM", "RAM", "ROM", "FLASH",
|
||||
"EEPROM", "FEPROM", "EPROM", "CDRAM", "3DRAM", "SDRAM", "SGRAM", "RDRAM",
|
||||
"DDR", "DDR2", "DDR2 FB-DIMM", "Reserved", "Reserved", "Reserved", "DDR3",
|
||||
"FBD2", "DDR4", "LPDDR", "LPDDR2", "LPDDR3", "LPDDR4",
|
||||
}
|
||||
|
||||
if index := int(dmi[p+0x12]); index >= 1 && index <= len(memTypes) {
|
||||
si.Memory.Type = memTypes[index-1]
|
||||
}
|
||||
}
|
||||
|
||||
if si.Memory.Speed == 0 && recLen >= 0x17 {
|
||||
if speed := uint(word(dmi, p+0x15)); speed != 0 {
|
||||
si.Memory.Speed = speed
|
||||
}
|
||||
}
|
||||
case 19:
|
||||
start := uint(dword(dmi, p+0x04))
|
||||
end := uint(dword(dmi, p+0x08))
|
||||
if start == 0xffffffff && end == 0xffffffff {
|
||||
if recLen >= 0x1f {
|
||||
start64 := qword(dmi, p+0x0f)
|
||||
end64 := qword(dmi, p+0x17)
|
||||
memSizeAlt += uint((end64 - start64 + 1) / 1048576)
|
||||
}
|
||||
} else {
|
||||
memSizeAlt += (end - start + 1) / 1024
|
||||
}
|
||||
case 127:
|
||||
break loop
|
||||
}
|
||||
|
||||
for p += int(recLen); p < len(dmi)-1; {
|
||||
if bytes.Equal(dmi[p:p+2], []byte{0, 0}) {
|
||||
p += 2
|
||||
break
|
||||
}
|
||||
p++
|
||||
}
|
||||
}
|
||||
|
||||
// Sometimes DMI type 17 has no information, so we fall back to DMI type 19, to at least get the RAM size.
|
||||
if si.Memory.Size == 0 && memSizeAlt > 0 {
|
||||
si.Memory.Type = "DRAM"
|
||||
si.Memory.Size = memSizeAlt
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user