Skip to content

Commit

Permalink
Merge pull request #343 from jaypipes/fix-341
Browse files Browse the repository at this point in the history
only process memory cell/block subdirs in sysfs
  • Loading branch information
ffromani authored May 8, 2023
2 parents 159b397 + f62e6fb commit 29cf834
Showing 1 changed file with 28 additions and 16 deletions.
44 changes: 28 additions & 16 deletions pkg/memory/memory_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ var (
// System log lines will look similar to the following:
// ... kernel: [0.000000] Memory: 24633272K/25155024K ...
_REGEX_SYSLOG_MEMLINE = regexp.MustCompile(`Memory:\s+\d+K\/(\d+)K`)
// regexMemoryBlockDirname matches a subdirectory in either
// /sys/devices/system/memory or /sys/devices/system/node/nodeX that
// represents information on a specific memory cell/block
regexMemoryBlockDirname = regexp.MustCompile(`memory\d+$`)
)

func (i *Info) load() error {
Expand Down Expand Up @@ -137,29 +141,37 @@ func memTotalPhysicalBytes(paths *linuxpath.Paths) (total int64) {
return total
}

// memoryTotalPhysicalBytesFromPath accepts a directory -- either
// /sys/devices/system/memory (for the entire system) or
// /sys/devices/system/node/nodeX (for a specific NUMA node) -- and a block
// size in bytes and iterates over the sysfs memory block subdirectories,
// accumulating blocks that are "online" to determine a total physical memory
// size in bytes
func memoryTotalPhysicalBytesFromPath(dir string, blockSizeBytes uint64) (int64, error) {
// iterate over memory's block /sys/.../memory*,
// if the memory block state is 'online' we increment the total
// with the memory block size to determine the amount of physical
// memory available on this system.
// This works for both system-wide:
// /sys/devices/system/memory/memory*
// and for per-numa-node report:
// /sys/devices/system/node/node*/memory*

sysMemory, err := filepath.Glob(filepath.Join(dir, "memory*"))
var total int64
files, err := ioutil.ReadDir(dir)
if err != nil {
return -1, err
} else if sysMemory == nil {
return -1, fmt.Errorf("cannot find memory entries in %q", dir)
}

var total int64
for _, path := range sysMemory {
s, err := ioutil.ReadFile(filepath.Join(path, "state"))
// There are many subdirectories of /sys/devices/system/memory or
// /sys/devices/system/node/nodeX that are named memory{cell} where {cell}
// is a 0-based index of the memory block. These subdirectories contain a
// state file (e.g. /sys/devices/system/memory/memory64/state that will
// contain the string "online" if that block is active.
for _, file := range files {
fname := file.Name()
// NOTE(jaypipes): we cannot rely on file.IsDir() here because the
// memory{cell} sysfs directories are not actual directories.
if !regexMemoryBlockDirname.MatchString(fname) {
continue
}
s, err := ioutil.ReadFile(filepath.Join(dir, fname, "state"))
if err != nil {
return -1, err
}
// if the memory block state is 'online' we increment the total with
// the memory block size to determine the amount of physical
// memory available on this system.
if strings.TrimSpace(string(s)) != "online" {
continue
}
Expand Down

0 comments on commit 29cf834

Please sign in to comment.