github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/pkg/system/meminfo_linux.go (about)

     1  package system // import "github.com/demonoid81/moby/pkg/system"
     2  
     3  import (
     4  	"bufio"
     5  	"io"
     6  	"os"
     7  	"strconv"
     8  	"strings"
     9  
    10  	units "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  	memAvailable := int64(-1)
    31  	for scanner.Scan() {
    32  		// Expected format: ["MemTotal:", "1234", "kB"]
    33  		parts := strings.Fields(scanner.Text())
    34  
    35  		// Sanity checks: Skip malformed entries.
    36  		if len(parts) < 3 || parts[2] != "kB" {
    37  			continue
    38  		}
    39  
    40  		// Convert to bytes.
    41  		size, err := strconv.Atoi(parts[1])
    42  		if err != nil {
    43  			continue
    44  		}
    45  		bytes := int64(size) * units.KiB
    46  
    47  		switch parts[0] {
    48  		case "MemTotal:":
    49  			meminfo.MemTotal = bytes
    50  		case "MemFree:":
    51  			meminfo.MemFree = bytes
    52  		case "MemAvailable:":
    53  			memAvailable = bytes
    54  		case "SwapTotal:":
    55  			meminfo.SwapTotal = bytes
    56  		case "SwapFree:":
    57  			meminfo.SwapFree = bytes
    58  		}
    59  
    60  	}
    61  	if memAvailable != -1 {
    62  		meminfo.MemFree = memAvailable
    63  	}
    64  
    65  	// Handle errors that may have occurred during the reading of the file.
    66  	if err := scanner.Err(); err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	return meminfo, nil
    71  }