Skip to content

Commit

Permalink
linux: teach uv_get_constrained_memory() cgroupsv2
Browse files Browse the repository at this point in the history
Fixes: libuv#2315
  • Loading branch information
bnoordhuis authored and maleadt committed Sep 14, 2022
1 parent 3f7038d commit fb3750e
Showing 1 changed file with 45 additions and 10 deletions.
55 changes: 45 additions & 10 deletions src/unix/linux-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,27 +775,62 @@ uint64_t uv_get_total_memory(void) {
}


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

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

return rc;
}


/* This might return 0 if there was a problem getting the memory limit from
* cgroups. This is OK because a return value of 0 signifies that the memory
* limit is unknown.
*/
static uint64_t uv__get_constrained_memory_fallback(void) {
return uv__read_uint64("/sys/fs/cgroup/memory/memory.limit_in_bytes");
}


uint64_t uv_get_constrained_memory(void) {
/*
* This might return 0 if there was a problem getting the memory limit from
* cgroups. This is OK because a return value of 0 signifies that the memory
* limit is unknown.
*/
return uv__read_cgroups_uint64("memory", "memory.limit_in_bytes");
char filename[4097];
char buf[1024];
uint64_t high;
uint64_t max;
char* p;

if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf)))
return uv__get_constrained_memory_fallback();

/* In the case of cgroupv2, we'll only have a single entry. */
if (memcmp(buf, "0::/", 4))
return uv__get_constrained_memory_fallback();

p = strchr(buf, '\n');
if (p != NULL)
*p = '\0';

p = buf + 4;

snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/memory.max", p);
max = uv__read_uint64(filename);

if (max == 0)
return uv__get_constrained_memory_fallback();

snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/memory.high", p);
high = uv__read_uint64(filename);

if (high == 0)
return uv__get_constrained_memory_fallback();

return high < max ? high : max;
}


Expand Down

0 comments on commit fb3750e

Please sign in to comment.