2021-08-07 00:10:57

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 0/9] Add a tool for using the new sysfs files

From: Anna Schumaker <[email protected]>

These patches implement a tool that can be used to read and write the
sysfs files, with subcommands! They do need my extra patches to add in
srcaddr and dst_port to the xprt_info file. Let me know if I need to
resend adding support for kernels both with and without these patches.

The following subcommands are implemented:
nfs-sysfs.py rpc-client
nfs-sysfs.py xprt
nfs-sysfs.py xprt set
nfs-sysfs.py xprt-switch
nfs-sysfs.py xprt-switch set

So you can print out information about every xprt-switch with:
anna@client ~ % nfs-sysfs xprt-switch
switch 0: num_xprts 1, num_active 1, queue_len 0
xprt 0: local, /var/run/gssproxy.sock [main]
switch 1: num_xprts 1, num_active 1, queue_len 0
xprt 1: local, /var/run/rpcbind.sock [main]
switch 2: num_xprts 1, num_active 1, queue_len 0
xprt 2: tcp, 192.168.111.1 [main]
switch 3: num_xprts 4, num_active 4, queue_len 0
xprt 3: tcp, 192.168.111.188 [main]
xprt 4: tcp, 192.168.111.188
xprt 5: tcp, 192.168.111.188
xprt 6: tcp, 192.168.111.188

And information about each xprt:
anna@client ~ % nfs-sysfs xprt
xprt 0: local, /var/run/gssproxy.sock, port 0, state <MAIN,CONNECTED,BOUND>
Source: (einval), port 0, Requests: 2
Congestion: cur 0, win 256, Slots: min 2, max 65536
Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
xprt 1: local, /var/run/rpcbind.sock, port 0, state <MAIN,CONNECTED,BOUND>
Source: (einval), port 0, Requests: 2
Congestion: cur 0, win 256, Slots: min 2, max 65536
Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
xprt 2: tcp, 192.168.111.1, port 2049, state <MAIN,CONNECTED,BOUND>
Source: 192.168.111.222, port 959, Requests: 2
Congestion: cur 0, win 256, Slots: min 2, max 65536
Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
xprt 3: tcp, 192.168.111.188, port 2049, state <MAIN,CONNECTED,BOUND>
Source: 192.168.111.222, port 921, Requests: 2
Congestion: cur 0, win 256, Slots: min 2, max 65536
Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
xprt 4: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
Source: 192.168.111.222, port 726, Requests: 2
Congestion: cur 0, win 256, Slots: min 2, max 65536
Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
xprt 5: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
Source: 192.168.111.222, port 671, Requests: 2
Congestion: cur 0, win 256, Slots: min 2, max 65536
Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
xprt 6: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
Source: 192.168.111.222, port 934, Requests: 2
Congestion: cur 0, win 256, Slots: min 2, max 65536
Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0

You can use the `set` subcommand to change the dstaddr of individual xprts:
anna@client ~ % sudo nfs-sysfs xprt --id 4
xprt 4: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
Source: 192.168.111.222, port 726, Requests: 2
Congestion: cur 0, win 256, Slots: min 2, max 65536
Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
anna@client ~ % sudo nfs-sysfs xprt set --id 4 --dstaddr server2.nowheycreamery.com
xprt 4: tcp, 192.168.111.186, port 2049, state <CONNECTED,BOUND>
Source: 192.168.111.222, port 726, Requests: 2
Congestion: cur 0, win 256, Slots: min 2, max 65536
Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0

Or for changing the dstaddr of all xprts attached to a switch:
anna@client % ./nfs-sysfs.py xprt-switch --id 3
switch 3: num_xprts 4, num_active 4, queue_len 0
xprt 3: tcp, 192.168.111.188 [main]
xprt 4: tcp, 192.168.111.188
xprt 5: tcp, 192.168.111.188
xprt 6: tcp, 192.168.111.188
anna@client % sudo ./nfs-sysfs.py xprt-switch set --id 4 --dstaddr server2.nowheycreamery.vm
switch 3: num_xprts 4, num_active 4, queue_len 0
xprt 2: tcp, 192.168.111.186 [main]
xprt 3: tcp, 192.168.111.186
xprt 5: tcp, 192.168.111.186
xprt 6: tcp, 192.168.111.186


What does everybody think? Is there any thing I should change about the
user input or output lines? How about other subcommands that should be
added with the initial submission?

Thanks,
Anna


Anna Schumaker (9):
nfs-sysfs: Add an nfs-sysfs.py tool
nfs-sysfs.py: Add a command for printing xprt switch information
nfs-sysfs.py: Add a command for printing individual xprts
nfs-sysfs.py: Add a command for printing rpc-client information
nfs-sysfs.py: Add a command for changing xprt dstaddr
nfs-sysfs.py: Add a command for changing xprt-switch dstaddrs
nfs-sysfs.py: Add a command for changing xprt state
nfs-sysfs: Add a man page
nfs-sysfs: Add installation to the Makefile

.gitignore | 2 +
configure.ac | 1 +
tools/Makefile.am | 2 +-
tools/nfs-sysfs/Makefile.am | 20 +++++++
tools/nfs-sysfs/client.py | 27 +++++++++
tools/nfs-sysfs/nfs-sysfs | 5 ++
tools/nfs-sysfs/nfs-sysfs.man | 88 +++++++++++++++++++++++++++++
tools/nfs-sysfs/nfs-sysfs.py | 23 ++++++++
tools/nfs-sysfs/switch.py | 51 +++++++++++++++++
tools/nfs-sysfs/sysfs.py | 28 ++++++++++
tools/nfs-sysfs/xprt.py | 101 ++++++++++++++++++++++++++++++++++
11 files changed, 347 insertions(+), 1 deletion(-)
create mode 100644 tools/nfs-sysfs/Makefile.am
create mode 100644 tools/nfs-sysfs/client.py
create mode 100644 tools/nfs-sysfs/nfs-sysfs
create mode 100644 tools/nfs-sysfs/nfs-sysfs.man
create mode 100755 tools/nfs-sysfs/nfs-sysfs.py
create mode 100644 tools/nfs-sysfs/switch.py
create mode 100644 tools/nfs-sysfs/sysfs.py
create mode 100644 tools/nfs-sysfs/xprt.py

--
2.32.0


2021-08-07 00:11:02

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 4/9] nfs-sysfs.py: Add a command for printing rpc-client information

From: Anna Schumaker <[email protected]>

It's mostly the same information as with xprt-switches, except with
rpc-client id prepended to the first line.

Signed-off-by: Anna Schumaker <[email protected]>
---
tools/nfs-sysfs/client.py | 27 +++++++++++++++++++++++++++
tools/nfs-sysfs/nfs-sysfs.py | 2 ++
tools/nfs-sysfs/switch.py | 7 ++++---
3 files changed, 33 insertions(+), 3 deletions(-)
create mode 100644 tools/nfs-sysfs/client.py

