fix: detect hybrid cgroup memory limits - #1669
Closed
leiysky wants to merge 2 commits into
Closed
Conversation
Comment on lines
+498
to
+528
| fn decode_cgroup_path(path: &str) -> String { | ||
| let bytes = path.as_bytes(); | ||
| let mut decoded = Vec::with_capacity(bytes.len()); | ||
| let mut pos = 0; | ||
|
|
||
| while pos < bytes.len() { | ||
| if bytes[pos] == b'\\' | ||
| && pos + 3 < bytes.len() | ||
| && let Some(value) = decode_octal_escape(&bytes[pos + 1..pos + 4]) | ||
| { | ||
| decoded.push(value); | ||
| pos += 4; | ||
| continue; | ||
| } | ||
|
|
||
| decoded.push(bytes[pos]); | ||
| pos += 1; | ||
| } | ||
|
|
||
| String::from_utf8(decoded).unwrap_or_else(|_| path.to_owned()) | ||
| } | ||
|
|
||
| fn decode_octal_escape(digits: &[u8]) -> Option<u8> { | ||
| let mut value = 0; | ||
|
|
||
| for digit in digits { | ||
| if !(b'0'..=b'7').contains(digit) { | ||
| return None; | ||
| } | ||
| value = value * 8 + (digit - b'0'); | ||
| } |
Owner
There was a problem hiding this comment.
Unless I missed something, we can keep the path as is (with Path::new()) and therefore completely remove these 2 functions.
| || controllers | ||
| .split(',') | ||
| .any(|controller| controller == "memory") | ||
| let Some(hierarchy_id) = fields.next() else { |
Comment on lines
+412
to
+417
| for field in fields.by_ref() { | ||
| if field == "-" { | ||
| found_separator = true; | ||
| break; | ||
| } | ||
| } |
Owner
There was a problem hiding this comment.
Suggested change
| for field in fields.by_ref() { | |
| if field == "-" { | |
| found_separator = true; | |
| break; | |
| } | |
| } | |
| // Skipping optional fields (the end is marked with "-"). | |
| while let Some(field) = fields.next() { | |
| if field == "-" { | |
| found_separator = true; | |
| break; | |
| } | |
| } |
Owner
There was a problem hiding this comment.
Took me a while to understand what by_ref() was doing so I'd rather have "simpler" code.
|
Hey @GuillaumeGomez! I'm @leiysky's collegaue and I'm trying to continue this PR in #1723 so that we can move from an internal pinned dependency back to the upstream I'll appreciate it if you can review #1723 when you have some time. |
Owner
|
Closing in favour of #1723 then. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix Linux cgroup memory limit detection in hybrid cgroup environments.
This changes cgroup path parsing to keep cgroup v2 and v1 memory-controller paths separately, prefers the v1 memory-controller limit when available, and stops treating
/proc/meminfoMemTotalas a cgroup memory limit when no finite cgroup limit is found.In some Kubernetes/container environments,
/proc/<pid>/cgroupcan contain both a cgroup v2 entry and a v1 memory-controller entry, for example:The old implementation parsed this into a single path and reused it for both v2 and v1. If the v2 path had
memory.max = max,memory_limitsstill initialized the result from hostMemTotal, socgroup_limits()could return host memory asSome(CGroupLimits)instead of either falling back to the v1 memory-controller path or returningNone.This can make callers believe a container has the host's memory capacity when it actually has a smaller cgroup limit.