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