SUSE/saptune

View on GitHub
system/mem.go

Summary

Maintainability
A
0 mins
Test Coverage
B
85%
package system

// Gather information about system memory and swap memory.

import (
    "fmt"
    "os"
    "strconv"
    "strings"
)

// string definitions for parsing /proc/meminfo output
const (
    MemMainTotalKey = "MemTotal"
    MemSwapTotalKey = "SwapTotal"
)

// ParseMeminfo parse /proc/meminfo into key(string) - value(int) pairs.
// Panic on error.
func ParseMeminfo() (infoMap map[string]uint64) {
    infoMap = make(map[string]uint64)
    memInfo, err := os.ReadFile("/proc/meminfo")
    if err != nil {
        panic(fmt.Errorf("failed to read /proc/meminfo: %v", err))
    }
    for _, line := range strings.Split(string(memInfo), "\n") {
        fields := consecutiveSpaces.Split(strings.TrimSpace(line), -1)
        if len(fields) <= 1 {
            continue
        }
        // First field is name with a suffix colon
        name := fields[0]
        // The second field is an integer value
        value, err := strconv.ParseUint(fields[1], 10, 64)
        if err != nil {
            panic(fmt.Errorf("failed to parse uint64 value from '%s' in /proc/meminfo", line))
        }
        infoMap[name[0:len(name)-1]] = value
    }
    return
}

// GetMainMemSizeMB return size of system main memory, excluding swap.
// Panic on error.
func GetMainMemSizeMB() uint64 {
    InfoLog("GetMainMemSizeMB - MemTotal is '%+v'\n", ParseMeminfo()[MemMainTotalKey])
    return ParseMeminfo()[MemMainTotalKey] / 1024
}

// GetTotalMemSizeMB return size of system main memory plus swap.
// Panic on error.
func GetTotalMemSizeMB() uint64 {
    InfoLog("GetTotalMemSizeMB - MemTotal is '%+v', SwapTotal is '%+v'\n", ParseMeminfo()[MemMainTotalKey], ParseMeminfo()[MemSwapTotalKey])
    return (ParseMeminfo()[MemMainTotalKey] + ParseMeminfo()[MemSwapTotalKey]) / 1024
}

// GetTotalMemSizePages return size of system main memory plus swap, in pages.
// Panic on error.
func GetTotalMemSizePages() uint64 {
    InfoLog("GetTotalMemSizePages - MemTotal is '%+v', SwapTotal is '%+v', pagesize is '%+v'('%+v')\n", ParseMeminfo()[MemMainTotalKey], ParseMeminfo()[MemSwapTotalKey], os.Getpagesize(), uint64(os.Getpagesize()))
    return (ParseMeminfo()[MemMainTotalKey] + ParseMeminfo()[MemSwapTotalKey]) / uint64(os.Getpagesize())
}

// GetSemaphoreLimits return kernel semaphore limits. Panic on error.
func GetSemaphoreLimits() (msl, mns, opm, mni uint64) {
    field, err := GetSysctlString("kernel.sem")
    if err != nil {
        _ = fmt.Errorf("failed to read kernel.sem values")
    }
    fields := consecutiveSpaces.Split(field, -1)
    if len(fields) < 4 {
        panic(fmt.Errorf("failed to read kernel.sem values: %v", fields))
    }
    for i, val := range []*uint64{&msl, &mns, &opm, &mni} {
        if *val, err = strconv.ParseUint(fields[i], 10, 64); err != nil {
            panic(fmt.Errorf("failed to parse kernel.sem values: %v", err))
        }
    }
    return
}