diff --git a/cmd/Makefile.am b/cmd/Makefile.am index 88609e455..90270209b 100644 --- a/cmd/Makefile.am +++ b/cmd/Makefile.am @@ -5,4 +5,6 @@ if USING_PYTHON SUBDIRS += arcstat arc_summary dbufstat endif +if BUILD_LINUX SUBDIRS += mount_zfs zed zvol_id zvol_wait +endif diff --git a/cmd/arc_summary/arc_summary2 b/cmd/arc_summary/arc_summary2 index 2946ee195..8ae35c0db 100755 --- a/cmd/arc_summary/arc_summary2 +++ b/cmd/arc_summary/arc_summary2 @@ -55,6 +55,30 @@ from subprocess import Popen, PIPE from decimal import Decimal as D +if sys.platform.startswith('linux'): + + def load_kstats(namespace): + """Collect information on a specific subsystem of the ARC""" + + 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] + + 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 + + show_tunable_descriptions = False alternate_tunable_layout = False @@ -77,15 +101,6 @@ def get_Kstat(): of the same name. """ - def load_kstats(namespace): - """Collect information on a specific subsystem of the ARC""" - - 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 = {} Kstat.update(load_kstats('arcstats')) Kstat.update(load_kstats('zfetchstats')) @@ -917,18 +932,6 @@ def _tunable_summary(Kstat): global show_tunable_descriptions global alternate_tunable_layout - 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 = {} diff --git a/cmd/arc_summary/arc_summary3 b/cmd/arc_summary/arc_summary3 index a32b2caee..5d1c5d5b4 100755 --- a/cmd/arc_summary/arc_summary3 +++ b/cmd/arc_summary/arc_summary3 @@ -46,9 +46,6 @@ import time DESCRIPTION = 'Print ARC and other statistics for ZFS on Linux' INDENT = ' '*8 LINE_LENGTH = 72 -PROC_PATH = '/proc/spl/kstat/zfs/' -SPL_PATH = '/sys/module/spl/parameters/' -TUNABLES_PATH = '/sys/module/zfs/parameters/' DATE_FORMAT = '%a %b %d %H:%M:%S %Y' TITLE = 'ZFS Subsystem Report' @@ -83,58 +80,58 @@ parser.add_argument('-s', '--section', dest='section', help=SECTION_HELP) ARGS = parser.parse_args() -def get_params(basepath): - """Collect information on the Solaris Porting Layer (SPL) or the - tunables, depending on the PATH given. Does not check if PATH is - legal. - """ - result = {} - for name in os.listdir(basepath): - path = os.path.join(basepath, name) +if 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): + path = os.path.join(KSTAT_PATH, section) with open(path) as f: - value = f.read() - result[name] = value.strip() - return result + return list(f)[2:] # Get rid of header + def get_params(basepath): + """Collect information on the Solaris Porting Layer (SPL) or the + tunables, depending on the PATH given. Does not check if PATH is + legal. + """ + result = {} + for name in os.listdir(basepath): + path = os.path.join(basepath, name) + with open(path) as f: + value = f.read() + result[name] = value.strip() + return result -def get_spl_params(): - return get_params(SPL_PATH) + def get_spl_params(): + return get_params(SPL_PATH) + def get_tunable_params(): + return get_params(TUNABLES_PATH) -def get_tunable_params(): - return get_params(TUNABLES_PATH) + def get_vdev_params(): + return get_params(TUNABLES_PATH) + def get_version_impl(request): + # The original arc_summary called /sbin/modinfo/{spl,zfs} to get + # the version information. We switch to /sys/module/{spl,zfs}/version + # to make sure we get what is really loaded in the kernel + command = ["cat", "/sys/module/{0}/version".format(request)] + req = request.upper() -def get_vdev_params(): - return get_params(TUNABLES_PATH) + # The recommended way to do this is with subprocess.run(). However, + # some installed versions of Python are < 3.5, so we offer them + # the option of doing it the old way (for now) + if 'run' in dir(subprocess): + info = subprocess.run(command, stdout=subprocess.PIPE, + universal_newlines=True) + version = info.stdout.strip() + else: + info = subprocess.check_output(command, universal_newlines=True) + version = info.strip() - -def get_version_impl(request): - # The original arc_summary called /sbin/modinfo/{spl,zfs} to get - # the version information. We switch to /sys/module/{spl,zfs}/version - # to make sure we get what is really loaded in the kernel - command = ["cat", "/sys/module/{0}/version".format(request)] - req = request.upper() - - # The recommended way to do this is with subprocess.run(). However, - # some installed versions of Python are < 3.5, so we offer them - # the option of doing it the old way (for now) - info = '' - if 'run' in dir(subprocess): - info = subprocess.run(command, stdout=subprocess.PIPE, - universal_newlines=True) - version = info.stdout.strip() - else: - info = subprocess.check_output(command, universal_newlines=True) - version = info.strip() - - return version - - -def load_kstats(section): - path = os.path.join(PROC_PATH, section) - with open(path) as f: - return list(f)[2:] # Get rid of header + return version def cleanup_line(single_line): @@ -299,10 +296,10 @@ def format_raw_line(name, value): def get_kstats(): - """Collect information on the ZFS subsystem from the /proc Linux virtual - file system. The step does not perform any further processing, giving us - the option to only work on what is actually needed. The name "kstat" is a - holdover from the Solaris utility of the same name. + """Collect information on the ZFS subsystem. The step does not perform any + further processing, giving us the option to only work on what is actually + needed. The name "kstat" is a holdover from the Solaris utility of the same + name. """ result = {} @@ -382,7 +379,7 @@ def get_version(request): def print_header(): """Print the initial heading with date and time as well as info on the - Linux and ZFS versions. This is not called for the graph. + kernel and ZFS versions. This is not called for the graph. """ # datetime is now recommended over time but we keep the exact formatting @@ -779,7 +776,7 @@ def section_vdev(kstats_dict): # for details tunables = get_vdev_params() - if tunables['zfs_vdev_cache_size'] == '0': + if tunables[VDEV_CACHE_SIZE] == '0': print('VDEV cache disabled, skipping section\n') return diff --git a/cmd/arcstat/arcstat b/cmd/arcstat/arcstat index 003499928..7562038d1 100755 --- a/cmd/arcstat/arcstat +++ b/cmd/arcstat/arcstat @@ -54,6 +54,7 @@ import copy from decimal import Decimal from signal import signal, SIGINT, SIGWINCH, SIG_DFL + cols = { # HDR: [Size, Scale, Description] "time": [8, -1, "Time"], @@ -118,6 +119,26 @@ out = None kstat = None +if sys.platform.startswith('linux'): + def kstat_update(): + global kstat + + k = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')] + + if not k: + sys.exit(1) + + del k[0:2] + kstat = {} + + for s in k: + if not s: + continue + + name, unused, value = s.split() + kstat[name] = Decimal(value) + + def detailed_usage(): sys.stderr.write("%s\n" % cmd) sys.stderr.write("Field definitions are as follows:\n") @@ -148,25 +169,6 @@ def usage(): sys.exit(1) -def kstat_update(): - global kstat - - k = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')] - - if not k: - sys.exit(1) - - del k[0:2] - kstat = {} - - for s in k: - if not s: - continue - - name, unused, value = s.split() - kstat[name] = Decimal(value) - - def snap_stats(): global cur global kstat