github.com/uriddle/docker@v0.0.0-20210926094723-4072e6aeb013/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 a io.Reader to the file.
    26  //
    27  // Throws error if there are problems reading from the file
    28  func parseMemInfo(reader io.Reader) (*MemInfo, error) {
    29  	meminfo := &MemInfo{}
    30  	scanner := bufio.NewScanner(reader)
    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 "SwapTotal:":
    53  			meminfo.SwapTotal = bytes
    54  		case "SwapFree:":
    55  			meminfo.SwapFree = bytes
    56  		}
    57  
    58  	}
    59  
    60  	// Handle errors that may have occurred during the reading of the file.
    61  	if err := scanner.Err(); err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	return meminfo, nil
    66  }