github.com/rawahars/moby@v24.0.4+incompatible/pkg/meminfo/meminfo_linux.go (about) 1 package meminfo 2 3 import ( 4 "bufio" 5 "io" 6 "os" 7 "strconv" 8 "strings" 9 ) 10 11 // readMemInfo retrieves memory statistics of the host system and returns a 12 // Memory type. 13 func readMemInfo() (*Memory, error) { 14 file, err := os.Open("/proc/meminfo") 15 if err != nil { 16 return nil, err 17 } 18 defer file.Close() 19 return parseMemInfo(file) 20 } 21 22 // parseMemInfo parses the /proc/meminfo file into 23 // a Memory object given an io.Reader to the file. 24 // Throws error if there are problems reading from the file 25 func parseMemInfo(reader io.Reader) (*Memory, error) { 26 meminfo := &Memory{} 27 scanner := bufio.NewScanner(reader) 28 memAvailable := int64(-1) 29 for scanner.Scan() { 30 // Expected format: ["MemTotal:", "1234", "kB"] 31 parts := strings.Fields(scanner.Text()) 32 33 // Sanity checks: Skip malformed entries. 34 if len(parts) < 3 || parts[2] != "kB" { 35 continue 36 } 37 38 // Convert to bytes. 39 size, err := strconv.Atoi(parts[1]) 40 if err != nil { 41 continue 42 } 43 // Convert to KiB 44 bytes := int64(size) * 1024 45 46 switch parts[0] { 47 case "MemTotal:": 48 meminfo.MemTotal = bytes 49 case "MemFree:": 50 meminfo.MemFree = bytes 51 case "MemAvailable:": 52 memAvailable = bytes 53 case "SwapTotal:": 54 meminfo.SwapTotal = bytes 55 case "SwapFree:": 56 meminfo.SwapFree = bytes 57 } 58 } 59 if memAvailable != -1 { 60 meminfo.MemFree = memAvailable 61 } 62 63 // Handle errors that may have occurred during the reading of the file. 64 if err := scanner.Err(); err != nil { 65 return nil, err 66 } 67 68 return meminfo, nil 69 }