Skip to content

Commit

Permalink
Fix resource detection for unset CPU and memory limits in cgroup v2 (#…
Browse files Browse the repository at this point in the history
…5267)

* Fix resource detection for unset CPU and memory limits in cgroup v2

Address the issue where `/sys/fs/cgroup/cpu.max` and `/sys/fs/cgroup/memory.max` report "max", indicating unset limits in cgroup v2. Now, system resources (CPU cores and memory) are fetched directly from `/proc/stat` and `/proc/meminfo` limits are not set..

* Small improvements

* Build fixes

* Fixes to LinuxUtilizationParserCgroupV2.cs

---------

Co-authored-by: Martin Obrátil <[email protected]>
Co-authored-by: Martin Obrátil <[email protected]>
  • Loading branch information
3 people authored Jul 23, 2024
1 parent 0d82461 commit 6a3cb23
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ public ulong GetAvailableMemoryInBytes()
_fileSystem.ReadAll(_memoryLimitInBytes, bufferWriter.Buffer);

ReadOnlySpan<char> memoryBuffer = bufferWriter.Buffer.WrittenSpan;

if (memoryBuffer.Equals("max\n", StringComparison.InvariantCulture))
{
return GetHostAvailableMemory();
}

_ = GetNextNumber(memoryBuffer, out maybeMemory);

if (maybeMemory == -1)
Expand Down Expand Up @@ -497,7 +503,13 @@ private static bool TryGetCpuUnitsFromCgroups(IFileSystem fileSystem, out float
return false;
}

int nextQuota = GetNextNumber(quotaBuffer, out long quota);
if (quotaBuffer.StartsWith("max", StringComparison.InvariantCulture))
{
cpuUnits = 0;
return false;
}

_ = GetNextNumber(quotaBuffer, out long quota);

if (quota == -1)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ public void When_Calling_GetMemoryUsageInBytes_Parser_Throws_When_UsageInBytes_D
Assert.Contains("/sys/fs/cgroup/memory.current", r.Message);
}

[ConditionalTheory]
[InlineData("max\n", 134_796_910_592ul)]
[InlineData("1000000\n", 1_000_000ul)]
public void When_Calling_GetAvailableMemoryInBytes_Parser_Returns_Available_Memory(string content, ulong expectedResult)
{
var f = new HardcodedValueFileSystem(new Dictionary<FileInfo, string>
{
{ new FileInfo("/sys/fs/cgroup/memory.max"), content },
{ new FileInfo("/proc/meminfo"), "MemTotal: 131637608 kB" }
});

var p = new LinuxUtilizationParserCgroupV2(f, new FakeUserHz(100));
var result = p.GetAvailableMemoryInBytes();

Assert.Equal(expectedResult, result);
}

[ConditionalTheory]
[InlineData("Suspicious12312312")]
[InlineData("string@")]
Expand Down Expand Up @@ -257,6 +274,21 @@ public void When_No_Cgroup_Cpu_Limits_Are_Not_Set_We_Get_Available_Cpus_From_Cpu
Assert.Equal(result, cpus);
}

[ConditionalFact]
public void When_Cpu_Max_Is_Set_To_Max_We_Get_Available_Cpus_From_CpuSetCpus()
{
var f = new HardcodedValueFileSystem(new Dictionary<FileInfo, string>
{
{ new FileInfo("/sys/fs/cgroup/cpuset.cpus.effective"), "0,1,2" },
{ new FileInfo("/sys/fs/cgroup/cpu.max"), "max 100000" },
});

var p = new LinuxUtilizationParserCgroupV2(f, new FakeUserHz(100));
var cpus = p.GetCgroupLimitedCpus();

Assert.Equal(3, cpus);
}

[ConditionalTheory]
[InlineData("-11")]
[InlineData("0-")]
Expand Down

0 comments on commit 6a3cb23

Please sign in to comment.