From 5fc3f458f9e18e6a8a7b4b0bb15a9fb4be39a6e3 Mon Sep 17 00:00:00 2001 From: David Zuelke Date: Tue, 25 Jun 2024 19:00:31 +0200 Subject: [PATCH] Read container memory limit from cgroup (v1 and v2) Uses memory.high if available (recommended way of setting a functioning soft limit), then first falls back to memory.max (e.g. from 'docker run -m'), then to memory.low (e.g. from 'docker run --memory-reservation'), and finally to memory.min. Falls back to direct reading of '/sys/fs/cgroup/memory/memory.limit_in_bytes' for cases where that exists, but no full cgroupfs is mounted (e.g. on Heroku). Limit enforcement (now to 8 TB) is still in place this way - a Docker v1 value will be read, and run into the limit for unrestricted containers, without hitting the fallback and getting returned. GUS-W-16052317 --- lib/environment.sh | 7 ++++++- profile/WEB_CONCURRENCY.sh | 19 +++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) mode change 100644 => 100755 lib/environment.sh diff --git a/lib/environment.sh b/lib/environment.sh old mode 100644 new mode 100755 index 2be01abfb..3fd41834a --- a/lib/environment.sh +++ b/lib/environment.sh @@ -86,7 +86,12 @@ write_profile() { local bp_dir="$1" local build_dir="$2" mkdir -p "$build_dir/.profile.d" - cp "$bp_dir"/profile/* "$build_dir/.profile.d/" + local restore_extglob + restore_extglob=$(shopt -p extglob) # will return "shopt -u extglob" (or "-s") + cp "$bp_dir"/profile/!(WEB_CONCURRENCY.sh) "$build_dir/.profile.d/" + $restore_extglob + # concatenate these two together + cat "$bp_dir"/etc/cgroups.sh "$bp_dir"/profile/WEB_CONCURRENCY.sh > "$build_dir/.profile.d/WEB_CONCURRENCY.sh" } write_ci_profile() { diff --git a/profile/WEB_CONCURRENCY.sh b/profile/WEB_CONCURRENCY.sh index 9e7d7eddf..a541dbd75 100755 --- a/profile/WEB_CONCURRENCY.sh +++ b/profile/WEB_CONCURRENCY.sh @@ -31,17 +31,28 @@ log_concurrency() { detect_memory() { local default=$1 - if [ -e /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then - echo $(($(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) / 1048576)) + local memory_limit + memory_limit=$(cgroup_util_read_cgroup_memory_limit_with_fallback) && { + echo $(( memory_limit / 1024 / 1024 )) + return + } + + if (($? == 99)); then + dne_memory else echo "$default" - fi + fi +} + +dne_memory() { + echo "129024" } bound_memory() { local detected=$1 # Memory is bound to the maximum memory of known dyno types: ~126 GB - local max_detected_memory=129024 + local max_detected_memory + max_detected_memory=$(dne_memory) if (( detected > max_detected_memory )); then echo "$max_detected_memory" else