Skip to content

Commit fb3750e

Browse files
bnoordhuismaleadt
authored andcommitted
linux: teach uv_get_constrained_memory() cgroupsv2
Fixes: libuv#2315
1 parent 3f7038d commit fb3750e

File tree

1 file changed

+45
-10
lines changed

1 file changed

+45
-10
lines changed

src/unix/linux-core.c

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -775,27 +775,62 @@ uint64_t uv_get_total_memory(void) {
775775
}
776776

777777

778-
static uint64_t uv__read_cgroups_uint64(const char* cgroup, const char* param) {
779-
char filename[256];
778+
static uint64_t uv__read_uint64(const char* filename) {
780779
char buf[32]; /* Large enough to hold an encoded uint64_t. */
781780
uint64_t rc;
782781

783782
rc = 0;
784-
snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/%s", cgroup, param);
785783
if (0 == uv__slurp(filename, buf, sizeof(buf)))
786-
sscanf(buf, "%" PRIu64, &rc);
784+
if (1 != sscanf(buf, "%" PRIu64, &rc))
785+
if (0 == strcmp(buf, "max\n"))
786+
rc = ~0ull;
787787

788788
return rc;
789789
}
790790

791791

792+
/* This might return 0 if there was a problem getting the memory limit from
793+
* cgroups. This is OK because a return value of 0 signifies that the memory
794+
* limit is unknown.
795+
*/
796+
static uint64_t uv__get_constrained_memory_fallback(void) {
797+
return uv__read_uint64("/sys/fs/cgroup/memory/memory.limit_in_bytes");
798+
}
799+
800+
792801
uint64_t uv_get_constrained_memory(void) {
793-
/*
794-
* This might return 0 if there was a problem getting the memory limit from
795-
* cgroups. This is OK because a return value of 0 signifies that the memory
796-
* limit is unknown.
797-
*/
798-
return uv__read_cgroups_uint64("memory", "memory.limit_in_bytes");
802+
char filename[4097];
803+
char buf[1024];
804+
uint64_t high;
805+
uint64_t max;
806+
char* p;
807+
808+
if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf)))
809+
return uv__get_constrained_memory_fallback();
810+
811+
/* In the case of cgroupv2, we'll only have a single entry. */
812+
if (memcmp(buf, "0::/", 4))
813+
return uv__get_constrained_memory_fallback();
814+
815+
p = strchr(buf, '\n');
816+
if (p != NULL)
817+
*p = '\0';
818+
819+
p = buf + 4;
820+
821+
snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/memory.max", p);
822+
max = uv__read_uint64(filename);
823+
824+
if (max == 0)
825+
return uv__get_constrained_memory_fallback();
826+
827+
snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/memory.high", p);
828+
high = uv__read_uint64(filename);
829+
830+
if (high == 0)
831+
return uv__get_constrained_memory_fallback();
832+
833+
return high < max ? high : max;
799834
}
800835

801836

0 commit comments

Comments
 (0)