diff --git a/tools/nfs-sysfs/client.py b/tools/nfs-sysfs/client.py
new file mode 100644
index 000000000000..5192cc226aed
--- /dev/null
+++ b/tools/nfs-sysfs/client.py
@@ -0,0 +1,27 @@
+import sysfs
+import switch
+
+class RpcClient:
+ def __init__(self, path):
+ self.path = path
+ self.id = int(str(path).rsplit("-", 1)[1])
+ self.switch = switch.XprtSwitch(path / (path / "switch").readlink(), sep=",")
+
+ def __lt__(self, rhs):
+ return self.id < rhs.id
+
+ def __str__(self):
+ return "client %s: %s" % (self.id, self.switch)
+
+
+def list_rpc_clients(args):
+ clients = [ RpcClient(f) for f in (sysfs.SUNRPC / "rpc-clients").iterdir() ]
+ clients.sort()
+ for client in clients:
+ if args.id == None or client.id == args.id[0]:
+ print(client)
+
+def add_command(subparser):
+ parser = subparser.add_parser("rpc-client", help="Commands for rpc clients")
+ parser.add_argument("--id", metavar="ID", nargs=1, type=int, help="Id of a specific client to show")
+ parser.set_defaults(func=list_rpc_clients)
diff --git a/tools/nfs-sysfs/nfs-sysfs.py b/tools/nfs-sysfs/nfs-sysfs.py
index dfad6ac08fa0..e2172cdfa4c1 100755
--- a/tools/nfs-sysfs/nfs-sysfs.py
+++ b/tools/nfs-sysfs/nfs-sysfs.py
@@ -10,9 +10,11 @@ def show_small_help(args):
parser.set_defaults(func=show_small_help)


+import client
import switch
import xprt
subparser = parser.add_subparsers(title="commands")
+client.add_command(subparser)
switch.add_command(subparser)
xprt.add_command(subparser)

diff --git a/tools/nfs-sysfs/switch.py b/tools/nfs-sysfs/switch.py
index afb6963a0a1f..5384f970235c 100644
--- a/tools/nfs-sysfs/switch.py
+++ b/tools/nfs-sysfs/switch.py
@@ -2,9 +2,10 @@ import sysfs
import xprt

class XprtSwitch:
- def __init__(self, path):
+ def __init__(self, path, sep=":"):
self.path = path
self.id = int(str(path).rsplit("-", 1)[1])
+ self.sep = sep

self.xprts = [ xprt.Xprt(p) for p in self.path.iterdir() if p.is_dir() ]
self.xprts.sort()
@@ -15,8 +16,8 @@ class XprtSwitch:
return self.path < rhs.path

def __str__(self):
- line = "switch %s: num_xprts %s, num_active %s, queue_len %s" % \
- (self.id, self.num_xprts, self.num_active, self.queue_len)
+ line = "switch %s%s num_xprts %s, num_active %s, queue_len %s" % \
+ (self.id, self.sep, self.num_xprts, self.num_active, self.queue_len)
for x in self.xprts:
line += "\n %s" % x.small_str()
return line
--
2.32.0

2021-08-07 00:11:10

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 9/9] nfs-sysfs: Add installation to the Makefile

From: Anna Schumaker <[email protected]>

And create a shell script that launches the python program from the
$(libdir)

Signed-off-by: Anna Schumaker <[email protected]>
---
configure.ac | 1 +
tools/Makefile.am | 2 +-
tools/nfs-sysfs/Makefile.am | 20 ++++++++++++++++++++
tools/nfs-sysfs/nfs-sysfs | 5 +++++
4 files changed, 27 insertions(+), 1 deletion(-)
create mode 100644 tools/nfs-sysfs/Makefile.am
create mode 100644 tools/nfs-sysfs/nfs-sysfs

diff --git a/configure.ac b/configure.ac
index bc2d0f02979c..092e230551f2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -731,6 +731,7 @@ AC_CONFIG_FILES([
tools/rpcgen/Makefile
tools/mountstats/Makefile
tools/nfs-iostat/Makefile
+ tools/nfs-sysfs/Makefile
tools/nfsdclnts/Makefile
tools/nfsconf/Makefile
tools/nfsdclddb/Makefile
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 9b4b0803db39..1c89d66be744 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -12,6 +12,6 @@ if CONFIG_NFSDCLD
OPTDIRS += nfsdclddb
endif

-SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat nfsdclnts $(OPTDIRS)
+SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat nfs-sysfs nfsdclnts $(OPTDIRS)

MAINTAINERCLEANFILES = Makefile.in
diff --git a/tools/nfs-sysfs/Makefile.am b/tools/nfs-sysfs/Makefile.am
new file mode 100644
index 000000000000..bdfc7454a7a1
--- /dev/null
+++ b/tools/nfs-sysfs/Makefile.am
@@ -0,0 +1,20 @@
+## Process this file with automake to produce Makefile.in
+PYTHON_FILES = nfs-sysfs.py client.py switch.py sysfs.py xprt.py
+tooldir = $(DESTDIR)$(libdir)/nfs-sysfs
+
+man8_MANS = nfs-sysfs.man
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ mkdir -p $(tooldir)
+ for f in $(PYTHON_FILES) ; do \
+ $(INSTALL) -m 644 $$f $(tooldir)/$$f ; \
+ done
+ chmod +x $(tooldir)/nfs-sysfs.py
+ $(INSTALL) -m 755 nfs-sysfs $(DESTDIR)$(sbindir)/nfs-sysfs
+ sed -i "s|LIBDIR=.|LIBDIR=$(tooldir)|" $(DESTDIR)$(sbindir)/nfs-sysfs
+
+
+
+MAINTAINERCLEANFILES=Makefile.in
diff --git a/tools/nfs-sysfs/nfs-sysfs b/tools/nfs-sysfs/nfs-sysfs
new file mode 100644
index 000000000000..f7ce621eff57
--- /dev/null
+++ b/tools/nfs-sysfs/nfs-sysfs
@@ -0,0 +1,5 @@
+#!/bin/bash
+LIBDIR=.
+PYTHON3=/usr/bin/python
+
+exec $PYTHON3 $LIBDIR/nfs-sysfs.py $*
--
2.32.0

2021-08-07 00:11:14

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 6/9] nfs-sysfs.py: Add a command for changing xprt-switch dstaddrs

From: Anna Schumaker <[email protected]>

This is basically the same as for xprts, but it iterates through all
xprts attached to the switch to apply the new address.

Signed-off-by: Anna Schumaker <[email protected]>
---
tools/nfs-sysfs/switch.py | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/tools/nfs-sysfs/switch.py b/tools/nfs-sysfs/switch.py
index 5384f970235c..859b82e07895 100644
--- a/tools/nfs-sysfs/switch.py
+++ b/tools/nfs-sysfs/switch.py
@@ -30,7 +30,22 @@ def list_xprt_switches(args):
if args.id == None or xs.id == args.id[0]:
print(xs)

+def set_xprt_switch_property(args):
+ switch = XprtSwitch(sysfs.SUNRPC / "xprt-switches" / f"switch-{args.id[0]}")
+ try:
+ for xprt in switch.xprts:
+ xprt.set_dstaddr(args.dstaddr[0])
+ print(switch)
+ except Exception as e:
+ print(e)
+
def add_command(subparser):
parser = subparser.add_parser("xprt-switch", help="Commands for xprt switches")
parser.add_argument("--id", metavar="ID", nargs=1, type=int, help="Id of a specific xprt-switch to show")
parser.set_defaults(func=list_xprt_switches)
+
+ subparser = parser.add_subparsers()
+ parser = subparser.add_parser("set", help="Set an xprt switch property")
+ parser.add_argument("--id", metavar="ID", nargs=1, type=int, required=True, help="Id of an xprt-switch to modify")
+ parser.add_argument("--dstaddr", metavar="dstaddr", nargs=1, type=str, help="New dstaddr to set")
+ parser.set_defaults(func=set_xprt_switch_property)
--
2.32.0

2021-08-07 00:11:17

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 1/9] nfs-sysfs: Add an nfs-sysfs.py tool

