github.com/sijibomii/docker@v0.0.0-20231230191044-5cf6ca554647/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  }