From 5f56d7426a19016706e8da72ce74bcb5a2a0a198 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 8 Jun 2020 13:12:43 +0200 Subject: [PATCH] linux: read load average from /proc/loadavg It was reported that uv_loadavg() reports the wrong values inside an lxc container. Libuv calls sysinfo(2) but that isn't intercepted by lxc. /proc/loadavg however is because /proc is a FUSE fs inside the container. This commit makes libuv try /proc/loadavg first and fall back to sysinfo(2) in case /proc isn't mounted. This commit is very similar to commit 3a1be725 ("linux: read free/total memory from /proc/meminfo") from April 2019. Fixes: https://github.com/nodejs/node/issues/33791 --- CMakeLists.txt | 6 ++---- Makefile.am | 6 ++---- src/unix/linux-core.c | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a44e953c471..cb79bfa3fe8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,8 +192,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android") src/unix/pthread-fixes.c src/unix/random-getentropy.c src/unix/random-getrandom.c - src/unix/random-sysctl-linux.c - src/unix/sysinfo-loadavg.c) + src/unix/random-sysctl-linux.c) endif() if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux|OS390") @@ -237,8 +236,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") src/unix/linux-syscalls.c src/unix/procfs-exepath.c src/unix/random-getrandom.c - src/unix/random-sysctl-linux.c - src/unix/sysinfo-loadavg.c) + src/unix/random-sysctl-linux.c) endif() if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD") diff --git a/Makefile.am b/Makefile.am index d9d2f3d02f5..c3391c2a82c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -386,8 +386,7 @@ libuv_la_SOURCES += src/unix/android-ifaddrs.c \ src/unix/procfs-exepath.c \ src/unix/pthread-fixes.c \ src/unix/random-getrandom.c \ - src/unix/random-sysctl-linux.c \ - src/unix/sysinfo-loadavg.c + src/unix/random-sysctl-linux.c endif if CYGWIN @@ -468,8 +467,7 @@ libuv_la_SOURCES += src/unix/linux-core.c \ src/unix/procfs-exepath.c \ src/unix/proctitle.c \ src/unix/random-getrandom.c \ - src/unix/random-sysctl-linux.c \ - src/unix/sysinfo-loadavg.c + src/unix/random-sysctl-linux.c test_run_tests_LDFLAGS += -lutil endif diff --git a/src/unix/linux-core.c b/src/unix/linux-core.c index 4148a4f5470..7e5c78c6752 100644 --- a/src/unix/linux-core.c +++ b/src/unix/linux-core.c @@ -1084,3 +1084,20 @@ uint64_t uv_get_constrained_memory(void) { */ return uv__read_cgroups_uint64("memory", "memory.limit_in_bytes"); } + + +void uv_loadavg(double avg[3]) { + struct sysinfo info; + char buf[128]; /* Large enough to hold all of /proc/loadavg. */ + + if (0 == uv__slurp("/proc/loadavg", buf, sizeof(buf))) + if (3 == sscanf(buf, "%lf %lf %lf", &avg[0], &avg[1], &avg[2])) + return; + + if (sysinfo(&info) < 0) + return; + + avg[0] = (double) info.loads[0] / 65536.0; + avg[1] = (double) info.loads[1] / 65536.0; + avg[2] = (double) info.loads[2] / 65536.0; +}