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 <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2015-06-13 00:00:00 +00:00 committed by Craig Small
parent 898e3cc3cf
commit 96bce4e11e

View File

@ -668,7 +668,7 @@ void meminfo(void){
}; };
const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct); const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct);
unsigned long watermark_low; unsigned long watermark_low;
signed long mem_available; signed long mem_available, mem_used;
FILE_TO_BUF(MEMINFO_FILE,meminfo_fd); FILE_TO_BUF(MEMINFO_FILE,meminfo_fd);
@ -705,7 +705,16 @@ nextline:
} }
kb_main_cached = kb_page_cache + kb_slab; kb_main_cached = kb_page_cache + kb_slab;
kb_swap_used = kb_swap_total - kb_swap_free; 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 <? 3.14 */ /* zero? might need fallback for 2.6.27 <= kernel <? 3.14 */
if (!kb_main_available) { if (!kb_main_available) {