Skip to content

Commit

Permalink
arc_summary: Make get_descriptions per platform
Browse files Browse the repository at this point in the history
Linux uses modinfo to get tunables descriptions, FreeBSD has to use
sysctl.

Move the existing function definition so it is defined that way on
Linux, and add a definition in terms of sysctl for FreeBSD.

Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Ryan Moeller <[email protected]>
Closes openzfs#10062
  • Loading branch information
Ryan Moeller authored and jsai20 committed Mar 30, 2021
1 parent 111f95c commit 24827ed
Showing 1 changed file with 76 additions and 53 deletions.
129 changes: 76 additions & 53 deletions cmd/arc_summary/arc_summary3
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,28 @@ if sys.platform.startswith('freebsd'):
version = sysctl.filter(mib)[0].value
return '{} version {}'.format(name, version)

def get_descriptions(_request):
# py-sysctl doesn't give descriptions, so we have to shell out.
command = ['sysctl', '-d', 'vfs.zfs']

# 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)
lines = info.stdout.split('\n')
else:
info = subprocess.check_output(command, universal_newlines=True)
lines = info.split('\n')

def fmt(line):
name, desc = line.split(':', 1)
return (name.strip(), desc.strip())

return dict([fmt(line) for line in lines if len(line) > 0])


elif sys.platform.startswith('linux'):
KSTAT_PATH = '/proc/spl/kstat/zfs'
SPL_PATH = '/sys/module/spl/parameters'
Expand Down Expand Up @@ -165,6 +187,60 @@ elif sys.platform.startswith('linux'):

return version

def get_descriptions(request):
"""Get the descriptions of the Solaris Porting Layer (SPL) or the
tunables, return with minimal formatting.
"""

if request not in ('spl', 'zfs'):
print('ERROR: description of "{0}" requested)'.format(request))
sys.exit(1)

descs = {}
target_prefix = 'parm:'

# We would prefer to do this with /sys/modules -- see the discussion at
# get_version() -- but there isn't a way to get the descriptions from
# there, so we fall back on modinfo
command = ["/sbin/modinfo", request, "-0"]

# 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 = ''

try:

if 'run' in dir(subprocess):
info = subprocess.run(command, stdout=subprocess.PIPE,
universal_newlines=True)
raw_output = info.stdout.split('\0')
else:
info = subprocess.check_output(command,
universal_newlines=True)
raw_output = info.split('\0')

except subprocess.CalledProcessError:
print("Error: Descriptions not available",
"(can't access kernel module)")
sys.exit(1)

for line in raw_output:

if not line.startswith(target_prefix):
continue

line = line[len(target_prefix):].strip()
name, raw_desc = line.split(':', 1)
desc = raw_desc.rsplit('(', 1)[0]

if desc == '':
desc = '(No description found)'

descs[name.strip()] = desc.strip()

return descs


def cleanup_line(single_line):
"""Format a raw line of data from /proc and isolate the name value
Expand Down Expand Up @@ -343,59 +419,6 @@ def get_kstats():
return result


def get_descriptions(request):
"""Get the descriptions of the Solaris Porting Layer (SPL) or the
tunables, return with minimal formatting.
"""

if request not in ('spl', 'zfs'):
print('ERROR: description of "{0}" requested)'.format(request))
sys.exit(1)

descs = {}
target_prefix = 'parm:'

# We would prefer to do this with /sys/modules -- see the discussion at
# get_version() -- but there isn't a way to get the descriptions from
# there, so we fall back on modinfo
command = ["/sbin/modinfo", request, "-0"]

# 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 = ''

try:

if 'run' in dir(subprocess):
info = subprocess.run(command, stdout=subprocess.PIPE,
universal_newlines=True)
raw_output = info.stdout.split('\0')
else:
info = subprocess.check_output(command, universal_newlines=True)
raw_output = info.split('\0')

except subprocess.CalledProcessError:
print("Error: Descriptions not available (can't access kernel module)")
sys.exit(1)

for line in raw_output:

if not line.startswith(target_prefix):
continue

line = line[len(target_prefix):].strip()
name, raw_desc = line.split(':', 1)
desc = raw_desc.rsplit('(', 1)[0]

if desc == '':
desc = '(No description found)'

descs[name.strip()] = desc.strip()

return descs


def get_version(request):
"""Get the version number of ZFS or SPL on this machine for header.
Returns an error string, but does not raise an error, if we can't
Expand Down

0 comments on commit 24827ed

Please sign in to comment.