From: Anna Schumaker <[email protected]>

This will be used to print and manipulate the sunrpc sysfs directory
files. Running without arguments prints both usage information and the
location of the sunrpc sysfs directory.

Signed-off-by: Anna Schumaker <[email protected]>
---
.gitignore | 2 ++
tools/nfs-sysfs/nfs-sysfs.py | 13 +++++++++++++
tools/nfs-sysfs/sysfs.py | 18 ++++++++++++++++++
3 files changed, 33 insertions(+)
create mode 100755 tools/nfs-sysfs/nfs-sysfs.py
create mode 100644 tools/nfs-sysfs/sysfs.py

diff --git a/.gitignore b/.gitignore
index c89d1cd2583d..a476bd20bc3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -84,3 +84,5 @@ systemd/rpc-gssd.service
cscope.*
# generic editor backup et al
*~
+# python bytecode
+__pycache__
diff --git a/tools/nfs-sysfs/nfs-sysfs.py b/tools/nfs-sysfs/nfs-sysfs.py
new file mode 100755
index 000000000000..8ff59ea9e81b
--- /dev/null
+++ b/tools/nfs-sysfs/nfs-sysfs.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+import argparse
+import sysfs
+
+parser = argparse.ArgumentParser()
+
+def show_small_help(args):
+ parser.print_usage()
+ print("sunrpc dir:", sysfs.SUNRPC)
+parser.set_defaults(func=show_small_help)
+
+args = parser.parse_args()
+args.func(args)
diff --git a/tools/nfs-sysfs/sysfs.py b/tools/nfs-sysfs/sysfs.py
new file mode 100644
index 000000000000..0b358f57bb28
--- /dev/null
+++ b/tools/nfs-sysfs/sysfs.py
@@ -0,0 +1,18 @@
+import pathlib
+import sys
+
+MOUNT = None
+with open("/proc/mounts", 'r') as f:
+ for line in f:
+ if "sysfs" in line:
+ MOUNT = line.split()[1]
+ break
+
+if MOUNT == None:
+ print("ERROR: sysfs is not mounted")
+ sys.exit(1)
+
+SUNRPC = pathlib.Path(MOUNT) / "kernel" / "sunrpc"
+if not SUNRPC.is_dir():
+ print("ERROR: sysfs does not have sunrpc directory")
+ sys.exit(1)
--
2.32.0

2021-08-07 00:11:17

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 3/9] nfs-sysfs.py: Add a command for printing individual xprts

From: Anna Schumaker <[email protected]>

This shows more detailed information than what is presented with xprt
switches. I take the chance to add a main-export indicator to the
small_str() used when printing out xprt-switches.

Signed-off-by: Anna Schumaker <[email protected]>
---
tools/nfs-sysfs/nfs-sysfs.py | 2 ++
tools/nfs-sysfs/xprt.py | 38 +++++++++++++++++++++++++++++++++++-
2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/tools/nfs-sysfs/nfs-sysfs.py b/tools/nfs-sysfs/nfs-sysfs.py
index 90efcbed7ac8..dfad6ac08fa0 100755
--- a/tools/nfs-sysfs/nfs-sysfs.py
+++ b/tools/nfs-sysfs/nfs-sysfs.py
@@ -11,8 +11,10 @@ parser.set_defaults(func=show_small_help)


import switch
+import xprt
subparser = parser.add_subparsers(title="commands")
switch.add_command(subparser)
+xprt.add_command(subparser)


args = parser.parse_args()
diff --git a/tools/nfs-sysfs/xprt.py b/tools/nfs-sysfs/xprt.py
index d37537771c1d..fbdd9bfc9375 100644
--- a/tools/nfs-sysfs/xprt.py
+++ b/tools/nfs-sysfs/xprt.py
@@ -1,12 +1,48 @@
+import sysfs
+
class Xprt:
def __init__(self, path):
self.path = path
self.id = int(str(path).rsplit("-", 2)[1])
self.type = str(path).rsplit("-", 2)[2]
self.dstaddr = open(path / "dstaddr", 'r').readline().strip()
+ self.srcaddr = open(path / "srcaddr", 'r').readline().strip()
+
+ with open(path / "xprt_state") as f:
+ self.state = ','.join(f.readline().split()[1:])
+ self.__dict__.update(sysfs.read_info_file(path / "xprt_info"))

def __lt__(self, rhs):
return self.id < rhs.id

+ def __str__(self):
+ state = self.state
+ if self.main_xprt:
+ state = "MAIN," + self.state
+
+ line = "xprt %s: %s, %s, port %s, state <%s>" % \
+ (self.id, self.type, self.dstaddr, self.dst_port, state)
+ line += "\n Source: %s, port %s, Requests: %s" % \
+ (self.srcaddr, self.src_port, self.num_reqs)
+ line += "\n Congestion: cur %s, win %s, Slots: min %s, max %s" % \
+ (self.cur_cong, self.cong_win, self.min_num_slots, self.max_num_slots)
+ line += "\n Queues: binding %s, sending %s, pending %s, backlog %s, tasks %s" % \
+ (self.binding_q_len, self.sending_q_len, self.pending_q_len, self.backlog_q_len, self.tasks_queuelen)
+ return line
+
def small_str(self):
- return "xprt %s: %s, %s" % (self.id, self.type, self.dstaddr)
+ return "xprt %s: %s, %s%s" % (self.id, self.type, self.dstaddr,
+ f" [main]" if self.main_xprt else "" )
+
+
+def list_xprts(args):
+ xprts = [ Xprt(f) for f in (sysfs.SUNRPC / "xprt-switches").glob("**/xprt-*") ]
+ xprts.sort()
+ for xprt in xprts:
+ if args.id == None or xprt.id == args.id[0]:
+ print(xprt)
+
+def add_command(subparser):
+ parser = subparser.add_parser("xprt", help="Commands for individual xprts")
+ parser.add_argument("--id", metavar="ID", nargs=1, type=int, help="Id of a specific xprt to show")
+ parser.set_defaults(func=list_xprts)
--
2.32.0

2021-08-07 00:11:23

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 5/9] nfs-sysfs.py: Add a command for changing xprt dstaddr

