From cb8b796036498b9a16c26ca615856a6369524272 Mon Sep 17 00:00:00 2001 From: Kenneth Lakin Date: Thu, 9 Sep 2021 14:54:51 -0700 Subject: [PATCH] Add new method to get memory ignoring cgroups In PR #50, the behavior of GetMem() was changed to return the amount of memory used / available within the current cgroup. There are some use cases that you don't want cgroup-constrained memory information. A new GetMemIgnoringCGroups method has been introduced to provide the system wide memory information. [#179517901] Update Bosh Agent to correctly report memory used in `bosh vms --vitals` and related code paths, and publish new stemcells Signed-off-by: Brian Upton --- concrete_sigar.go | 6 ++++++ concrete_sigar_test.go | 3 +++ sigar_darwin.go | 4 ++++ sigar_linux.go | 12 ++++++++++++ sigar_linux_test.go | 21 +++++++++++++++++++++ sigar_windows.go | 4 ++++ 6 files changed, 50 insertions(+) diff --git a/concrete_sigar.go b/concrete_sigar.go index 0e80aa4b9..8b57d5444 100644 --- a/concrete_sigar.go +++ b/concrete_sigar.go @@ -56,6 +56,12 @@ func (c *ConcreteSigar) GetMem() (Mem, error) { return m, err } +func (c *ConcreteSigar) GetMemIgnoringCGroups() (Mem, error) { + m := Mem{} + err := m.GetIgnoringCGroups() + return m, err +} + func (c *ConcreteSigar) GetSwap() (Swap, error) { s := Swap{} err := s.Get() diff --git a/concrete_sigar_test.go b/concrete_sigar_test.go index 81fdc541e..2a0016308 100644 --- a/concrete_sigar_test.go +++ b/concrete_sigar_test.go @@ -68,6 +68,9 @@ var _ = Describe("ConcreteSigar", func() { Expect(mem.Total).To(BeNumerically(">", 0)) Expect(mem.Used + mem.Free).To(BeNumerically("<=", mem.Total)) + + mem, err = concreteSigar.GetMemIgnoringCGroups() + Expect(err).ToNot(HaveOccurred()) }) It("GetSwap", func() { diff --git a/sigar_darwin.go b/sigar_darwin.go index 3f41d6534..23bae7abd 100644 --- a/sigar_darwin.go +++ b/sigar_darwin.go @@ -68,6 +68,10 @@ func (self *Mem) Get() error { return nil } +func (self *Mem) GetIgnoringCGroups() error { + return self.Get() +} + type xsw_usage struct { Total, Avail, Used uint64 } diff --git a/sigar_linux.go b/sigar_linux.go index b3d0b2ccc..b290f250d 100644 --- a/sigar_linux.go +++ b/sigar_linux.go @@ -100,6 +100,14 @@ func (self *Uptime) Get() error { } func (self *Mem) Get() error { + return self.get(false) +} + +func (self *Mem) GetIgnoringCGroups() error { + return self.get(true) +} + +func (self *Mem) get(ignoreCGroups bool) error { var available uint64 = MaxUint64 var buffers, cached uint64 table := map[string]*uint64{ @@ -123,6 +131,10 @@ func (self *Mem) Get() error { self.Used = self.Total - self.Free self.ActualUsed = self.Total - self.ActualFree + if ignoreCGroups { + return nil + } + // Instead of detecting if this code is run within a container // or not (*), we simply attempt to retrieve the cgroup // information about memory limits and usage and if present diff --git a/sigar_linux_test.go b/sigar_linux_test.go index 240b9900a..4e21c7d96 100644 --- a/sigar_linux_test.go +++ b/sigar_linux_test.go @@ -883,6 +883,27 @@ DirectMap2M: 34983936 kB`) }) }) + Describe("When cgroups are enabled but the GetIgnoringCGroups method is called", func() { + // cgroup = '/user' + // The other tests use cgroup = '/'. This reduces the amount of changes needed + BeforeEach(func() { + cgroupSetup(`4:memory:/user`) + memInfoWithMemAvailable() + memLimitSetup2(`/user`, `21390950400`) + memUsageWithSwap(`/user`) + }) + + It("returns the system memory info", func() { + mem := Mem{} + err := mem.GetIgnoringCGroups() + Expect(err).ToNot(HaveOccurred()) + + Expect(mem.Total).To(BeNumerically("==", 35008180*1024)) + Expect(mem.Free).To(BeNumerically("==", 487816*1024)) + Expect(mem.ActualFree).To(BeNumerically("==", 20913400*1024)) + Expect(mem.ActualUsed).To(BeNumerically("==", 14433054720)) + }) + }) }) Describe("Swap", func() { diff --git a/sigar_windows.go b/sigar_windows.go index 1e0a007c7..3f8af478d 100644 --- a/sigar_windows.go +++ b/sigar_windows.go @@ -71,6 +71,10 @@ func (m *Mem) Get() error { return nil } +func (m *Mem) GetIgnoringCGroups() error { + return m.Get() +} + func (s *Swap) Get() error { const MB = 1024 * 1024 out, err := exec.Command("wmic", "pagefile", "list", "full").Output()