From 6122948b3bb6b96f9bac35492dce245fb96659db Mon Sep 17 00:00:00 2001 From: Ryan Moeller Date: Tue, 10 Sep 2019 15:17:54 -0400 Subject: [PATCH] Add/generalize abstraction in arc_summary2 A more generic interface can be used for the abstraction of loading kstats, allowing other platforms to implement the function cleanly. In a similar vein, loading tunables can be abstracted away in order for other platforms to provide their own implementations of this function. Reviewed-by: Brian Behlendorf Reviewed-by: Matt Macy Signed-off-by: Ryan Moeller Closes #9277 --- cmd/arc_summary/arc_summary2 | 52 +++++++++++++++++------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/cmd/arc_summary/arc_summary2 b/cmd/arc_summary/arc_summary2 index ab4a3c574..734fb708b 100755 --- a/cmd/arc_summary/arc_summary2 +++ b/cmd/arc_summary/arc_summary2 @@ -54,6 +54,7 @@ import errno from subprocess import Popen, PIPE from decimal import Decimal as D + show_tunable_descriptions = False alternate_tunable_layout = False @@ -76,24 +77,19 @@ def get_Kstat(): of the same name. """ - def load_proc_kstats(fn, namespace): + def load_kstats(namespace): """Collect information on a specific subsystem of the ARC""" - kstats = [line.strip() for line in open(fn)] - del kstats[0:2] - for kstat in kstats: - kstat = kstat.strip() - name, _, value = kstat.split() - Kstat[namespace + name] = D(value) + kstat = 'kstat.zfs.misc.%s.%%s' % namespace + path = '/proc/spl/kstat/zfs/%s' % namespace + with open(path) as f: + entries = [line.strip().split() for line in f][2:] # Skip header + return [(kstat % name, D(value)) for name, _, value in entries] Kstat = {} - load_proc_kstats('/proc/spl/kstat/zfs/arcstats', - 'kstat.zfs.misc.arcstats.') - load_proc_kstats('/proc/spl/kstat/zfs/zfetchstats', - 'kstat.zfs.misc.zfetchstats.') - load_proc_kstats('/proc/spl/kstat/zfs/vdev_cache_stats', - 'kstat.zfs.misc.vdev_cache_stats.') - + Kstat.update(load_kstats('arcstats')) + Kstat.update(load_kstats('zfetchstats')) + Kstat.update(load_kstats('vdev_cache_stats')) return Kstat @@ -921,14 +917,19 @@ def _tunable_summary(Kstat): global show_tunable_descriptions global alternate_tunable_layout - names = os.listdir("/sys/module/zfs/parameters/") - - values = {} - for name in names: - with open("/sys/module/zfs/parameters/" + name) as f: - value = f.read() - values[name] = value.strip() + def load_tunables(): + basepath = '/sys/module/zfs/parameters' + tunables = {} + for name in os.listdir(basepath): + if not name: + continue + path = '%s/%s' % (basepath, name) + with open(path) as f: + value = f.read() + tunables[name] = value.strip() + return tunables + tunables = load_tunables() descriptions = {} if show_tunable_descriptions: @@ -966,22 +967,17 @@ def _tunable_summary(Kstat): sys.stderr.write("Tunable descriptions will be disabled.\n") sys.stdout.write("ZFS Tunables:\n") - names.sort() if alternate_tunable_layout: fmt = "\t%s=%s\n" else: fmt = "\t%-50s%s\n" - for name in names: - - if not name: - continue - + for name in sorted(tunables.keys()): if show_tunable_descriptions and name in descriptions: sys.stdout.write("\t# %s\n" % descriptions[name]) - sys.stdout.write(fmt % (name, values[name])) + sys.stdout.write(fmt % (name, tunables[name])) unSub = [