From: Anna Schumaker <[email protected]>

Using the socket module for dns resolution

Signed-off-by: Anna Schumaker <[email protected]>
---
tools/nfs-sysfs/xprt.py | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)

diff --git a/tools/nfs-sysfs/xprt.py b/tools/nfs-sysfs/xprt.py
index fbdd9bfc9375..2160cb0a9575 100644
--- a/tools/nfs-sysfs/xprt.py
+++ b/tools/nfs-sysfs/xprt.py
@@ -1,3 +1,4 @@
+import socket
import sysfs

class Xprt:
@@ -34,6 +35,12 @@ class Xprt:
return "xprt %s: %s, %s%s" % (self.id, self.type, self.dstaddr,
f" [main]" if self.main_xprt else "" )

+ def set_dstaddr(self, newaddr):
+ resolved = socket.gethostbyname(newaddr)
+ with open(self.path / "dstaddr", 'w') as f:
+ f.write(resolved)
+ self.dstaddr = open(self.path / "dstaddr", 'r').readline().strip()
+

def list_xprts(args):
xprts = [ Xprt(f) for f in (sysfs.SUNRPC / "xprt-switches").glob("**/xprt-*") ]
@@ -42,7 +49,28 @@ def list_xprts(args):
if args.id == None or xprt.id == args.id[0]:
print(xprt)

+def get_xprt(id):
+ xprts = [ Xprt(f) for f in (sysfs.SUNRPC / "xprt-switches").glob("**/xprt-*") ]
+ for xprt in xprts:
+ if xprt.id == id:
+ return xprt
+
+def set_xprt_property(args):
+ xprt = get_xprt(args.id[0])
+ try:
+ if args.dstaddr != None:
+ xprt.set_dstaddr(args.dstaddr[0])
+ print(xprt)
+ except Exception as e:
+ print(e)
+
def add_command(subparser):
parser = subparser.add_parser("xprt", help="Commands for individual xprts")
parser.add_argument("--id", metavar="ID", nargs=1, type=int, help="Id of a specific xprt to show")
parser.set_defaults(func=list_xprts)
+
+ subparser = parser.add_subparsers()
+ parser = subparser.add_parser("set", help="Set an xprt property")
+ parser.add_argument("--id", metavar="ID", nargs=1, type=int, required=True, help="Id of a specific xprt to modify")
+ parser.add_argument("--dstaddr", metavar="dstaddr", nargs=1, type=str, help="New dstaddr to set")
+ parser.set_defaults(func=set_xprt_property)
--
2.32.0

2021-08-07 00:11:41

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 8/9] nfs-sysfs: Add a man page

From: Anna Schumaker <[email protected]>

Signed-off-by: Anna Schumaker <[email protected]>
---
tools/nfs-sysfs/nfs-sysfs.man | 88 +++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
create mode 100644 tools/nfs-sysfs/nfs-sysfs.man

diff --git a/tools/nfs-sysfs/nfs-sysfs.man b/tools/nfs-sysfs/nfs-sysfs.man
new file mode 100644
index 000000000000..3ebbeaf93eaa
--- /dev/null
+++ b/tools/nfs-sysfs/nfs-sysfs.man
@@ -0,0 +1,88 @@
+.\"
+.\" nfs-sysfs(8)
+.\"
+.TH nfs-sysfs 8 "05 Aug 2021"
+.SH NAME
+nfs-sysfs \- Displays NFS & SunRPC connection information
+.SH SYNOPSIS
+.B nfs-sysfs
+.RB [ \-h | \-\-help ]
+.P
+.B nfs-sysfs rpc-client
+.RB [ \-h | \-\-help ]
+.RB [ \--id
+.IR ID ]
+.P
+.B nfs-sysfs xprt-switch
+.RB [ \-h | \-\-help ]
+.RB [ \--id
+.IR ID ]
+.P
+.B nfs-sysfs xprt-switch set
+.RB [ \-h | \-\-help ]
+.RB [ \--id
+.IR ID ]
+.RB [ \--dstaddr
+.IR dstaddr]
+.P
+.B nfs-sysfs xprt
+.RB [ \-h | \-\-help ]
+.RB [ \--id
+.IR ID ]
+.P
+.B nfs-sysfs xprt set
+.RB [ \-h | \-\-help ]
+.RB [ \--id
+.IR ID ]
+.RB [ \--dstaddr
+.IR dstaddr]
+.RB [ --offline ]
+.RB [ --online ]
+.RB [ --remove ]
+.P
+.SH DESCRIPTION
+.RB "The " nfs-sysfs " command displays information collected in the SunRPC sysfs files about the system's SunRPC objects.
+.P
+.SS Objects
+Valid
+.BR nfs-sysfs (8)
+objects are:
+.IP "\fBrpc-client\fP"
+Display information about this system's RPC clients.
+.IP "\fBxprt-switch\fP"
+Display information about groups of transports.
+.IP "\fBxprt\fP"
+Display detailed information about each transport that exists on the system.
+.SH OPTIONS
+.SS Options valid for all objects
+.TP
+.B \-h, \-\-help
+Show the help message and exit
+.TP
+.B \-\-id \fIID
+Set or display properties for the object with the given
+.IR ID.
+This option is mandatory for setting properties.
+.SS Options specific to the `xprt-switch set` sub-command
+.TP
+.B \-\-dstaddr \fIdstaddr
+Change the destination address of all transports in the xprt-switch to
+.IR dstaddr
+.SS Options specific to the `xprt set` sub-command
+.TP
+.B \-\-dstaddr \fIdstaddr
+Change the destination address of this specific transport to
+.TP
+.B \-\-offline
+Change the transport state from online to offline
+.TP
+.B \-\-online
+Change the transport state from offline to online
+.TP
+.B \-\-remove
+Removes the transport from the xprt-switch. Note that "main" transports cannot be removed.
+.SH DIRECTORY
+.TP
+.B /sys/kernel/sunrpc/
+.SH AUTHOR
+Anna Schumaker <[email protected]>
--
2.32.0

2021-08-07 00:11:57

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 7/9] nfs-sysfs.py: Add a command for changing xprt state

From: Anna Schumaker <[email protected]>

We can set it offline or online, or we can remove an xprt. The kernel
only supports removing offlined transports, so we make sure to set the
state to "offline" before sending the remove command.

Signed-off-by: Anna Schumaker <[email protected]>
---
tools/nfs-sysfs/xprt.py | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/tools/nfs-sysfs/xprt.py b/tools/nfs-sysfs/xprt.py
index 2160cb0a9575..92b83ebc4cd1 100644
--- a/tools/nfs-sysfs/xprt.py
+++ b/tools/nfs-sysfs/xprt.py
@@ -8,15 +8,18 @@ class Xprt:
self.type = str(path).rsplit("-", 2)[2]
self.dstaddr = open(path / "dstaddr", 'r').readline().strip()
self.srcaddr = open(path / "srcaddr", 'r').readline().strip()
+ self.exists = True

