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-inotify.c
|
||||||
src/unix/linux-syscalls.c
|
src/unix/linux-syscalls.c
|
||||||
src/unix/procfs-exepath.c
|
src/unix/procfs-exepath.c
|
||||||
src/unix/sysinfo-loadavg.c
|
src/unix/sysinfo-loadavg.c)
|
||||||
src/unix/sysinfo-memory.c)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
|
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/linux-syscalls.h \
|
||||||
src/unix/procfs-exepath.c \
|
src/unix/procfs-exepath.c \
|
||||||
src/unix/proctitle.c \
|
src/unix/proctitle.c \
|
||||||
src/unix/sysinfo-loadavg.c \
|
src/unix/sysinfo-loadavg.c
|
||||||
src/unix/sysinfo-memory.c
|
|
||||||
test_run_tests_LDFLAGS += -lutil
|
test_run_tests_LDFLAGS += -lutil
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@ -936,3 +936,75 @@ void uv__set_process_title(const char* title) {
|
|||||||
prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
|
prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
|||||||
1
uv.gyp
1
uv.gyp
@ -241,7 +241,6 @@
|
|||||||
'src/unix/linux-syscalls.h',
|
'src/unix/linux-syscalls.h',
|
||||||
'src/unix/procfs-exepath.c',
|
'src/unix/procfs-exepath.c',
|
||||||
'src/unix/sysinfo-loadavg.c',
|
'src/unix/sysinfo-loadavg.c',
|
||||||
'src/unix/sysinfo-memory.c',
|
|
||||||
],
|
],
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'libraries': [ '-ldl', '-lrt' ],
|
'libraries': [ '-ldl', '-lrt' ],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user