]> git.proxmox.com Git - mirror_zfs.git/commitdiff
FreeBSD: Update usage of py-sysctl
authorRyan Moeller <ryan@iXsystems.com>
Tue, 8 Dec 2020 17:02:16 +0000 (17:02 +0000)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 23 Dec 2020 22:34:59 +0000 (14:34 -0800)
py-sysctl now includes the CTLTYPE_NODE type nodes in the list returned
by sysctl.filter() on FreeBSD head.  It also provides descriptions now.

Eliminate the subprocess call to get descriptions, and filter out the
nodes so we only deal with values.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ryan Moeller <ryan@iXsystems.com>
Closes #11318

cmd/arc_summary/arc_summary2
cmd/arc_summary/arc_summary3
cmd/arcstat/arcstat.in

index a925d32788eac4bf3f5a3e158dd6eb30a50a5b32..126b5b115f97f0c05b503da1bc27d6da1dd9f713 100755 (executable)
@@ -59,14 +59,20 @@ if sys.platform.startswith('freebsd'):
     # Requires py27-sysctl on FreeBSD
     import sysctl
 
+    def is_value(ctl):
+        return ctl.type != sysctl.CTLTYPE_NODE
+
     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)]
+        fmt = lambda kstat: (kstat.name, D(kstat.value))
+        kstats = sysctl.filter(base)
+        return [fmt(kstat) for kstat in kstats if is_value(kstat)]
 
     def load_tunables():
-        return dict((ctl.name, ctl.value) for ctl in sysctl.filter('vfs.zfs'))
+        ctls = sysctl.filter('vfs.zfs')
+        return dict((ctl.name, ctl.value) for ctl in ctls if is_value(ctl))
 
 elif sys.platform.startswith('linux'):
 
index 83cbf0f1728dbd9d9a94d6e9b829ee689645cba8..c0a64df84a156fa28ef64b264c78dffd1726ca06 100755 (executable)
@@ -86,16 +86,24 @@ if sys.platform.startswith('freebsd'):
 
     VDEV_CACHE_SIZE = 'vdev.cache_size'
 
+    def is_value(ctl):
+        return ctl.type != sysctl.CTLTYPE_NODE
+
+    def namefmt(ctl, base='vfs.zfs.'):
+        # base is removed from the name
+        cut = len(base)
+        return ctl.name[cut:]
+
     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):],
+        fmt = lambda kstat: '{name} : {value}'.format(name=namefmt(kstat, base),
                                                       value=kstat.value)
-        return [fmt(kstat) for kstat in sysctl.filter(base)]
+        kstats = sysctl.filter(base)
+        return [fmt(kstat) for kstat in kstats if is_value(kstat)]
 
     def get_params(base):
-        cut = 8 # = len('vfs.zfs.')
-        return {ctl.name[cut:]: str(ctl.value) for ctl in sysctl.filter(base)}
+        ctls = sysctl.filter(base)
+        return {namefmt(ctl): str(ctl.value) for ctl in ctls if is_value(ctl)}
 
     def get_tunable_params():
         return get_params('vfs.zfs')
@@ -112,25 +120,8 @@ if sys.platform.startswith('freebsd'):
         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])
+        ctls = sysctl.filter('vfs.zfs')
+        return {namefmt(ctl): ctl.description for ctl in ctls if is_value(ctl)}
 
 
 elif sys.platform.startswith('linux'):
index 941009d2396da65eb19d8dcef7ca1a55b14796d6..0e2e222a54c1a716d69cf264511c82053ddd7a68 100755 (executable)
@@ -128,13 +128,14 @@ pretty_print = True
 
 
 if sys.platform.startswith('freebsd'):
-    # Requires py27-sysctl on FreeBSD
+    # Requires py-sysctl on FreeBSD
     import sysctl
 
     def kstat_update():
         global kstat
 
-        k = sysctl.filter('kstat.zfs.misc.arcstats')
+        k = [ctl for ctl in sysctl.filter('kstat.zfs.misc.arcstats')
+             if ctl.type != sysctl.CTLTYPE_NODE]
 
         if not k:
             sys.exit(1)