|
|
d4362b |
diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
|
|
|
d4362b |
index 48ef0964..bda9af67 100755
|
|
|
d4362b |
--- a/tools/mountstats/mountstats.py
|
|
|
d4362b |
+++ b/tools/mountstats/mountstats.py
|
|
|
d4362b |
@@ -308,6 +308,8 @@ class DeviceData:
|
|
|
d4362b |
op = words[0][:-1]
|
|
|
d4362b |
self.__rpc_data['ops'] += [op]
|
|
|
d4362b |
self.__rpc_data[op] = [int(word) for word in words[1:]]
|
|
|
d4362b |
+ if len(self.__rpc_data[op]) < 9:
|
|
|
d4362b |
+ self.__rpc_data[op] += [0]
|
|
|
d4362b |
|
|
|
d4362b |
def parse_stats(self, lines):
|
|
|
d4362b |
"""Turn a list of lines from a mount stat file into a
|
|
|
d4362b |
@@ -475,7 +477,9 @@ class DeviceData:
|
|
|
d4362b |
retrans = stats[2] - count
|
|
|
d4362b |
if retrans != 0:
|
|
|
d4362b |
print('\t%d retrans (%d%%)' % (retrans, ((retrans * 100) / count)), end=' ')
|
|
|
d4362b |
- print('\t%d major timeouts' % stats[3])
|
|
|
d4362b |
+ print('\t%d major timeouts' % stats[3], end='')
|
|
|
d4362b |
+ if len(stats) >= 10 and stats[9] != 0:
|
|
|
d4362b |
+ print('\t%d errors (%d%%)' % (stats[9], ((stats[9] * 100) / count)))
|
|
|
d4362b |
else:
|
|
|
d4362b |
print('')
|
|
|
d4362b |
print('\tavg bytes sent per op: %d\tavg bytes received per op: %d' % \
|
|
|
d4362b |
@@ -580,7 +584,7 @@ class DeviceData:
|
|
|
d4362b |
self.__nfs_data['fstype'] = 'nfs4'
|
|
|
d4362b |
self.__rpc_data['ops'] = ops
|
|
|
d4362b |
for op in ops:
|
|
|
d4362b |
- self.__rpc_data[op] = [0 for i in range(8)]
|
|
|
d4362b |
+ self.__rpc_data[op] = [0 for i in range(9)]
|
|
|
d4362b |
|
|
|
d4362b |
def accumulate_iostats(self, new_stats):
|
|
|
d4362b |
"""Accumulate counters from all RPC op buckets in new_stats. This is
|
|
|
d4362b |
@@ -605,6 +609,8 @@ class DeviceData:
|
|
|
d4362b |
queued_for = float(rpc_stats[5])
|
|
|
d4362b |
rtt = float(rpc_stats[6])
|
|
|
d4362b |
exe = float(rpc_stats[7])
|
|
|
d4362b |
+ if len(rpc_stats) >= 9:
|
|
|
d4362b |
+ errs = int(rpc_stats[8])
|
|
|
d4362b |
|
|
|
d4362b |
# prevent floating point exceptions
|
|
|
d4362b |
if ops != 0:
|
|
|
d4362b |
@@ -613,12 +619,15 @@ class DeviceData:
|
|
|
d4362b |
rtt_per_op = rtt / ops
|
|
|
d4362b |
exe_per_op = exe / ops
|
|
|
d4362b |
queued_for_per_op = queued_for / ops
|
|
|
d4362b |
+ if len(rpc_stats) >= 9:
|
|
|
d4362b |
+ errs_percent = (errs * 100) / ops
|
|
|
d4362b |
else:
|
|
|
d4362b |
kb_per_op = 0.0
|
|
|
d4362b |
retrans_percent = 0.0
|
|
|
d4362b |
rtt_per_op = 0.0
|
|
|
d4362b |
exe_per_op = 0.0
|
|
|
d4362b |
queued_for_per_op = 0.0
|
|
|
d4362b |
+ errs_percent = 0.0
|
|
|
d4362b |
|
|
|
d4362b |
op += ':'
|
|
|
d4362b |
print(format(op.lower(), '<16s'), end='')
|
|
|
d4362b |
@@ -628,7 +637,10 @@ class DeviceData:
|
|
|
d4362b |
print(format('retrans', '>16s'), end='')
|
|
|
d4362b |
print(format('avg RTT (ms)', '>16s'), end='')
|
|
|
d4362b |
print(format('avg exe (ms)', '>16s'), end='')
|
|
|
d4362b |
- print(format('avg queue (ms)', '>16s'))
|
|
|
d4362b |
+ print(format('avg queue (ms)', '>16s'), end='')
|
|
|
d4362b |
+ if len(rpc_stats) >= 9:
|
|
|
d4362b |
+ print(format('errors', '>16s'), end='')
|
|
|
d4362b |
+ print()
|
|
|
d4362b |
|
|
|
d4362b |
print(format((ops / sample_time), '>24.3f'), end='')
|
|
|
d4362b |
print(format((kilobytes / sample_time), '>16.3f'), end='')
|
|
|
d4362b |
@@ -637,7 +649,11 @@ class DeviceData:
|
|
|
d4362b |
print(format(retransmits, '>16'), end='')
|
|
|
d4362b |
print(format(rtt_per_op, '>16.3f'), end='')
|
|
|
d4362b |
print(format(exe_per_op, '>16.3f'), end='')
|
|
|
d4362b |
- print(format(queued_for_per_op, '>16.3f'))
|
|
|
d4362b |
+ print(format(queued_for_per_op, '>16.3f'), end='')
|
|
|
d4362b |
+ if len(rpc_stats) >= 9:
|
|
|
d4362b |
+ errors = '{0:>10.0f} ({1:>3.1f}%)'.format(errs, errs_percent).strip()
|
|
|
d4362b |
+ print(format(errors, '>16'), end='')
|
|
|
d4362b |
+ print()
|
|
|
d4362b |
|
|
|
d4362b |
def display_iostats(self, sample_time):
|
|
|
d4362b |
"""Display NFS and RPC stats in an iostat-like way
|
|
|
d4362b |
diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py
|
|
|
d4362b |
old mode 100644
|
|
|
d4362b |
new mode 100755
|
|
|
d4362b |
index f1556fb7..5b2260ad
|
|
|
d4362b |
--- a/tools/nfs-iostat/nfs-iostat.py
|
|
|
d4362b |
+++ b/tools/nfs-iostat/nfs-iostat.py
|
|
|
d4362b |
@@ -329,6 +329,8 @@ class DeviceData:
|
|
|
d4362b |
queued_for = float(rpc_stats[5])
|
|
|
d4362b |
rtt = float(rpc_stats[6])
|
|
|
d4362b |
exe = float(rpc_stats[7])
|
|
|
d4362b |
+ if len(rpc_stats) >= 9:
|
|
|
d4362b |
+ errs = float(rpc_stats[8])
|
|
|
d4362b |
|
|
|
d4362b |
# prevent floating point exceptions
|
|
|
d4362b |
if ops != 0:
|
|
|
d4362b |
@@ -337,12 +339,16 @@ class DeviceData:
|
|
|
d4362b |
rtt_per_op = rtt / ops
|
|
|
d4362b |
exe_per_op = exe / ops
|
|
|
d4362b |
queued_for_per_op = queued_for / ops
|
|
|
d4362b |
+ if len(rpc_stats) >= 9:
|
|
|
d4362b |
+ errs_percent = (errs * 100) / ops
|
|
|
d4362b |
else:
|
|
|
d4362b |
kb_per_op = 0.0
|
|
|
d4362b |
retrans_percent = 0.0
|
|
|
d4362b |
rtt_per_op = 0.0
|
|
|
d4362b |
exe_per_op = 0.0
|
|
|
d4362b |
queued_for_per_op = 0.0
|
|
|
d4362b |
+ if len(rpc_stats) >= 9:
|
|
|
d4362b |
+ errs_percent = 0.0
|
|
|
d4362b |
|
|
|
d4362b |
op += ':'
|
|
|
d4362b |
print(format(op.lower(), '<16s'), end='')
|
|
|
d4362b |
@@ -352,7 +358,10 @@ class DeviceData:
|
|
|
d4362b |
print(format('retrans', '>16s'), end='')
|
|
|
d4362b |
print(format('avg RTT (ms)', '>16s'), end='')
|
|
|
d4362b |
print(format('avg exe (ms)', '>16s'), end='')
|
|
|
d4362b |
- print(format('avg queue (ms)', '>16s'))
|
|
|
d4362b |
+ print(format('avg queue (ms)', '>16s'), end='')
|
|
|
d4362b |
+ if len(rpc_stats) >= 9:
|
|
|
d4362b |
+ print(format('errors', '>16s'), end='')
|
|
|
d4362b |
+ print()
|
|
|
d4362b |
|
|
|
d4362b |
print(format((ops / sample_time), '>24.3f'), end='')
|
|
|
d4362b |
print(format((kilobytes / sample_time), '>16.3f'), end='')
|
|
|
d4362b |
@@ -361,7 +370,11 @@ class DeviceData:
|
|
|
d4362b |
print(format(retransmits, '>16'), end='')
|
|
|
d4362b |
print(format(rtt_per_op, '>16.3f'), end='')
|
|
|
d4362b |
print(format(exe_per_op, '>16.3f'), end='')
|
|
|
d4362b |
- print(format(queued_for_per_op, '>16.3f'))
|
|
|
d4362b |
+ print(format(queued_for_per_op, '>16.3f'), end='')
|
|
|
d4362b |
+ if len(rpc_stats) >= 9:
|
|
|
d4362b |
+ errors = '{0:>10.0f} ({1:>3.1f}%)'.format(errs, errs_percent).strip()
|
|
|
d4362b |
+ print(format(errors, '>16'), end='')
|
|
|
d4362b |
+ print()
|
|
|
d4362b |
|
|
|
d4362b |
def ops(self, sample_time):
|
|
|
d4362b |
sends = float(self.__rpc_data['rpcsends'])
|
|
|
d4362b |
diff --git a/tools/nfs-iostat/nfsiostat.man b/tools/nfs-iostat/nfsiostat.man
|
|
|
d4362b |
index 9ae94c5f..940c0431 100644
|
|
|
d4362b |
--- a/tools/nfs-iostat/nfsiostat.man
|
|
|
d4362b |
+++ b/tools/nfs-iostat/nfsiostat.man
|
|
|
d4362b |
@@ -97,6 +97,14 @@ This is the duration from the time the NFS client created the RPC request task t
|
|
|
d4362b |
.RE
|
|
|
d4362b |
.RE
|
|
|
d4362b |
.RE
|
|
|
d4362b |
+.RS 8
|
|
|
d4362b |
+- \fBerrors\fR
|
|
|
d4362b |
+.RS
|
|
|
d4362b |
+This is the number of operations that completed with an error status (status < 0). This count is only available on kernels with RPC iostats version 1.1 or above.
|
|
|
d4362b |
+.RS
|
|
|
d4362b |
+.RE
|
|
|
d4362b |
+.RE
|
|
|
d4362b |
+.RE
|
|
|
d4362b |
.TP
|
|
|
d4362b |
Note that if an interval is used as argument to \fBnfsiostat\fR, then the diffrence from previous interval will be displayed, otherwise the results will be from the time that the share was mounted.
|
|
|
d4362b |
|