lib/memory: fall back to reading hierarchical memory limit in cgroups when the default limit isn't set

Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/699
This commit is contained in:
Aliaksandr Valialkin 2020-09-04 00:04:08 +03:00
parent d387da142e
commit be6ae4b5e7
3 changed files with 32 additions and 9 deletions

View file

@ -14,3 +14,18 @@ func GetMemoryLimit() int64 {
}
return n
}
// GetHierarchicalMemoryLimit returns hierarchical memory limit
func GetHierarchicalMemoryLimit() int64 {
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/699
n, err := readInt64FromCommand("cat /sys/fs/cgroup/memory/memory.stat | grep hierarchical_memory_limit | cut -d' ' -f 2")
if err == nil {
return n
}
n, err = readInt64FromCommand(
"cat /sys/fs/cgroup/memory$(cat /proc/self/cgroup | grep memory | cut -d: -f3)/memory.stat | grep hierarchical_memory_limit | cut -d' ' -f 2")
if err != nil {
return 0
}
return n
}

View file

@ -9,16 +9,19 @@ import (
func readInt64(path, altCommand string) (int64, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
// Read data according to https://unix.stackexchange.com/questions/242718/how-to-find-out-how-much-memory-lxc-container-is-allowed-to-consume
// This should properly determine the data location inside lxc container.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/84
cmd := exec.Command("/bin/sh", "-c", altCommand)
data, err = cmd.Output()
if err == nil {
data = bytes.TrimSpace(data)
return strconv.ParseInt(string(data), 10, 64)
}
return readInt64FromCommand(altCommand)
}
func readInt64FromCommand(command string) (int64, error) {
cmd := exec.Command("/bin/sh", "-c", command)
data, err := cmd.Output()
if err != nil {
return 0, err
}
}
data = bytes.TrimSpace(data)
return strconv.ParseInt(string(data), 10, 64)
}

View file

@ -19,8 +19,13 @@ func sysTotalMemory() int {
totalMem = int(uint64(si.Totalram) * uint64(si.Unit))
}
mem := cgroup.GetMemoryLimit()
if mem <= 0 || int64(int(mem)) != mem || int(mem) > totalMem {
// Try reading hierachical memory limit.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/699
mem = cgroup.GetHierarchicalMemoryLimit()
if mem <= 0 || int64(int(mem)) != mem || int(mem) > totalMem {
return totalMem
}
}
return int(mem)
}