- with open(path / "xprt_state") as f:
- self.state = ','.join(f.readline().split()[1:])
+ self.read_state()
self.__dict__.update(sysfs.read_info_file(path / "xprt_info"))

def __lt__(self, rhs):
return self.id < rhs.id

def __str__(self):
+ if self.exists == False:
+ return "xprt %s: has been removed" % self.id
+
state = self.state
if self.main_xprt:
state = "MAIN," + self.state
@@ -31,6 +34,13 @@ class Xprt:
(self.binding_q_len, self.sending_q_len, self.pending_q_len, self.backlog_q_len, self.tasks_queuelen)
return line

+ def read_state(self):
+ if not self.path.exists():
+ self.exists = False
+ return
+ with open(self.path / "xprt_state") as f:
+ self.state = ','.join(f.readline().split()[1:])
+
def small_str(self):
return "xprt %s: %s, %s%s" % (self.id, self.type, self.dstaddr,
f" [main]" if self.main_xprt else "" )
@@ -41,6 +51,11 @@ class Xprt:
f.write(resolved)
self.dstaddr = open(self.path / "dstaddr", 'r').readline().strip()

+ def set_state(self, state):
+ with open(self.path / "xprt_state", 'w') as f:
+ f.write(state)
+ self.read_state()
+

def list_xprts(args):
xprts = [ Xprt(f) for f in (sysfs.SUNRPC / "xprt-switches").glob("**/xprt-*") ]
@@ -60,6 +75,13 @@ def set_xprt_property(args):
try:
if args.dstaddr != None:
xprt.set_dstaddr(args.dstaddr[0])
+ if args.offline == True:
+ xprt.set_state("offline")
+ elif args.online == True:
+ xprt.set_state("online")
+ elif args.remove == True:
+ xprt.set_state("offline")
+ xprt.set_state("remove")
print(xprt)
except Exception as e:
print(e)
@@ -73,4 +95,7 @@ def add_command(subparser):
parser = subparser.add_parser("set", help="Set an xprt property")
parser.add_argument("--id", metavar="ID", nargs=1, type=int, required=True, help="Id of a specific xprt to modify")
parser.add_argument("--dstaddr", metavar="dstaddr", nargs=1, type=str, help="New dstaddr to set")
+ parser.add_argument("--offline", action="store_true", help="Set an xprt offline")
+ parser.add_argument("--online", action="store_true", help="Set an offline xprt back online")
+ parser.add_argument("--remove", action="store_true", help="Remove an xprt")
parser.set_defaults(func=set_xprt_property)
--
2.32.0

2021-08-08 16:31:17

by Steve Dickson

[permalink] [raw]
Subject: Re: [PATCH v2 0/9] Add a tool for using the new sysfs files

Hey Anna,

On 8/6/21 4:17 PM, [email protected] wrote:
> From: Anna Schumaker <[email protected]>
>
> These patches implement a tool that can be used to read and write the
> sysfs files, with subcommands! They do need my extra patches to add in
> srcaddr and dst_port to the xprt_info file. Let me know if I need to
> resend adding support for kernels both with and without these patches.
>
> The following subcommands are implemented:
> nfs-sysfs.py rpc-client
> nfs-sysfs.py xprt
> nfs-sysfs.py xprt set
> nfs-sysfs.py xprt-switch
> nfs-sysfs.py xprt-switch set
>
> So you can print out information about every xprt-switch with:
> anna@client ~ % nfs-sysfs xprt-switch
> switch 0: num_xprts 1, num_active 1, queue_len 0
> xprt 0: local, /var/run/gssproxy.sock [main]
> switch 1: num_xprts 1, num_active 1, queue_len 0
> xprt 1: local, /var/run/rpcbind.sock [main]
> switch 2: num_xprts 1, num_active 1, queue_len 0
> xprt 2: tcp, 192.168.111.1 [main]
> switch 3: num_xprts 4, num_active 4, queue_len 0
> xprt 3: tcp, 192.168.111.188 [main]
> xprt 4: tcp, 192.168.111.188
> xprt 5: tcp, 192.168.111.188
> xprt 6: tcp, 192.168.111.188
>
> And information about each xprt:
> anna@client ~ % nfs-sysfs xprt
> xprt 0: local, /var/run/gssproxy.sock, port 0, state <MAIN,CONNECTED,BOUND>
> Source: (einval), port 0, Requests: 2
> Congestion: cur 0, win 256, Slots: min 2, max 65536
> Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> xprt 1: local, /var/run/rpcbind.sock, port 0, state <MAIN,CONNECTED,BOUND>
> Source: (einval), port 0, Requests: 2
> Congestion: cur 0, win 256, Slots: min 2, max 65536
> Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> xprt 2: tcp, 192.168.111.1, port 2049, state <MAIN,CONNECTED,BOUND>
> Source: 192.168.111.222, port 959, Requests: 2
> Congestion: cur 0, win 256, Slots: min 2, max 65536
> Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> xprt 3: tcp, 192.168.111.188, port 2049, state <MAIN,CONNECTED,BOUND>
> Source: 192.168.111.222, port 921, Requests: 2
> Congestion: cur 0, win 256, Slots: min 2, max 65536
> Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> xprt 4: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
> Source: 192.168.111.222, port 726, Requests: 2
> Congestion: cur 0, win 256, Slots: min 2, max 65536
> Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> xprt 5: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
> Source: 192.168.111.222, port 671, Requests: 2
> Congestion: cur 0, win 256, Slots: min 2, max 65536
> Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> xprt 6: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
> Source: 192.168.111.222, port 934, Requests: 2
> Congestion: cur 0, win 256, Slots: min 2, max 65536
> Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
>
> You can use the `set` subcommand to change the dstaddr of individual xprts:
> anna@client ~ % sudo nfs-sysfs xprt --id 4
> xprt 4: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
> Source: 192.168.111.222, port 726, Requests: 2
> Congestion: cur 0, win 256, Slots: min 2, max 65536
> Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> anna@client ~ % sudo nfs-sysfs xprt set --id 4 --dstaddr server2.nowheycreamery.com
> xprt 4: tcp, 192.168.111.186, port 2049, state <CONNECTED,BOUND>
> Source: 192.168.111.222, port 726, Requests: 2
> Congestion: cur 0, win 256, Slots: min 2, max 65536
> Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
>
> Or for changing the dstaddr of all xprts attached to a switch:
> anna@client % ./nfs-sysfs.py xprt-switch --id 3
> switch 3: num_xprts 4, num_active 4, queue_len 0
> xprt 3: tcp, 192.168.111.188 [main]
> xprt 4: tcp, 192.168.111.188
> xprt 5: tcp, 192.168.111.188
> xprt 6: tcp, 192.168.111.188
> anna@client % sudo ./nfs-sysfs.py xprt-switch set --id 4 --dstaddr server2.nowheycreamery.vm
> switch 3: num_xprts 4, num_active 4, queue_len 0
> xprt 2: tcp, 192.168.111.186 [main]
> xprt 3: tcp, 192.168.111.186
> xprt 5: tcp, 192.168.111.186
> xprt 6: tcp, 192.168.111.186
>
>
> What does everybody think? Is there any thing I should change about the
> user input or output lines? How about other subcommands that should be
> added with the initial submission?
I have not play around with this new tool.. but I will! Looking
forward to it... But... and I should have mention this in v1
my apologies.

