From 96bce4e11ee5bcbda8062169a75dea5561ef3618 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sat, 13 Jun 2015 00:00:00 +0000 Subject: [PATCH] library: address memory aberration with LXC containers Under a lxc container, the /proc/meminfo 'MemFree' and 'MemAvailable' amounts will be equal, unless memory is being limited via cgroups in which case 'MemAvailable' could exceed that for 'MemTotal'. And when a container has been nested, there exist additional memory quirks. A program might then display used or available amounts greater than total memory (assuming unsigned honored), or negative values (should a signed cast be employed). This anomaly primarily impacted the top and free pgms. Thus, two simple sanity checks have been introduced to avoid any illogical kb_main_available or kb_main_used. ( Busybox top & free also display anomalous although ) ( different results when running in a lxc container. ) Reference(s): https://bugzilla.redhat.com/show_bug.cgi?id=1153817 Signed-off-by: Jim Warner --- proc/sysinfo.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/proc/sysinfo.c b/proc/sysinfo.c index ee286f26..e6450eff 100644 --- a/proc/sysinfo.c +++ b/proc/sysinfo.c @@ -668,7 +668,7 @@ void meminfo(void){ }; const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct); unsigned long watermark_low; - signed long mem_available; + signed long mem_available, mem_used; FILE_TO_BUF(MEMINFO_FILE,meminfo_fd); @@ -705,7 +705,16 @@ nextline: } kb_main_cached = kb_page_cache + kb_slab; kb_swap_used = kb_swap_total - kb_swap_free; - kb_main_used = kb_main_total - kb_main_free - kb_main_cached - kb_main_buffers; + + /* if kb_main_available is greater than kb_main_total or our calculation of + mem_used overflows, that's symptomatic of running within a lxc container + where such values will be dramatically distorted over those of the host. */ + if (kb_main_available > kb_main_total) + kb_main_available = kb_main_free; + mem_used = kb_main_total - kb_main_free - kb_main_cached - kb_main_buffers; + if (mem_used < 0) + mem_used = kb_main_total - kb_main_free; + kb_main_used = (unsigned long)mem_used; /* zero? might need fallback for 2.6.27 <= kernel