From 75aecfefea66f66d3524d74ea15ea7210a278fec Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Sun, 18 Sep 2016 16:34:48 +0200 Subject: [PATCH] #887: MemAvailable column may not be there; in that case calculate available mem the same way htop does --- psutil/_pslinux.py | 21 ++++++++++++++++++++- psutil/tests/test_linux.py | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 82f790744..04ed4eb27 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -289,6 +289,16 @@ def set_scputimes_ntuple(procfs_path): def virtual_memory(): + """Report memory stats trying to match "free" and "vmstat -s" cmdline + utility values as much as possible. + + This implementation uses procps-ng-3.3.12 as a reference (2016-09-18): + https://gitlab.com/procps-ng/procps/blob/ + 24fd2605c51fccc375ab0287cec33aa767f06718/proc/sysinfo.c + + ...or "free" / procps-ng-3.3.10 version which is available in Ubuntu + 16.04 and which should report the same numbers. + """ total, free, buffers, shared, _, _, unit_multiplier = cext.linux_sysinfo() total *= unit_multiplier free *= unit_multiplier @@ -329,7 +339,16 @@ def virtual_memory(): # free and htop available memory differs as per: # http://askubuntu.com/a/369589 # http://unix.stackexchange.com/a/65852/168884 - avail = mems['MemAvailable:'] + try: + avail = mems['MemAvailable:'] + except KeyError: + # Column is not there; it's likely this is an older kernel. + # In this case "free" won't show an "available" column. + # Also, procps does some hacky things: + # https://gitlab.com/procps-ng/procps/blob/ + # /24fd2605c51fccc375ab0287cec33aa767f06718/proc/sysinfo.c#L774 + # We won't. Like this we'll match "htop". + avail = free + buffers + cached # XXX: this value matches "free", but not all the time, see: # https://github.com/giampaolo/psutil/issues/685#issuecomment-202914057 diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index 877651073..520ae8e34 100644 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -191,7 +191,6 @@ def test_inactive(self): vmstat_value, psutil_value, delta=MEMORY_TOLERANCE) @retry_before_failing() - @unittest.skipIf(TRAVIS, "fails on travis") def test_shared(self): free = free_physmem() free_value = free.shared @@ -202,6 +201,7 @@ def test_shared(self): free_value, psutil_value, delta=MEMORY_TOLERANCE, msg='%s %s \n%s' % (free_value, psutil_value, free.output)) + @retry_before_failing() def test_available(self): # "free" output format has changed at some point: # https://github.com/giampaolo/psutil/issues/538#issuecomment-147192098