[lxc-devel] [lxd/master] lxd/resources/memory: Fix memory calculation

monstermunchkin on Github lxc-bot at linuxcontainers.org
Fri May 15 09:32:02 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 501 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200515/5751b5b6/attachment-0001.bin>
-------------- next part --------------
From 7223c37b193771bfe14fc98d2a59168e6fdd585d Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Fri, 15 May 2020 11:29:21 +0200
Subject: [PATCH] lxd/resources/memory: Fix memory calculation

This calculates the total memory from /sys/devices/system/memory, and
replaces the previously retrieved value if successful.

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/resources/memory.go | 62 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/lxd/resources/memory.go b/lxd/resources/memory.go
index 7a0de098b4..644503cb8d 100644
--- a/lxd/resources/memory.go
+++ b/lxd/resources/memory.go
@@ -15,6 +15,7 @@ import (
 )
 
 var sysDevicesNode = "/sys/devices/system/node"
+var sysDevicesSystemMemory = "/sys/devices/system/memory"
 
 type meminfo struct {
 	Cached         uint64
@@ -134,6 +135,60 @@ func parseMeminfo(path string) (*meminfo, error) {
 	return &memory, nil
 }
 
+func getTotalMemory() uint64 {
+	memoryBlockSizePath := filepath.Join(sysDevicesSystemMemory, "block_size_bytes")
+
+	if !sysfsExists(memoryBlockSizePath) {
+		return 0
+	}
+
+	// Get block size
+	content, err := ioutil.ReadFile(memoryBlockSizePath)
+	if err != nil {
+		return 0
+	}
+
+	blockSize, err := strconv.ParseUint(strings.TrimSpace(string(content)), 16, 64)
+	if err != nil {
+		return 0
+	}
+
+	var count uint64 = 0
+
+	entries, err := ioutil.ReadDir(sysDevicesSystemMemory)
+	if err != nil {
+		return 0
+	}
+
+	// Count the number of blocks
+	for _, entry := range entries {
+		// Only consider directories
+		if !entry.IsDir() {
+			continue
+		}
+
+		entryName := entry.Name()
+		entryPath := filepath.Join(sysDevicesSystemMemory, entryName)
+
+		// Ignore directories not starting with "memory"
+		if !strings.HasPrefix(entryName, "memory") {
+			continue
+		}
+
+		content, err := ioutil.ReadFile(filepath.Join(entryPath, "online"))
+		if err != nil {
+			return 0
+		}
+
+		// Only count the block if it's online
+		if strings.TrimSpace(string(content)) == "1" {
+			count++
+		}
+	}
+
+	return blockSize * count
+}
+
 // GetMemory returns a filled api.ResourcesMemory struct ready for use by LXD
 func GetMemory() (*api.ResourcesMemory, error) {
 	memory := api.ResourcesMemory{}
@@ -144,6 +199,13 @@ func GetMemory() (*api.ResourcesMemory, error) {
 		return nil, errors.Wrap(err, "Failed to parse /proc/meminfo")
 	}
 
+	// Calculate the total memory from /sys/devices/system/memory.
+	// If successful, replace the previous value, retrieved from /proc/meminfo.
+	memTotal := getTotalMemory()
+	if memTotal > 0 {
+		info.Total = memTotal
+	}
+
 	// Fill used values
 	memory.HugepagesUsed = (info.HugepagesTotal - info.HugepagesFree) * info.HugepagesSize
 	memory.HugepagesTotal = info.HugepagesTotal * info.HugepagesSize


More information about the lxc-devel mailing list