From: Weston Andros Adamson <dros@primarydata.com>
To: bfields@fieldses.org
Cc: linux-nfs@vger.kernel.org, Weston Andros Adamson <dros@primarydata.com>
Subject: [PATCH pynfs 08/17] 4.1 server: add -s option to print summary of ops
Date: Wed, 4 Jun 2014 17:01:56 -0400 [thread overview]
Message-ID: <1401915726-29092-9-git-send-email-dros@primarydata.com> (raw)
In-Reply-To: <1401915726-29092-1-git-send-email-dros@primarydata.com>
As a middle ground between verbose (-v) mode and silent mode, add
"-s" (aka "--show_summary") to print one line per operation.
The summary mode will print a "role" header whenever the role changes.
Example output - mds starts, talks to v3 ds (.200), client (.11) mounts,
touches an existing file:
call v3 172.16.200.200:2049
access
Mounting (2, 6) on '/files'
handle v4.1 ::ffff:172.16.200.11:758
exchange_id
create_session
sequence, reclaim_complete
sequence, putrootfh, secinfo_no_name
sequence, putrootfh, getfh, getattr
sequence, putfh, getattr
(repeated 6 times)
sequence, putfh, access, getattr
sequence, putfh, lookup, getfh, getattr
(repeated 1 times)
sequence, putfh, secinfo -> NFS4ERR_NOTSUPP
sequence, putfh, getattr
(repeated 4 times)
sequence, putfh, access, getattr
call v3 172.16.200.200:2049
create -> NFS3ERR_EXIST
lookup
getattr
(repeated 1 times)
handle v4.1 ::ffff:172.16.200.11:758
sequence, putfh, open, getfh, access, getattr
call v3 172.16.200.200:2049
getattr
(repeated 1 times)
handle v4.1 ::ffff:172.16.200.11:758
sequence, putfh, setattr, getattr
sequence, putfh, close, getattr
Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
nfs4.1/dataserver.py | 16 ++++++++++------
nfs4.1/nfs4client.py | 7 ++++++-
nfs4.1/nfs4server.py | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
nfs4.1/server_exports.py | 7 ++++---
4 files changed, 66 insertions(+), 11 deletions(-)
diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index d697631..9b0462d 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -13,8 +13,8 @@ import socket
log = logging.getLogger("Dataserver Manager")
-class DataServer(object):
- def __init__(self, server, port, path, flavor=rpc.AUTH_SYS, active=True, mdsds=True, multipath_servers=None):
+class DataServer41(object):
+ def __init__(self, server, port, path, flavor=rpc.AUTH_SYS, active=True, mdsds=True, multipath_servers=None, summary=None):
self.mdsds = mdsds
self.server = server
self.port = int(port)
@@ -32,6 +32,8 @@ class DataServer(object):
else:
self.multipath_servers = []
+ self.summary = summary
+
if active:
self.up()
@@ -47,7 +49,8 @@ class DataServer(object):
# only support root with AUTH_SYS for now
s1 = rpc.security.instance(rpc.AUTH_SYS)
self.cred1 = s1.init_cred(uid=0, gid=0)
- self.c1 = nfs4client.NFS4Client(self.server, self.port)
+ self.c1 = nfs4client.NFS4Client(self.server, self.port,
+ summary=self.summary)
self.c1.set_cred(self.cred1)
self.c1.null()
c = self.c1.new_client("DS.init_%s" % self.server)
@@ -172,7 +175,7 @@ class DSDevice(object):
self.address_body = None # set by load()
self.mdsds = mdsds # if you are both the DS and the MDS we are the only server
- def load(self, filename):
+ def load(self, filename, server_obj):
""" Read dataservers from configuration file:
where each line has format e.g. server[:[port][/path]]
"""
@@ -194,8 +197,9 @@ class DSDevice(object):
try:
log.info("Adding dataserver ip:%s port:%s path:%s" %
(server, port, '/'.join(path)))
- ds = DataServer(server, port, path, mdsds=self.mdsds,
- multipath_servers=server_list)
+ ds = DataServer41(server, port, path, mdsds=self.mdsds,
+ multipath_servers=server_list,
+ summary=server_obj.summary)
self.list.append(ds)
except socket.error:
log.critical("cannot access %s:%i/%s" %
diff --git a/nfs4.1/nfs4client.py b/nfs4.1/nfs4client.py
index e504362..f5d2006 100644
--- a/nfs4.1/nfs4client.py
+++ b/nfs4.1/nfs4client.py
@@ -21,7 +21,7 @@ logging.basicConfig(level=logging.INFO,
log_cb = logging.getLogger("nfs.client.cb")
class NFS4Client(rpc.Client, rpc.Server):
- def __init__(self, host='localhost', port=2049, minorversion=1, ctrl_proc=16):
+ def __init__(self, host='localhost', port=2049, minorversion=1, ctrl_proc=16, summary=None):
rpc.Client.__init__(self, 100003, 4)
self.prog = 0x40000000
self.versions = [1] # List of supported versions of prog
@@ -36,6 +36,7 @@ class NFS4Client(rpc.Client, rpc.Server):
self.c1 = self.connect(self.server_address)
self.sessions = {} # XXX Really, this should be per server
self.ctrl_proc = ctrl_proc
+ self.summary = summary
def set_cred(self, credinfo):
self.default_cred = credinfo
@@ -83,6 +84,10 @@ class NFS4Client(rpc.Client, rpc.Server):
pipe = kwargs.get("pipe", None)
res = self.listen(xid, pipe=pipe)
log_cb.info("compound result = %r" % (res,))
+ if self.summary:
+ self.summary.show_op('call v4.1 %s:%s' % self.server_address,
+ [ nfs_opnum4[a.argop].lower()[3:] for a in args[0] ],
+ nfsstat4[res.status])
return res
def listen(self, xid, pipe=None, timeout=10.0):
diff --git a/nfs4.1/nfs4server.py b/nfs4.1/nfs4server.py
index 67adbf1..088e8c4 100755
--- a/nfs4.1/nfs4server.py
+++ b/nfs4.1/nfs4server.py
@@ -502,6 +502,41 @@ class Slot(object):
# STUB - for client, need to track slot usage
+class SummaryOutput:
+ def __init__(self, enabled=True):
+ self._enabled = enabled
+ self._last = None
+ self._last_role = None
+ self._repeat_count = 0
+
+ def show_op(self, role, opnames, status):
+ if not self._enabled:
+ return
+
+ summary_line = " %s" % ', '.join(opnames)
+
+ if status != "NFS4_OK" and status != "NFS3_OK":
+ summary_line += " -> %s" % (status,)
+
+ print_summary_line = True
+ if summary_line != self._last or role != self._last_role:
+ if self._last and self._repeat_count:
+ print " (repeated %u times)" % self._repeat_count
+ self._last = summary_line
+ self._repeat_count = 0
+ else:
+ print_summary_line = False
+ self._repeat_count += 1
+
+ if self._last_role != role:
+ print
+ print role
+ self._last_role = role
+
+ if print_summary_line:
+ print summary_line
+
+
##################################################
# The primary class - it is excessively long #
##################################################
@@ -527,6 +562,8 @@ class NFS4Server(rpc.Server):
log_41.setLevel(9)
log_cfg.setLevel(20)
+ self.summary = SummaryOutput(kwargs.pop('show_summary', False))
+
rpc.Server.__init__(self, prog=NFS4_PROGRAM, versions=[4], port=port,
**kwargs)
self.root = RootFS().root # Root of exported filesystem tree
@@ -776,6 +813,7 @@ class NFS4Server(rpc.Server):
return env
# Handle the individual operations
status = NFS4_OK
+ opnames = []
for arg in args.argarray:
opname = nfs_opnum4.get(arg.argop, 'op_illegal')
log_41.info("*** %s (%d) ***" % (opname, arg.argop))
@@ -805,10 +843,14 @@ class NFS4Server(rpc.Server):
result = encode_status_by_name(opname.lower()[3:],
NFS4ERR_SERVERFAULT)
env.results.append(result)
+ opnames.append(opname.lower()[3:])
status = result.status
if status != NFS4_OK:
break
log_41.info("Replying. Status %s (%d)" % (nfsstat4[status], status))
+ client_addr = '%s:%s' % cred.connection._s.getpeername()[:2]
+ self.summary.show_op('handle v4.1 %s' % client_addr,
+ opnames, nfsstat4[status])
return env
def delete_session(self, session, sessionid):
@@ -2062,6 +2104,8 @@ def scan_options():
help="Reset and clear any disk-based filesystems")
p.add_option("-v", "--verbose", action="store_true", default=False,
help="Print debug info to screen and enter interpreter on ^C")
+ p.add_option("-s", "--show_summary", action="store_true", default=False,
+ help="Print short summary of operations")
p.add_option("--use_block", action="store_true", default=False,
help="Mount a block-pnfs fs")
p.add_option("--use_files", action="store_true", default=False,
@@ -2095,7 +2139,8 @@ if __name__ == "__main__":
S = NFS4Server(port=opts.port,
is_mds=opts.use_block or opts.use_files,
is_ds = opts.is_ds,
- verbose = opts.verbose)
+ verbose = opts.verbose,
+ show_summary = opts.show_summary)
read_exports(S, opts)
if True:
S.start()
diff --git a/nfs4.1/server_exports.py b/nfs4.1/server_exports.py
index d96b27b..ef857ee 100644
--- a/nfs4.1/server_exports.py
+++ b/nfs4.1/server_exports.py
@@ -15,7 +15,7 @@ def mount_stuff(server, opts):
E = BlockLayoutFS(5, backing_device=dev)
server.mount(E, path="/block")
if opts.use_files:
- dservers = _load_dataservers(opts.dataservers, server.is_ds and server.is_mds)
+ dservers = _load_dataservers(opts.dataservers, server)
if dservers is None:
return
F = FileLayoutFS(6, dservers)
@@ -33,7 +33,8 @@ def _create_simple_block_dev():
c1 = Concat([s3, s1])
return BlockVolume(c1)
-def _load_dataservers(file, connect_to_ds=False):
+def _load_dataservers(filename, server):
+ connect_to_ds = server.is_ds and server.is_mds
dss = DSDevice(connect_to_ds)
- dss.load(file)
+ dss.load(filename, server)
return dss;
--
1.8.5.2 (Apple Git-48)
next prev parent reply other threads:[~2014-06-04 21:02 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-04 21:01 [PATCH pynfs 00/17] prep for flex file layout server Weston Andros Adamson
2014-06-04 21:01 ` [PATCH pynfs 01/17] 4.1 client: reclaim_complete after create_session Weston Andros Adamson
2014-06-05 2:26 ` J. Bruce Fields
2014-06-05 12:54 ` Weston Andros Adamson
2014-06-04 21:01 ` [PATCH pynfs 02/17] 4.1 server: service RECLAIM_COMPLETE operations Weston Andros Adamson
2014-06-05 2:29 ` J. Bruce Fields
2014-06-05 12:22 ` Trond Myklebust
2014-06-05 12:58 ` Weston Andros Adamson
2014-06-05 13:06 ` J. Bruce Fields
2014-06-05 13:18 ` Weston Andros Adamson
2014-06-05 13:34 ` Weston Andros Adamson
2014-06-05 13:41 ` J. Bruce Fields
2014-06-05 13:49 ` Weston Andros Adamson
2014-06-04 21:01 ` [PATCH pynfs 03/17] dataserver: only catch connection error Weston Andros Adamson
2014-06-04 21:01 ` [PATCH pynfs 04/17] 4.1 server: avoid traceback in DS disconnect() Weston Andros Adamson
2014-06-04 21:01 ` [PATCH pynfs 06/17] 4.1 client: remove unused imports Weston Andros Adamson
2014-06-04 21:01 ` [PATCH pynfs 07/17] 4.1 server: add -v flag & silence random output Weston Andros Adamson
2014-06-04 21:01 ` Weston Andros Adamson [this message]
2014-06-04 21:01 ` [PATCH pynfs 09/17] dataserver: make generic interface to ops Weston Andros Adamson
2014-06-04 21:01 ` [PATCH pynfs 10/17] dataserver: don't import * from nfs4 specific mods Weston Andros Adamson
2014-06-04 21:01 ` [PATCH pynfs 11/17] 4.1 server: move nfs4_ops.py to nfs_ops.py Weston Andros Adamson
2014-06-04 21:02 ` [PATCH pynfs 12/17] add mntv3, portmapv2 and nfsv3 .x files Weston Andros Adamson
2014-06-05 2:34 ` J. Bruce Fields
2014-06-04 21:02 ` [PATCH pynfs 13/17] dataserver: separate generic and 4.1 code Weston Andros Adamson
2014-06-04 21:02 ` [PATCH pynfs 14/17] 4.1 server: add support for NFSv3 data servers Weston Andros Adamson
2014-06-04 21:02 ` [PATCH pynfs 15/17] 4.1 server: get rid of old op_getdeviceinfo Weston Andros Adamson
2014-06-04 21:02 ` [PATCH pynfs 15/17] nfs41 svr: " Weston Andros Adamson
2014-06-04 21:02 ` [PATCH pynfs 16/17] rpc: on socket error, close and mark pipe inactive Weston Andros Adamson
2014-06-04 21:02 ` [PATCH pynfs 17/17] nfs3clnt: reconnect when sending on inactive pipe Weston Andros Adamson
[not found] ` <1401915726-29092-6-git-send-email-dros@primarydata.com>
2014-06-05 2:31 ` [PATCH pynfs 05/17] move .x files to subdir 'xdrdef' J. Bruce Fields
2014-06-05 12:51 ` Weston Andros Adamson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1401915726-29092-9-git-send-email-dros@primarydata.com \
--to=dros@primarydata.com \
--cc=bfields@fieldses.org \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).