linux: read free/total memory from /proc/meminfo
It was reported that uv_get_free_memory() and uv_get_total_memory() report the wrong values inside an lxc container. Libuv calls sysinfo(2) but that isn't intercepted by lxc. /proc/meminfo however is because /proc is a FUSE fs inside the container. This commit makes libuv try /proc/meminfo first and fall back to sysinfo(2) in case /proc isn't mounted. Fixes: https://github.com/libuv/libuv/issues/2249 PR-URL: https://github.com/libuv/libuv/pull/2258 Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
1c2dc9c8d1
commit
3a1be72532
@ -297,8 +297,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
src/unix/linux-inotify.c
|
||||
src/unix/linux-syscalls.c
|
||||
src/unix/procfs-exepath.c
|
||||
src/unix/sysinfo-loadavg.c
|
||||
src/unix/sysinfo-memory.c)
|
||||
src/unix/sysinfo-loadavg.c)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
|
||||
|
||||
@ -425,8 +425,7 @@ libuv_la_SOURCES += src/unix/linux-core.c \
|
||||
src/unix/linux-syscalls.h \
|
||||
src/unix/procfs-exepath.c \
|
||||
src/unix/proctitle.c \
|
||||
src/unix/sysinfo-loadavg.c \
|
||||
src/unix/sysinfo-memory.c
|
||||
src/unix/sysinfo-loadavg.c
|
||||
test_run_tests_LDFLAGS += -lutil
|
||||
endif
|
||||
|
||||
|
||||
@ -936,3 +936,75 @@ void uv__set_process_title(const char* title) {
|
||||
prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static uint64_t uv__read_proc_meminfo(const char* what) {
|
||||
unsigned long rc;
|
||||
ssize_t n;
|
||||
char* p;
|
||||
int fd;
|
||||
char buf[4096]; /* Large enough to hold all of /proc/meminfo. */
|
||||
|
||||
rc = 0;
|
||||
fd = uv__open_cloexec("/proc/meminfo", O_RDONLY);
|
||||
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
|
||||
n = read(fd, buf, sizeof(buf) - 1);
|
||||
|
||||
if (n <= 0)
|
||||
goto out;
|
||||
|
||||
buf[n] = '\0';
|
||||
p = strstr(buf, what);
|
||||
|
||||
if (p == NULL)
|
||||
goto out;
|
||||
|
||||
p += strlen(what);
|
||||
|
||||
if (1 != sscanf(p, "%lu kB", &rc))
|
||||
goto out;
|
||||
|
||||
rc *= 1024;
|
||||
|
||||
out:
|
||||
|
||||
if (uv__close_nocheckstdio(fd))
|
||||
abort();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_free_memory(void) {
|
||||
struct sysinfo info;
|
||||
uint64_t rc;
|
||||
|
||||
rc = uv__read_proc_meminfo("MemFree:");
|
||||
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
if (0 == sysinfo(&info))
|
||||
return (uint64_t) info.freeram * info.mem_unit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_total_memory(void) {
|
||||
struct sysinfo info;
|
||||
uint64_t rc;
|
||||
|
||||
rc = uv__read_proc_meminfo("MemTotal:");
|
||||
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
if (0 == sysinfo(&info))
|
||||
return (uint64_t) info.totalram * info.mem_unit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user