The rest of the NFS tools do not have have "nfs-" as the
prefix only an "nfs"... As with nfs-iostat, I'll me more that
will to take the patch with the '-' char, but I would
prefer the man page and the installed script be call nfssysfs,
just to say with the current naming conventions.

steved.

>
> Thanks,
> Anna
>
>
> Anna Schumaker (9):
> nfs-sysfs: Add an nfs-sysfs.py tool
> nfs-sysfs.py: Add a command for printing xprt switch information
> nfs-sysfs.py: Add a command for printing individual xprts
> nfs-sysfs.py: Add a command for printing rpc-client information
> nfs-sysfs.py: Add a command for changing xprt dstaddr
> nfs-sysfs.py: Add a command for changing xprt-switch dstaddrs
> nfs-sysfs.py: Add a command for changing xprt state
> nfs-sysfs: Add a man page
> nfs-sysfs: Add installation to the Makefile
>
> .gitignore | 2 +
> configure.ac | 1 +
> tools/Makefile.am | 2 +-
> tools/nfs-sysfs/Makefile.am | 20 +++++++
> tools/nfs-sysfs/client.py | 27 +++++++++
> tools/nfs-sysfs/nfs-sysfs | 5 ++
> tools/nfs-sysfs/nfs-sysfs.man | 88 +++++++++++++++++++++++++++++
> tools/nfs-sysfs/nfs-sysfs.py | 23 ++++++++
> tools/nfs-sysfs/switch.py | 51 +++++++++++++++++
> tools/nfs-sysfs/sysfs.py | 28 ++++++++++
> tools/nfs-sysfs/xprt.py | 101 ++++++++++++++++++++++++++++++++++
> 11 files changed, 347 insertions(+), 1 deletion(-)
> create mode 100644 tools/nfs-sysfs/Makefile.am
> create mode 100644 tools/nfs-sysfs/client.py
> create mode 100644 tools/nfs-sysfs/nfs-sysfs
> create mode 100644 tools/nfs-sysfs/nfs-sysfs.man
> create mode 100755 tools/nfs-sysfs/nfs-sysfs.py
> create mode 100644 tools/nfs-sysfs/switch.py
> create mode 100644 tools/nfs-sysfs/sysfs.py
> create mode 100644 tools/nfs-sysfs/xprt.py
>

2021-08-08 19:01:36

by Anna Schumaker

[permalink] [raw]
Subject: Re: [PATCH v2 0/9] Add a tool for using the new sysfs files

Hi Steve,

On Sun, Aug 8, 2021 at 12:30 PM Steve Dickson <[email protected]> wrote:
>
> Hey Anna,
>
> On 8/6/21 4:17 PM, [email protected] wrote:
> > From: Anna Schumaker <[email protected]>
> >
> > These patches implement a tool that can be used to read and write the
> > sysfs files, with subcommands! They do need my extra patches to add in
> > srcaddr and dst_port to the xprt_info file. Let me know if I need to
> > resend adding support for kernels both with and without these patches.
> >
> > The following subcommands are implemented:
> > nfs-sysfs.py rpc-client
> > nfs-sysfs.py xprt
> > nfs-sysfs.py xprt set
> > nfs-sysfs.py xprt-switch
> > nfs-sysfs.py xprt-switch set
> >
> > So you can print out information about every xprt-switch with:
> > anna@client ~ % nfs-sysfs xprt-switch
> > switch 0: num_xprts 1, num_active 1, queue_len 0
> > xprt 0: local, /var/run/gssproxy.sock [main]
> > switch 1: num_xprts 1, num_active 1, queue_len 0
> > xprt 1: local, /var/run/rpcbind.sock [main]
> > switch 2: num_xprts 1, num_active 1, queue_len 0
> > xprt 2: tcp, 192.168.111.1 [main]
> > switch 3: num_xprts 4, num_active 4, queue_len 0
> > xprt 3: tcp, 192.168.111.188 [main]
> > xprt 4: tcp, 192.168.111.188
> > xprt 5: tcp, 192.168.111.188
> > xprt 6: tcp, 192.168.111.188
> >
> > And information about each xprt:
> > anna@client ~ % nfs-sysfs xprt
> > xprt 0: local, /var/run/gssproxy.sock, port 0, state <MAIN,CONNECTED,BOUND>
> > Source: (einval), port 0, Requests: 2
> > Congestion: cur 0, win 256, Slots: min 2, max 65536
> > Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> > xprt 1: local, /var/run/rpcbind.sock, port 0, state <MAIN,CONNECTED,BOUND>
> > Source: (einval), port 0, Requests: 2
> > Congestion: cur 0, win 256, Slots: min 2, max 65536
> > Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> > xprt 2: tcp, 192.168.111.1, port 2049, state <MAIN,CONNECTED,BOUND>
> > Source: 192.168.111.222, port 959, Requests: 2
> > Congestion: cur 0, win 256, Slots: min 2, max 65536
> > Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> > xprt 3: tcp, 192.168.111.188, port 2049, state <MAIN,CONNECTED,BOUND>
> > Source: 192.168.111.222, port 921, Requests: 2
> > Congestion: cur 0, win 256, Slots: min 2, max 65536
> > Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> > xprt 4: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
> > Source: 192.168.111.222, port 726, Requests: 2
> > Congestion: cur 0, win 256, Slots: min 2, max 65536
> > Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> > xprt 5: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
> > Source: 192.168.111.222, port 671, Requests: 2
> > Congestion: cur 0, win 256, Slots: min 2, max 65536
> > Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> > xprt 6: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
> > Source: 192.168.111.222, port 934, Requests: 2
> > Congestion: cur 0, win 256, Slots: min 2, max 65536
> > Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> >
> > You can use the `set` subcommand to change the dstaddr of individual xprts:
> > anna@client ~ % sudo nfs-sysfs xprt --id 4
> > xprt 4: tcp, 192.168.111.188, port 2049, state <CONNECTED,BOUND>
> > Source: 192.168.111.222, port 726, Requests: 2
> > Congestion: cur 0, win 256, Slots: min 2, max 65536
> > Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> > anna@client ~ % sudo nfs-sysfs xprt set --id 4 --dstaddr server2.nowheycreamery.com
> > xprt 4: tcp, 192.168.111.186, port 2049, state <CONNECTED,BOUND>
> > Source: 192.168.111.222, port 726, Requests: 2
> > Congestion: cur 0, win 256, Slots: min 2, max 65536
> > Queues: binding 0, sending 0, pending 0, backlog 0, tasks 0
> >
> > Or for changing the dstaddr of all xprts attached to a switch:
> > anna@client % ./nfs-sysfs.py xprt-switch --id 3
> > switch 3: num_xprts 4, num_active 4, queue_len 0
> > xprt 3: tcp, 192.168.111.188 [main]
> > xprt 4: tcp, 192.168.111.188
> > xprt 5: tcp, 192.168.111.188
> > xprt 6: tcp, 192.168.111.188
> > anna@client % sudo ./nfs-sysfs.py xprt-switch set --id 4 --dstaddr server2.nowheycreamery.vm
> > switch 3: num_xprts 4, num_active 4, queue_len 0
> > xprt 2: tcp, 192.168.111.186 [main]
> > xprt 3: tcp, 192.168.111.186
> > xprt 5: tcp, 192.168.111.186
> > xprt 6: tcp, 192.168.111.186
> >
> >
> > What does everybody think? Is there any thing I should change about the
> > user input or output lines? How about other subcommands that should be
> > added with the initial submission?
> I have not play around with this new tool.. but I will! Looking
> forward to it... But... and I should have mention this in v1
> my apologies.
>
> The rest of the NFS tools do not have have "nfs-" as the
> prefix only an "nfs"... As with nfs-iostat, I'll me more that
> will to take the patch with the '-' char, but I would
> prefer the man page and the installed script be call nfssysfs,
> just to say with the current naming conventions.

