Use GlobalMemoryStatusEx to get total physical memory on Windows node
This commit is contained in:
parent
098cba3f14
commit
071be11db5
@ -23,18 +23,32 @@ import (
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/golang/glog"
|
||||
cadvisorapi "github.com/google/cadvisor/info/v1"
|
||||
"golang.org/x/sys/windows"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
)
|
||||
|
||||
// MemoryStatusEx is the same as Windows structure MEMORYSTATUSEX
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366770(v=vs.85).aspx
|
||||
type MemoryStatusEx struct {
|
||||
Length uint32
|
||||
MemoryLoad uint32
|
||||
TotalPhys uint64
|
||||
AvailPhys uint64
|
||||
TotalPageFile uint64
|
||||
AvailPageFile uint64
|
||||
TotalVirtual uint64
|
||||
AvailVirtual uint64
|
||||
AvailExtendedVirtual uint64
|
||||
}
|
||||
|
||||
var (
|
||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procGetPhysicallyInstalledSystemMemory = modkernel32.NewProc("GetPhysicallyInstalledSystemMemory")
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
|
||||
)
|
||||
|
||||
// NewPerfCounterClient creates a client using perf counters
|
||||
@ -163,20 +177,24 @@ func (p *perfCounterNodeStatsClient) convertCPUValue(cpuValue uint64) uint64 {
|
||||
}
|
||||
|
||||
func getPhysicallyInstalledSystemMemoryBytes() (uint64, error) {
|
||||
var physicalMemoryKiloBytes uint64
|
||||
// We use GlobalMemoryStatusEx instead of GetPhysicallyInstalledSystemMemory
|
||||
// on Windows node for the following reasons:
|
||||
// 1. GetPhysicallyInstalledSystemMemory retrieves the amount of physically
|
||||
// installed RAM from the computer's SMBIOS firmware tables.
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/cc300158(v=vs.85).aspx
|
||||
// On some VM, it is unable to read data from SMBIOS and fails with ERROR_INVALID_DATA.
|
||||
// 2. On Linux node, total physical memory is read from MemTotal in /proc/meminfo.
|
||||
// GlobalMemoryStatusEx returns the amount of physical memory that is available
|
||||
// for the operating system to use. The amount returned by GlobalMemoryStatusEx
|
||||
// is closer in parity with Linux
|
||||
// https://www.kernel.org/doc/Documentation/filesystems/proc.txt
|
||||
var statex MemoryStatusEx
|
||||
statex.Length = uint32(unsafe.Sizeof(statex))
|
||||
ret, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&statex)))
|
||||
|
||||
if ok := getPhysicallyInstalledSystemMemory(&physicalMemoryKiloBytes); !ok {
|
||||
if ret == 0 {
|
||||
return 0, errors.New("unable to read physical memory")
|
||||
}
|
||||
|
||||
return physicalMemoryKiloBytes * 1024, nil // convert kilobytes to bytes
|
||||
}
|
||||
|
||||
func getPhysicallyInstalledSystemMemory(totalMemoryInKilobytes *uint64) bool {
|
||||
ret, _, _ := syscall.Syscall(procGetPhysicallyInstalledSystemMemory.Addr(), 1,
|
||||
uintptr(unsafe.Pointer(totalMemoryInKilobytes)),
|
||||
0,
|
||||
0)
|
||||
|
||||
return ret != 0
|
||||
return statex.TotalPhys, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user