Skip to content

Commit

Permalink
[NetBSD] available mem can be higher than total (#2233)
Browse files Browse the repository at this point in the history
On NetBSD "available" memory can be higher than "total". From now now calculate it exactly the same as Zabbix:
https://github.com/zabbix/zabbix/blob/af5e0f80253e585ca7082ca6bc9cc07400afe2a7/src/libs/zbxsysinfo/netbsd/memory.c

Fixes #2231 which produced this failure:

```
======================================================================
FAIL: psutil.tests.test_system.TestMemoryAPIs.test_virtual_memory
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/vagrant/psutil/psutil/tests/test_system.py", line 275, in test_virtual_memory
    assert 0 <= mem.percent <= 100, mem
           ^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: svmem(total=1019899904, available=1046573056, percent=-2.6, used=603414528, free=545050624, active=234807296, inactive=133210112, buffers=260288512, cached=368312320, shared=0, wired=294912)
```
  • Loading branch information
giampaolo authored Apr 13, 2023
1 parent eb8e318 commit 6e2dc77
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 14 deletions.
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
1 minute).
- 2229_, [OpenBSD]: unable to properly recognize zombie processes.
`NoSuchProcess`_ may be raised instead of `ZombieProcess`_.
- 2231_, [NetBSD]: *available* `virtual_memory()`_ is higher than *total*.

5.9.4
=====
Expand Down
29 changes: 19 additions & 10 deletions psutil/_psbsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,11 @@
# =====================================================================


def virtual_memory():
"""System virtual memory as a namedtuple."""
mem = cext.virtual_mem()
total, free, active, inactive, wired, cached, buffers, shared = mem
if NETBSD:
if NETBSD:
def virtual_memory():
"""System virtual memory as a namedtuple."""
mem = cext.virtual_mem()
total, free, active, inactive, wired, cached, avail = mem
# On NetBSD buffers and shared mem is determined via /proc.
# The C ext set them to 0.
with open('/proc/meminfo', 'rb') as f:
Expand All @@ -191,11 +191,20 @@ def virtual_memory():
shared = int(line.split()[1]) * 1024
elif line.startswith(b'Cached:'):
cached = int(line.split()[1]) * 1024
avail = inactive + cached + free
used = active + wired + cached
percent = usage_percent((total - avail), total, round_=1)
return svmem(total, avail, percent, used, free,
active, inactive, buffers, cached, shared, wired)
used = active + wired + cached
percent = usage_percent((total - avail), total, round_=1)
return svmem(total, avail, percent, used, free,
active, inactive, buffers, cached, shared, wired)
else:
def virtual_memory():
"""System virtual memory as a namedtuple."""
mem = cext.virtual_mem()
total, free, active, inactive, wired, cached, buffers, shared = mem
avail = inactive + cached + free
used = active + wired + cached
percent = usage_percent((total - avail), total, round_=1)
return svmem(total, avail, percent, used, free,
active, inactive, buffers, cached, shared, wired)


def swap_memory():
Expand Down
10 changes: 6 additions & 4 deletions psutil/arch/netbsd/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,25 @@ psutil_virtual_mem(PyObject *self, PyObject *args) {
struct uvmexp_sysctl uv;
int mib[] = {CTL_VM, VM_UVMEXP2};
long pagesize = psutil_getpagesize();
unsigned long long available;

size = sizeof(uv);
if (sysctl(mib, 2, &uv, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}

return Py_BuildValue("KKKKKKKK",
// follow zabbix
available = uv.inactive + uv.execpages + uv.filepages + uv.free;
return Py_BuildValue(
"KKKKKKK",
(unsigned long long) uv.npages << uv.pageshift, // total
(unsigned long long) uv.free << uv.pageshift, // free
(unsigned long long) uv.active << uv.pageshift, // active
(unsigned long long) uv.inactive << uv.pageshift, // inactive
(unsigned long long) uv.wired << uv.pageshift, // wired
(unsigned long long) (uv.filepages + uv.execpages) * pagesize, // cached
// These are determined from /proc/meminfo in Python.
(unsigned long long) 0, // buffers
(unsigned long long) 0 // shared
available << uv.pageshift // available
);
}

Expand Down

0 comments on commit 6e2dc77

Please sign in to comment.