Skip to content

Commit

Permalink
feat: add compatibility for zfs arc architectures, (matches htop sour…
Browse files Browse the repository at this point in the history
…ce code)
  • Loading branch information
hewdoe committed Mar 21, 2024
1 parent f51f62b commit 0857e40
Showing 1 changed file with 82 additions and 2 deletions.
84 changes: 82 additions & 2 deletions psutil/_pslinux.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ class IOPriority(enum.IntEnum):
svmem = namedtuple(
'svmem', ['total', 'available', 'percent', 'used', 'free',
'active', 'inactive', 'buffers', 'cached', 'shared', 'slab'])
# psutil.zfs_arc_stats()
szfsarc = namedtuple(
'szfsarc', ['enabled', 'min', 'max', 'compressed', 'uncompressed',
'size', 'header', 'anon', 'mfu', 'mru', 'other'])
# psutil.disk_io_counters()
sdiskio = namedtuple(
'sdiskio', ['read_count', 'write_count',
Expand Down Expand Up @@ -415,13 +419,15 @@ def calculate_avail_vmem(mems):
return int(avail)


def virtual_memory():
def virtual_memory(bool:include_zfs_arc=False):
"""Report virtual memory stats.
This implementation mimicks procps-ng-3.3.12, aka "free" CLI tool:
This implementation mimics procps-ng-3.3.12, aka "free" CLI tool:
https://gitlab.com/procps-ng/procps/blob/
24fd2605c51fccc375ab0287cec33aa767f06718/proc/sysinfo.c#L778-791
The returned values are supposed to match both "free" and "vmstat -s"
CLI tools.
If specifying the `include_zfs_arc` parameter, the implementation mimics
"htop" CLI tool instead of "free" CLI tool.
"""
missing_fields = []
mems = {}
Expand Down Expand Up @@ -523,6 +529,22 @@ def virtual_memory():
# 24fd2605c51fccc375ab0287cec33aa767f06718/proc/sysinfo.c#L764
avail = free

# ZFS ARC memory consumption is not reported by /proc/meminfo.
# Specifying `include_zfs_arc` will include reclaimable ZFS ARC
# memory in the returned values.
# N.B. this will make psutil match the output of "htop" instead
# of "free" CLI tool.
# See:
# https://www.reddit.com/r/zfs/comments/ha0p7f/understanding_arcstat_and_free/
# https://github.com/openzfs/zfs/issues/10255
if include_zfs_arc:
zfs = zfs_arc_stats()
if zfs.enabled:
shrinkable_size = max(zfs.size - zfs.min, 0)
used -= shrinkable_size
cached += shrinkable_size
avail += shrinkable_size

percent = usage_percent((total - avail), total, round_=1)

# Warn about missing metrics which are set to 0.
Expand Down Expand Up @@ -603,6 +625,64 @@ def swap_memory():
return _common.sswap(total, used, free, percent, sin, sout)


def zfs_arc_stats():
"""Return ZFS ARC (Adaptive Replacement Cache) stats."""
missing_fields = []
mems = {}

def get_if_available(key):
try:
return mems[key] / 1024
except KeyError:
missing_fields.append(key)
return 0


with open_binary('%s/spl/kstat/zfs/arcstats' % get_procfs_path()) as f:
for line in f:
fields = line.split()
mems[fields[0]] = int(fields[1])

zfs_min = get_if_available(b'c_min')
zfs_max = get_if_available(b'c_max')
zfs_compressed = get_if_available(b'compressed_size')
zfs_uncompressed = get_if_available(b'uncompressed_size')
zfs_size = get_if_available(b'size')
zfs_header = get_if_available(b'hdr_size')
dbuf_size = get_if_available(b'dbuf_size')
dnode_size = get_if_available(b'dnode_size')
bonus_size = get_if_available(b'bonus_size')
zfs_anon = get_if_available(b'anon_size')
zfs_mfu = get_if_available(b'mfu_size')
zfs_mru = get_if_available(b'mru_size')

zfs_enabled = zfs.size > 0
zfs_other = dbuf_size + dnode_size + bonus_size if all([dbuf_size, dnode_size, bonus_size]) else 0

# Warn about missing metrics which are set to 0.
if missing_fields:
msg = "%s memory stats couldn't be determined and %s set to 0" % (
", ".join(missing_fields),
"was" if len(missing_fields) == 1 else "were",
)
warnings.warn(msg, RuntimeWarning, stacklevel=2)

return szfsarc(
zfs_enabled,
zfs_min,
zfs_max,
zfs_compressed,
zfs_uncompressed,
zfs_size,
zfs_header,
zfs_anon,
zfs_mfu,
zfs_mru,
zfs_other
)



# =====================================================================
# --- CPU
# =====================================================================
Expand Down

0 comments on commit 0857e40

Please sign in to comment.