No problem! Changing the name of the tool should be easy enough. I'm
not committed to the name either, so if anybody has a better name in
mind please let me know!


Anna
>
> steved.
>
> >
> > Thanks,
> > Anna
> >
> >
> > Anna Schumaker (9):
> > nfs-sysfs: Add an nfs-sysfs.py tool
> > nfs-sysfs.py: Add a command for printing xprt switch information
> > nfs-sysfs.py: Add a command for printing individual xprts
> > nfs-sysfs.py: Add a command for printing rpc-client information
> > nfs-sysfs.py: Add a command for changing xprt dstaddr
> > nfs-sysfs.py: Add a command for changing xprt-switch dstaddrs
> > nfs-sysfs.py: Add a command for changing xprt state
> > nfs-sysfs: Add a man page
> > nfs-sysfs: Add installation to the Makefile
> >
> > .gitignore | 2 +
> > configure.ac | 1 +
> > tools/Makefile.am | 2 +-
> > tools/nfs-sysfs/Makefile.am | 20 +++++++
> > tools/nfs-sysfs/client.py | 27 +++++++++
> > tools/nfs-sysfs/nfs-sysfs | 5 ++
> > tools/nfs-sysfs/nfs-sysfs.man | 88 +++++++++++++++++++++++++++++
> > tools/nfs-sysfs/nfs-sysfs.py | 23 ++++++++
> > tools/nfs-sysfs/switch.py | 51 +++++++++++++++++
> > tools/nfs-sysfs/sysfs.py | 28 ++++++++++
> > tools/nfs-sysfs/xprt.py | 101 ++++++++++++++++++++++++++++++++++
> > 11 files changed, 347 insertions(+), 1 deletion(-)
> > create mode 100644 tools/nfs-sysfs/Makefile.am
> > create mode 100644 tools/nfs-sysfs/client.py
> > create mode 100644 tools/nfs-sysfs/nfs-sysfs
> > create mode 100644 tools/nfs-sysfs/nfs-sysfs.man
> > create mode 100755 tools/nfs-sysfs/nfs-sysfs.py
> > create mode 100644 tools/nfs-sysfs/switch.py
> > create mode 100644 tools/nfs-sysfs/sysfs.py
> > create mode 100644 tools/nfs-sysfs/xprt.py
> >
>

2021-08-17 16:58:33

by Mora, Jorge

[permalink] [raw]
Subject: Re: [PATCH v2 1/9] nfs-sysfs: Add an nfs-sysfs.py tool

Hello Anna,

Comments are inline.

--Jorge

On 8/6/21, 2:17 PM, "Anna Schumaker on behalf of [email protected]" <[email protected] on behalf of [email protected]> wrote:

NetApp Security WARNING: This is an external email. Do not click links or open attachments unless you recognize the sender and know the content is safe.




From: Anna Schumaker <[email protected]>

This will be used to print and manipulate the sunrpc sysfs directory
files. Running without arguments prints both usage information and the
location of the sunrpc sysfs directory.

Signed-off-by: Anna Schumaker <[email protected]>
---
.gitignore | 2 ++
tools/nfs-sysfs/nfs-sysfs.py | 13 +++++++++++++
tools/nfs-sysfs/sysfs.py | 18 ++++++++++++++++++
3 files changed, 33 insertions(+)
create mode 100755 tools/nfs-sysfs/nfs-sysfs.py
create mode 100644 tools/nfs-sysfs/sysfs.py

diff --git a/.gitignore b/.gitignore
index c89d1cd2583d..a476bd20bc3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -84,3 +84,5 @@ systemd/rpc-gssd.service
cscope.*
# generic editor backup et al
*~
+# python bytecode
+__pycache__
diff --git a/tools/nfs-sysfs/nfs-sysfs.py b/tools/nfs-sysfs/nfs-sysfs.py
new file mode 100755
index 000000000000..8ff59ea9e81b
--- /dev/null
+++ b/tools/nfs-sysfs/nfs-sysfs.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+import argparse
+import sysfs
+
+parser = argparse.ArgumentParser()
+
+def show_small_help(args):
+ parser.print_usage()
+ print("sunrpc dir:", sysfs.SUNRPC)
+parser.set_defaults(func=show_small_help)
+
+args = parser.parse_args()
+args.func(args)
diff --git a/tools/nfs-sysfs/sysfs.py b/tools/nfs-sysfs/sysfs.py
new file mode 100644
index 000000000000..0b358f57bb28
--- /dev/null
+++ b/tools/nfs-sysfs/sysfs.py
@@ -0,0 +1,18 @@
+import pathlib
+import sys
+
+MOUNT = None
+with open("/proc/mounts", 'r') as f:
+ for line in f:
JM: The following could select the wrong mount line.
+ if "sysfs" in line:
JM: Match "sysfs" at the beginning of the line instead:
if re.search(r"^sysfs\s", line):
+ MOUNT = line.split()[1]
+ break
+
JM: The preferred way is to use "MOUNT is None", but this is just a guideline and it should work either way.
+if MOUNT == None:
+ print("ERROR: sysfs is not mounted")
+ sys.exit(1)
+
+SUNRPC = pathlib.Path(MOUNT) / "kernel" / "sunrpc"
+if not SUNRPC.is_dir():
+ print("ERROR: sysfs does not have sunrpc directory")
+ sys.exit(1)
--
2.32.0


2021-08-17 17:01:58

by Mora, Jorge

[permalink] [raw]
Subject: Re: [PATCH v2 7/9] nfs-sysfs.py: Add a command for changing xprt state

Hello Anna,

Comments are inline:

--Jorge

On 8/6/21, 2:17 PM, "Anna Schumaker on behalf of [email protected]" <[email protected] on behalf of [email protected]> wrote:

NetApp Security WARNING: This is an external email. Do not click links or open attachments unless you recognize the sender and know the content is safe.




From: Anna Schumaker <[email protected]>

