From 101f9b1771a638947697e46f3acc16addefdf9f5 Mon Sep 17 00:00:00 2001 From: Ryan Moeller Date: Sat, 30 Nov 2019 18:43:23 -0500 Subject: [PATCH] Add FreeBSD code to arc_summary and arcstat Adding the FreeBSD code allows arc_summary and arcstat to be used on FreeBSD. Reviewed-by: Brian Behlendorf Signed-off-by: Ryan Moeller Closes #9641 --- cmd/arc_summary/arc_summary2 | 15 +++++++++++- cmd/arc_summary/arc_summary3 | 44 ++++++++++++++++++++++++++++++++---- cmd/arcstat/arcstat | 24 +++++++++++++++++++- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/cmd/arc_summary/arc_summary2 b/cmd/arc_summary/arc_summary2 index 8ae35c0db7..5dc40d759d 100755 --- a/cmd/arc_summary/arc_summary2 +++ b/cmd/arc_summary/arc_summary2 @@ -55,7 +55,20 @@ from subprocess import Popen, PIPE from decimal import Decimal as D -if sys.platform.startswith('linux'): +if sys.platform.startswith('freebsd'): + # Requires py27-sysctl on FreeBSD + import sysctl + + def load_kstats(namespace): + """Collect information on a specific subsystem of the ARC""" + + base = 'kstat.zfs.misc.%s.' % namespace + return [(kstat.name, D(kstat.value)) for kstat in sysctl.filter(base)] + + def load_tunables(): + return dict((ctl.name, ctl.value) for ctl in sysctl.filter('vfs.zfs')) + +elif sys.platform.startswith('linux'): def load_kstats(namespace): """Collect information on a specific subsystem of the ARC""" diff --git a/cmd/arc_summary/arc_summary3 b/cmd/arc_summary/arc_summary3 index 5d1c5d5b41..af49fe3ab3 100755 --- a/cmd/arc_summary/arc_summary3 +++ b/cmd/arc_summary/arc_summary3 @@ -80,10 +80,42 @@ parser.add_argument('-s', '--section', dest='section', help=SECTION_HELP) ARGS = parser.parse_args() -if sys.platform.startswith('linux'): - KSTAT_PATH = '/proc/spl/kstat/zfs/' - SPL_PATH = '/sys/module/spl/parameters/' - TUNABLES_PATH = '/sys/module/zfs/parameters/' +if sys.platform.startswith('freebsd'): + # Requires py36-sysctl on FreeBSD + import sysctl + + VDEV_CACHE_SIZE = 'vdev.cache_size' + + def load_kstats(section): + base = 'kstat.zfs.misc.{section}.'.format(section=section) + # base is removed from the name + fmt = lambda kstat: '{name} : {value}'.format(name=kstat.name[len(base):], + value=kstat.value) + return [fmt(kstat) for kstat in sysctl.filter(base)] + + def get_params(base): + cut = 8 # = len('vfs.zfs.') + return {ctl.name[cut:]: str(ctl.value) for ctl in sysctl.filter(base)} + + def get_tunable_params(): + return get_params('vfs.zfs') + + def get_vdev_params(): + return get_params('vfs.zfs.vdev') + + def get_version_impl(request): + # FreeBSD reports versions for zpl and spa instead of zfs and spl. + name = {'zfs': 'zpl', + 'spl': 'spa'}[request] + mib = 'vfs.zfs.version.{}'.format(name) + version = sysctl.filter(mib)[0].value + return '{} version {}'.format(name, version) + +elif sys.platform.startswith('linux'): + KSTAT_PATH = '/proc/spl/kstat/zfs' + SPL_PATH = '/sys/module/spl/parameters' + TUNABLES_PATH = '/sys/module/zfs/parameters' + VDEV_CACHE_SIZE = 'zfs_vdev_cache_size' def load_kstats(section): @@ -720,6 +752,10 @@ def section_spl(*_): and/or descriptions. This does not use kstats. """ + if sys.platform.startswith('freebsd'): + # No SPL support in FreeBSD + return + spls = get_spl_params() keylist = sorted(spls.keys()) print('Solaris Porting Layer (SPL):') diff --git a/cmd/arcstat/arcstat b/cmd/arcstat/arcstat index 7562038d12..143f475747 100755 --- a/cmd/arcstat/arcstat +++ b/cmd/arcstat/arcstat @@ -119,7 +119,29 @@ out = None kstat = None -if sys.platform.startswith('linux'): +if sys.platform.startswith('freebsd'): + # Requires py27-sysctl on FreeBSD + import sysctl + + def kstat_update(): + global kstat + + k = sysctl.filter('kstat.zfs.misc.arcstats') + + if not k: + sys.exit(1) + + kstat = {} + + for s in k: + if not s: + continue + + name, value = s.name, s.value + # Trims 'kstat.zfs.misc.arcstats' from the name + kstat[name[24:]] = Decimal(value) + +elif sys.platform.startswith('linux'): def kstat_update(): global kstat