We can set it offline or online, or we can remove an xprt. The kernel
only supports removing offlined transports, so we make sure to set the
state to "offline" before sending the remove command.

Signed-off-by: Anna Schumaker <[email protected]>
---
tools/nfs-sysfs/xprt.py | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/tools/nfs-sysfs/xprt.py b/tools/nfs-sysfs/xprt.py
index 2160cb0a9575..92b83ebc4cd1 100644
--- a/tools/nfs-sysfs/xprt.py
+++ b/tools/nfs-sysfs/xprt.py
@@ -8,15 +8,18 @@ class Xprt:
self.type = str(path).rsplit("-", 2)[2]
self.dstaddr = open(path / "dstaddr", 'r').readline().strip()
self.srcaddr = open(path / "srcaddr", 'r').readline().strip()
+ self.exists = True

- with open(path / "xprt_state") as f:
- self.state = ','.join(f.readline().split()[1:])
+ self.read_state()
self.__dict__.update(sysfs.read_info_file(path / "xprt_info"))

def __lt__(self, rhs):
return self.id < rhs.id

def __str__(self):
JM: Do not compare with True or False just use boolean as is:
if not self.exists:
+ if self.exists == False:
+ return "xprt %s: has been removed" % self.id
+
state = self.state
if self.main_xprt:
state = "MAIN," + self.state
@@ -31,6 +34,13 @@ class Xprt:
(self.binding_q_len, self.sending_q_len, self.pending_q_len, self.backlog_q_len, self.tasks_queuelen)
return line

+ def read_state(self):
+ if not self.path.exists():
+ self.exists = False
+ return
+ with open(self.path / "xprt_state") as f:
+ self.state = ','.join(f.readline().split()[1:])
+
def small_str(self):
return "xprt %s: %s, %s%s" % (self.id, self.type, self.dstaddr,
f" [main]" if self.main_xprt else "" )
@@ -41,6 +51,11 @@ class Xprt:
f.write(resolved)
self.dstaddr = open(self.path / "dstaddr", 'r').readline().strip()

+ def set_state(self, state):
+ with open(self.path / "xprt_state", 'w') as f:
+ f.write(state)
+ self.read_state()
+

def list_xprts(args):
xprts = [ Xprt(f) for f in (sysfs.SUNRPC / "xprt-switches").glob("**/xprt-*") ]
@@ -60,6 +75,13 @@ def set_xprt_property(args):
try:
if args.dstaddr != None:
xprt.set_dstaddr(args.dstaddr[0])
JM: Do not compare with True:
if args.offline:
elif args.online:
elif args.remove:
+ if args.offline == True:
+ xprt.set_state("offline")
+ elif args.online == True:
+ xprt.set_state("online")
+ elif args.remove == True:
+ xprt.set_state("offline")
+ xprt.set_state("remove")
print(xprt)
except Exception as e:
print(e)
@@ -73,4 +95,7 @@ def add_command(subparser):
parser = subparser.add_parser("set", help="Set an xprt property")
parser.add_argument("--id", metavar="ID", nargs=1, type=int, required=True, help="Id of a specific xprt to modify")
parser.add_argument("--dstaddr", metavar="dstaddr", nargs=1, type=str, help="New dstaddr to set")
+ parser.add_argument("--offline", action="store_true", help="Set an xprt offline")
+ parser.add_argument("--online", action="store_true", help="Set an offline xprt back online")
+ parser.add_argument("--remove", action="store_true", help="Remove an xprt")
parser.set_defaults(func=set_xprt_property)
--
2.32.0


2021-08-23 21:42:53

by Anna Schumaker

[permalink] [raw]
Subject: Re: [PATCH v2 1/9] nfs-sysfs: Add an nfs-sysfs.py tool

Hi Jorge,

On Tue, Aug 17, 2021 at 12:57 PM Mora, Jorge <[email protected]> wrote:
>
> Hello Anna,
>
> Comments are inline.
>
> --Jorge
>
> On 8/6/21, 2:17 PM, "Anna Schumaker on behalf of [email protected]" <[email protected] on behalf of [email protected]> wrote:
>
> NetApp Security WARNING: This is an external email. Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
>
>
>
> From: Anna Schumaker <[email protected]>
>
> This will be used to print and manipulate the sunrpc sysfs directory
> files. Running without arguments prints both usage information and the
> location of the sunrpc sysfs directory.
>
> Signed-off-by: Anna Schumaker <[email protected]>
> ---
> .gitignore | 2 ++
> tools/nfs-sysfs/nfs-sysfs.py | 13 +++++++++++++
> tools/nfs-sysfs/sysfs.py | 18 ++++++++++++++++++
> 3 files changed, 33 insertions(+)
> create mode 100755 tools/nfs-sysfs/nfs-sysfs.py
> create mode 100644 tools/nfs-sysfs/sysfs.py
>
> diff --git a/.gitignore b/.gitignore
> index c89d1cd2583d..a476bd20bc3b 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -84,3 +84,5 @@ systemd/rpc-gssd.service
> cscope.*
> # generic editor backup et al
> *~
> +# python bytecode
> +__pycache__
> diff --git a/tools/nfs-sysfs/nfs-sysfs.py b/tools/nfs-sysfs/nfs-sysfs.py
> new file mode 100755
> index 000000000000..8ff59ea9e81b
> --- /dev/null
> +++ b/tools/nfs-sysfs/nfs-sysfs.py
> @@ -0,0 +1,13 @@
> +#!/usr/bin/python
> +import argparse
> +import sysfs
> +
> +parser = argparse.ArgumentParser()
> +
> +def show_small_help(args):
> + parser.print_usage()
> + print("sunrpc dir:", sysfs.SUNRPC)
> +parser.set_defaults(func=show_small_help)
> +
> +args = parser.parse_args()
> +args.func(args)
> diff --git a/tools/nfs-sysfs/sysfs.py b/tools/nfs-sysfs/sysfs.py
> new file mode 100644
> index 000000000000..0b358f57bb28
> --- /dev/null
> +++ b/tools/nfs-sysfs/sysfs.py
> @@ -0,0 +1,18 @@
> +import pathlib
> +import sys
> +
> +MOUNT = None
> +with open("/proc/mounts", 'r') as f:
> + for line in f:
> JM: The following could select the wrong mount line.
> + if "sysfs" in line:
> JM: Match "sysfs" at the beginning of the line instead:
> if re.search(r"^sysfs\s", line):

On my system, the beginning of the line is "sys" and not "sysfs". Is
it called "sysfs" on yours? That might be something I need to account
for if it's different.

Anna

> + MOUNT = line.split()[1]
> + break
> +
> JM: The preferred way is to use "MOUNT is None", but this is just a guideline and it should work either way.
> +if MOUNT == None:
> + print("ERROR: sysfs is not mounted")
> + sys.exit(1)
> +
> +SUNRPC = pathlib.Path(MOUNT) / "kernel" / "sunrpc"
> +if not SUNRPC.is_dir():
> + print("ERROR: sysfs does not have sunrpc directory")
> + sys.exit(1)
> --
> 2.32.0
>
>