11590Srgrimes/*
21590Srgrimes * Copyright (c) 1983, 1989, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * This code is derived from software contributed to Berkeley by
61590Srgrimes * Rick Macklem at The University of Guelph.
71590Srgrimes *
81590Srgrimes * Redistribution and use in source and binary forms, with or without
91590Srgrimes * modification, are permitted provided that the following conditions
101590Srgrimes * are met:
111590Srgrimes * 1. Redistributions of source code must retain the above copyright
121590Srgrimes *    notice, this list of conditions and the following disclaimer.
131590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
141590Srgrimes *    notice, this list of conditions and the following disclaimer in the
151590Srgrimes *    documentation and/or other materials provided with the distribution.
161590Srgrimes * 4. Neither the name of the University nor the names of its contributors
171590Srgrimes *    may be used to endorse or promote products derived from this software
181590Srgrimes *    without specific prior written permission.
191590Srgrimes *
201590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
211590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
221590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
231590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
241590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
251590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
261590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
271590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
281590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
291590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
301590Srgrimes * SUCH DAMAGE.
311590Srgrimes */
32306632Srmacklem/*-
33306632Srmacklem * Copyright (c) 2004, 2008, 2009 Silicon Graphics International Corp.
34306632Srmacklem * All rights reserved.
35306632Srmacklem *
36306632Srmacklem * Redistribution and use in source and binary forms, with or without
37306632Srmacklem * modification, are permitted provided that the following conditions
38306632Srmacklem * are met:
39306632Srmacklem * 1. Redistributions of source code must retain the above copyright
40306632Srmacklem *    notice, this list of conditions, and the following disclaimer,
41306632Srmacklem *    without modification.
42306632Srmacklem * 2. Redistributions in binary form must reproduce at minimum a disclaimer
43306632Srmacklem *    substantially similar to the "NO WARRANTY" disclaimer below
44306632Srmacklem *    ("Disclaimer") and any redistribution must be conditioned upon
45306632Srmacklem *    including a substantially similar Disclaimer requirement for further
46306632Srmacklem *    binary redistribution.
47306632Srmacklem *
48306632Srmacklem * NO WARRANTY
49306632Srmacklem * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50306632Srmacklem * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51306632Srmacklem * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
52306632Srmacklem * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
53306632Srmacklem * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54306632Srmacklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55306632Srmacklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56306632Srmacklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57306632Srmacklem * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
58306632Srmacklem * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59306632Srmacklem * POSSIBILITY OF SUCH DAMAGES.
60306632Srmacklem */
611590Srgrimes
62306632Srmacklem
631590Srgrimes#ifndef lint
64194792Sdelphijstatic const char copyright[] =
651590Srgrimes"@(#) Copyright (c) 1983, 1989, 1993\n\
661590Srgrimes	The Regents of the University of California.  All rights reserved.\n";
671590Srgrimes#endif /* not lint */
681590Srgrimes
691590Srgrimes#ifndef lint
7032649Sbde#if 0
7132649Sbdestatic char sccsid[] = "@(#)nfsstat.c	8.2 (Berkeley) 3/31/95";
7232649Sbde#endif
733819Swollmanstatic const char rcsid[] =
7450477Speter  "$FreeBSD: stable/11/usr.bin/nfsstat/nfsstat.c 321000 2017-07-14 21:43:57Z rmacklem $";
751590Srgrimes#endif /* not lint */
761590Srgrimes
771590Srgrimes#include <sys/param.h>
78194190Sed#include <sys/module.h>
791590Srgrimes#include <sys/mount.h>
8011936Sphk#include <sys/time.h>
813819Swollman#include <sys/sysctl.h>
829336Sdfr#include <nfs/nfsproto.h>
8383653Speter#include <nfsclient/nfs.h>
8483653Speter#include <nfsserver/nfs.h>
85192762Srmacklem#include <nfs/nfssvc.h>
86192762Srmacklem
87192762Srmacklem#include <fs/nfs/nfsport.h>
88192762Srmacklem
891590Srgrimes#include <signal.h>
901590Srgrimes#include <fcntl.h>
91200462Sdelphij#include <ctype.h>
921590Srgrimes#include <errno.h>
9377207Stmm#include <limits.h>
941590Srgrimes#include <nlist.h>
951590Srgrimes#include <unistd.h>
961590Srgrimes#include <stdio.h>
97306632Srmacklem#include <stdint.h>
981590Srgrimes#include <stdlib.h>
991590Srgrimes#include <string.h>
100200462Sdelphij#include <paths.h>
101306632Srmacklem#include <devstat.h>
1023819Swollman#include <err.h>
1031590Srgrimes
10452493Sdillonstatic int widemode = 0;
105172759Sjhbstatic int zflag = 0;
106192762Srmacklemstatic int printtitle = 1;
107306632Srmacklemstatic struct nfsstatsv1 ext_nfsstats;
108221455Srmacklemstatic int extra_output = 0;
1091590Srgrimes
110281888Straszstatic void intpr(int, int);
111306632Srmacklemstatic void printhdr(int, int, int);
112281888Straszstatic void usage(void);
113281888Straszstatic char *sperc1(int, int);
114281888Straszstatic char *sperc2(int, int);
115281888Straszstatic void exp_intpr(int, int);
116309831Srmacklemstatic void exp41_intpr(int, int);
117306632Srmacklemstatic void exp_sidewaysintpr(u_int, int, int, int);
118306632Srmacklemstatic void compute_new_stats(struct nfsstatsv1 *cur_stats,
119306632Srmacklem    struct nfsstatsv1 *prev_stats, int curop, long double etime,
120306632Srmacklem    long double *mbsec, long double *kb_per_transfer,
121306632Srmacklem    long double *transfers_per_second, long double *ms_per_transfer,
122306632Srmacklem    uint64_t *queue_len, long double *busy_pct);
1233819Swollman
12452493Sdillon#define DELTA(field)	(nfsstats.field - lastst.field)
12552493Sdillon
126306632Srmacklem#define	STAT_TYPE_READ		0
127306632Srmacklem#define	STAT_TYPE_WRITE		1
128306632Srmacklem#define	STAT_TYPE_COMMIT	2
129306632Srmacklem#define	NUM_STAT_TYPES		3
130306632Srmacklem
131306632Srmacklemstruct stattypes {
132306632Srmacklem	int stat_type;
133306632Srmacklem	int nfs_type;
134306632Srmacklem};
135306632Srmacklemstatic struct stattypes statstruct[] = {
136306632Srmacklem	{STAT_TYPE_READ, NFSV4OP_READ},
137306632Srmacklem	{STAT_TYPE_WRITE, NFSV4OP_WRITE},
138306632Srmacklem	{STAT_TYPE_COMMIT, NFSV4OP_COMMIT}
139306632Srmacklem};
140306632Srmacklem
141306632Srmacklem#define	STAT_TYPE_TO_NFS(stat_type)	statstruct[stat_type].nfs_type
142306632Srmacklem
143131990Sstefanfint
144172759Sjhbmain(int argc, char **argv)
1451590Srgrimes{
1461590Srgrimes	u_int interval;
14752493Sdillon	int clientOnly = -1;
14852493Sdillon	int serverOnly = -1;
149306632Srmacklem	int newStats = 0;
1501590Srgrimes	int ch;
1511590Srgrimes	char *memf, *nlistf;
152243783Srmacklem	int mntlen, i;
153243783Srmacklem	char buf[1024];
154243783Srmacklem	struct statfs *mntbuf;
155243783Srmacklem	struct nfscl_dumpmntopts dumpmntopts;
1561590Srgrimes
1571590Srgrimes	interval = 0;
1581590Srgrimes	memf = nlistf = NULL;
159309831Srmacklem	while ((ch = getopt(argc, argv, "cdEesWM:mN:w:z")) != -1)
1601590Srgrimes		switch(ch) {
1611590Srgrimes		case 'M':
1621590Srgrimes			memf = optarg;
1631590Srgrimes			break;
164243783Srmacklem		case 'm':
165243783Srmacklem			/* Display mount options for NFS mount points. */
166243783Srmacklem			mntlen = getmntinfo(&mntbuf, MNT_NOWAIT);
167243783Srmacklem			for (i = 0; i < mntlen; i++) {
168243783Srmacklem				if (strcmp(mntbuf->f_fstypename, "nfs") == 0) {
169243783Srmacklem					dumpmntopts.ndmnt_fname =
170243783Srmacklem					    mntbuf->f_mntonname;
171243783Srmacklem					dumpmntopts.ndmnt_buf = buf;
172243783Srmacklem					dumpmntopts.ndmnt_blen = sizeof(buf);
173243783Srmacklem					if (nfssvc(NFSSVC_DUMPMNTOPTS,
174243783Srmacklem					    &dumpmntopts) >= 0)
175243783Srmacklem						printf("%s on %s\n%s\n",
176243783Srmacklem						    mntbuf->f_mntfromname,
177243783Srmacklem						    mntbuf->f_mntonname, buf);
178251585Srmacklem					else if (errno == EPERM)
179251585Srmacklem						errx(1, "Only priviledged users"
180251585Srmacklem						    " can use the -m option");
181243783Srmacklem				}
182243783Srmacklem				mntbuf++;
183243783Srmacklem			}
184243783Srmacklem			exit(0);
1851590Srgrimes		case 'N':
1861590Srgrimes			nlistf = optarg;
1871590Srgrimes			break;
18852493Sdillon		case 'W':
18952493Sdillon			widemode = 1;
19052493Sdillon			break;
1911590Srgrimes		case 'w':
1921590Srgrimes			interval = atoi(optarg);
1931590Srgrimes			break;
19452493Sdillon		case 'c':
19552493Sdillon			clientOnly = 1;
19652493Sdillon			if (serverOnly < 0)
19752493Sdillon				serverOnly = 0;
19852493Sdillon			break;
199306632Srmacklem		case 'd':
200306632Srmacklem			newStats = 1;
201306632Srmacklem			if (interval == 0)
202306632Srmacklem				interval = 1;
203306632Srmacklem			break;
20452493Sdillon		case 's':
20552493Sdillon			serverOnly = 1;
20652493Sdillon			if (clientOnly < 0)
20752493Sdillon				clientOnly = 0;
20852493Sdillon			break;
209172759Sjhb		case 'z':
210172759Sjhb			zflag = 1;
211172759Sjhb			break;
212309831Srmacklem		case 'E':
213309831Srmacklem			if (extra_output != 0)
214309831Srmacklem				errx(1, "-e and -E are mutually exclusive");
215309831Srmacklem			extra_output = 2;
216309831Srmacklem			break;
217193258Srmacklem		case 'e':
218309831Srmacklem			if (extra_output != 0)
219309831Srmacklem				errx(1, "-e and -E are mutually exclusive");
220221455Srmacklem			extra_output = 1;
221192762Srmacklem			break;
2221590Srgrimes		case '?':
2231590Srgrimes		default:
2241590Srgrimes			usage();
2251590Srgrimes		}
2261590Srgrimes	argc -= optind;
2271590Srgrimes	argv += optind;
2281590Srgrimes
2291590Srgrimes#define	BACKWARD_COMPATIBILITY
2301590Srgrimes#ifdef	BACKWARD_COMPATIBILITY
2311590Srgrimes	if (*argv) {
2321590Srgrimes		interval = atoi(*argv);
2331590Srgrimes		if (*++argv) {
2341590Srgrimes			nlistf = *argv;
2351590Srgrimes			if (*++argv)
2361590Srgrimes				memf = *argv;
2371590Srgrimes		}
2381590Srgrimes	}
2391590Srgrimes#endif
240281888Strasz	if (modfind("nfscommon") < 0)
241281888Strasz		errx(1, "NFS client/server not loaded");
242192762Srmacklem
243192762Srmacklem	if (interval) {
244306632Srmacklem		exp_sidewaysintpr(interval, clientOnly, serverOnly,
245306632Srmacklem		    newStats);
246192762Srmacklem	} else {
247309831Srmacklem		if (extra_output == 2)
248309831Srmacklem			exp41_intpr(clientOnly, serverOnly);
249309831Srmacklem		else if (extra_output == 1)
250192762Srmacklem			exp_intpr(clientOnly, serverOnly);
251192762Srmacklem		else
252192762Srmacklem			intpr(clientOnly, serverOnly);
253192762Srmacklem	}
2541590Srgrimes	exit(0);
2551590Srgrimes}
2561590Srgrimes
2571590Srgrimes/*
258281888Strasz * Print a description of the nfs stats.
2593819Swollman */
260194792Sdelphijstatic void
26152493Sdillonintpr(int clientOnly, int serverOnly)
2621590Srgrimes{
263221455Srmacklem	int nfssvc_flag;
2641590Srgrimes
265306632Srmacklem	nfssvc_flag = NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT;
266281888Strasz	if (zflag != 0) {
267281888Strasz		if (clientOnly != 0)
268281888Strasz			nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
269281888Strasz		if (serverOnly != 0)
270281888Strasz			nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
27183653Speter	}
272306632Srmacklem	ext_nfsstats.vers = NFSSTATS_V1;
273281888Strasz	if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
274281888Strasz		err(1, "Can't get stats");
27552493Sdillon	if (clientOnly) {
27652493Sdillon		printf("Client Info:\n");
27752493Sdillon		printf("Rpc Counts:\n");
27852493Sdillon		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
27952493Sdillon			"Getattr", "Setattr", "Lookup", "Readlink", "Read",
28052493Sdillon			"Write", "Create", "Remove");
281306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
282306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETATTR],
283306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETATTR],
284306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
285306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READLINK],
286306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READ],
287306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_WRITE],
288306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATE],
289306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
29052493Sdillon		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
29152493Sdillon			"Rename", "Link", "Symlink", "Mkdir", "Rmdir",
29252493Sdillon			"Readdir", "RdirPlus", "Access");
293306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
294306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RENAME],
295306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LINK],
296306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
297306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKDIR],
298306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RMDIR],
299306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIR],
300306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
301306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
30283653Speter		printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
30383653Speter			"Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
304306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju\n",
305306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKNOD],
306306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
307306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSINFO],
308306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
309306632Srmacklem			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_COMMIT]);
31052493Sdillon		printf("Rpc Info:\n");
31152493Sdillon		printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
31252493Sdillon			"TimedOut", "Invalid", "X Replies", "Retries",
31352493Sdillon			"Requests");
314306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju\n",
315306632Srmacklem			(uintmax_t)ext_nfsstats.rpctimeouts,
316306632Srmacklem			(uintmax_t)ext_nfsstats.rpcinvalid,
317306632Srmacklem			(uintmax_t)ext_nfsstats.rpcunexpected,
318306632Srmacklem			(uintmax_t)ext_nfsstats.rpcretries,
319306632Srmacklem			(uintmax_t)ext_nfsstats.rpcrequests);
32052493Sdillon		printf("Cache Info:\n");
32152493Sdillon		printf("%9.9s %9.9s %9.9s %9.9s",
32252493Sdillon			"Attr Hits", "Misses", "Lkup Hits", "Misses");
32352493Sdillon		printf(" %9.9s %9.9s %9.9s %9.9s\n",
32452493Sdillon			"BioR Hits", "Misses", "BioW Hits", "Misses");
325306632Srmacklem		printf("%9ju %9ju %9ju %9ju",
326306632Srmacklem			(uintmax_t)ext_nfsstats.attrcache_hits,
327306632Srmacklem			(uintmax_t)ext_nfsstats.attrcache_misses,
328306632Srmacklem			(uintmax_t)ext_nfsstats.lookupcache_hits,
329306632Srmacklem			(uintmax_t)ext_nfsstats.lookupcache_misses);
330306632Srmacklem		printf(" %9ju %9ju %9ju %9ju\n",
331306632Srmacklem			(uintmax_t)(ext_nfsstats.biocache_reads -
332306632Srmacklem			ext_nfsstats.read_bios),
333306632Srmacklem			(uintmax_t)ext_nfsstats.read_bios,
334306632Srmacklem			(uintmax_t)(ext_nfsstats.biocache_writes -
335306632Srmacklem			ext_nfsstats.write_bios),
336306632Srmacklem			(uintmax_t)ext_nfsstats.write_bios);
33752493Sdillon		printf("%9.9s %9.9s %9.9s %9.9s",
33852493Sdillon			"BioRLHits", "Misses", "BioD Hits", "Misses");
339220596Sru		printf(" %9.9s %9.9s %9.9s %9.9s\n", "DirE Hits", "Misses", "Accs Hits", "Misses");
340306632Srmacklem		printf("%9ju %9ju %9ju %9ju",
341306632Srmacklem			(uintmax_t)(ext_nfsstats.biocache_readlinks -
342306632Srmacklem			ext_nfsstats.readlink_bios),
343306632Srmacklem			(uintmax_t)ext_nfsstats.readlink_bios,
344306632Srmacklem			(uintmax_t)(ext_nfsstats.biocache_readdirs -
345306632Srmacklem			ext_nfsstats.readdir_bios),
346306632Srmacklem			(uintmax_t)ext_nfsstats.readdir_bios);
347306632Srmacklem		printf(" %9ju %9ju %9ju %9ju\n",
348306632Srmacklem			(uintmax_t)ext_nfsstats.direofcache_hits,
349306632Srmacklem			(uintmax_t)ext_nfsstats.direofcache_misses,
350306632Srmacklem			(uintmax_t)ext_nfsstats.accesscache_hits,
351306632Srmacklem			(uintmax_t)ext_nfsstats.accesscache_misses);
35252493Sdillon	}
35352493Sdillon	if (serverOnly) {
35452493Sdillon		printf("\nServer Info:\n");
35552493Sdillon		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
35652493Sdillon			"Getattr", "Setattr", "Lookup", "Readlink", "Read",
35752493Sdillon			"Write", "Create", "Remove");
358306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
359306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
360306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
361306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
362306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
363306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READ],
364306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
365306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CREATE],
366306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
36752493Sdillon		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
36852493Sdillon			"Rename", "Link", "Symlink", "Mkdir", "Rmdir",
36952493Sdillon			"Readdir", "RdirPlus", "Access");
370306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
371306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
372306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
373306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
374306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
375306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
376306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
377306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
378306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
37983653Speter		printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
38083653Speter			"Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
381306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju\n",
382306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
383306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
384306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
385306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
386306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT]);
38752493Sdillon		printf("Server Ret-Failed\n");
388306632Srmacklem		printf("%17ju\n", (uintmax_t)ext_nfsstats.srvrpc_errs);
38952493Sdillon		printf("Server Faults\n");
390306632Srmacklem		printf("%13ju\n", (uintmax_t)ext_nfsstats.srv_errs);
39152493Sdillon		printf("Server Cache Stats:\n");
39252493Sdillon		printf("%9.9s %9.9s %9.9s %9.9s\n",
39352493Sdillon			"Inprog", "Idem", "Non-idem", "Misses");
394306632Srmacklem		printf("%9ju %9ju %9ju %9ju\n",
395306632Srmacklem			(uintmax_t)ext_nfsstats.srvcache_inproghits,
396306632Srmacklem			(uintmax_t)ext_nfsstats.srvcache_idemdonehits,
397306632Srmacklem			(uintmax_t)ext_nfsstats.srvcache_nonidemdonehits,
398306632Srmacklem			(uintmax_t)ext_nfsstats.srvcache_misses);
39952493Sdillon		printf("Server Write Gathering:\n");
40052493Sdillon		printf("%9.9s %9.9s %9.9s\n",
40152493Sdillon			"WriteOps", "WriteRPC", "Opsaved");
402281888Strasz		/*
403281888Strasz		 * The new client doesn't do write gathering. It was
404281888Strasz		 * only useful for NFSv2.
405281888Strasz		 */
406306632Srmacklem		printf("%9ju %9ju %9d\n",
407306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
408306632Srmacklem			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 0);
40952493Sdillon	}
4101590Srgrimes}
4111590Srgrimes
412281888Straszstatic void
413306632Srmacklemprinthdr(int clientOnly, int serverOnly, int newStats)
4141590Srgrimes{
415306632Srmacklem
416306632Srmacklem	if (newStats) {
417306632Srmacklem		printf(" [%s Read %s]  [%s Write %s]  "
418306632Srmacklem		    "%s[=========== Total ============]\n"
419306632Srmacklem		    " KB/t   tps    MB/s%s  KB/t   tps    MB/s%s  "
420306632Srmacklem		    "%sKB/t   tps    MB/s    ms  ql  %%b",
421306632Srmacklem		    widemode ? "========" : "=====",
422306632Srmacklem		    widemode ? "========" : "=====",
423306632Srmacklem		    widemode ? "========" : "=====",
424306632Srmacklem		    widemode ? "======="  : "====",
425306632Srmacklem		    widemode ? "[Commit ]  " : "",
426306632Srmacklem		    widemode ? "    ms" : "",
427306632Srmacklem		    widemode ? "    ms" : "",
428306632Srmacklem		    widemode ? "tps    ms  " : "");
429306632Srmacklem	} else {
430306632Srmacklem		printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
431306632Srmacklem		    ((serverOnly && clientOnly) ? "        " : " "),
432306632Srmacklem		    "GtAttr", "Lookup", "Rdlink", "Read", "Write", "Rename",
433306632Srmacklem		    "Access", "Rddir");
434306632Srmacklem		if (widemode && clientOnly) {
435306632Srmacklem			printf(" Attr Lkup BioR BioW Accs BioD");
436306632Srmacklem		}
43752493Sdillon	}
43852493Sdillon	printf("\n");
4391590Srgrimes	fflush(stdout);
4401590Srgrimes}
4411590Srgrimes
442281888Straszstatic void
443172759Sjhbusage(void)
4441590Srgrimes{
4451590Srgrimes	(void)fprintf(stderr,
446306632Srmacklem	    "usage: nfsstat [-cdemszW] [-M core] [-N system] [-w wait]\n");
4471590Srgrimes	exit(1);
4481590Srgrimes}
44952493Sdillon
45052493Sdillonstatic char SPBuf[64][8];
45152493Sdillonstatic int SPIndex;
45252493Sdillon
453281888Straszstatic char *
45452493Sdillonsperc1(int hits, int misses)
45552493Sdillon{
45652493Sdillon	char *p = SPBuf[SPIndex];
45752493Sdillon
45852493Sdillon	if (hits + misses) {
45952493Sdillon		sprintf(p, "%3d%%",
46052493Sdillon		    (int)(char)((quad_t)hits * 100 / (hits + misses)));
46152493Sdillon	} else {
46252493Sdillon		sprintf(p, "   -");
46352493Sdillon	}
46452493Sdillon	SPIndex = (SPIndex + 1) & 63;
46552493Sdillon	return(p);
46652493Sdillon}
46752493Sdillon
468281888Straszstatic char *
46952493Sdillonsperc2(int ttl, int misses)
47052493Sdillon{
47152493Sdillon	char *p = SPBuf[SPIndex];
47252493Sdillon
47352493Sdillon	if (ttl) {
47452493Sdillon		sprintf(p, "%3d%%",
47552493Sdillon		    (int)(char)((quad_t)(ttl - misses) * 100 / ttl));
47652493Sdillon	} else {
47752493Sdillon		sprintf(p, "   -");
47852493Sdillon	}
47952493Sdillon	SPIndex = (SPIndex + 1) & 63;
48052493Sdillon	return(p);
48152493Sdillon}
48252493Sdillon
483306632Srmacklem#define DELTA_T(field)					\
484306632Srmacklem	devstat_compute_etime(&cur_stats->field,	\
485306632Srmacklem	(prev_stats ? &prev_stats->field : NULL))
486306632Srmacklem
487192762Srmacklem/*
488306632Srmacklem * XXX KDM mostly copied from ctlstat.  We should commonize the code (and
489306632Srmacklem * the devstat code) somehow.
490306632Srmacklem */
491306632Srmacklemstatic void
492306632Srmacklemcompute_new_stats(struct nfsstatsv1 *cur_stats,
493306632Srmacklem		  struct nfsstatsv1 *prev_stats, int curop,
494306632Srmacklem		  long double etime, long double *mbsec,
495306632Srmacklem		  long double *kb_per_transfer,
496306632Srmacklem		  long double *transfers_per_second,
497306632Srmacklem		  long double *ms_per_transfer, uint64_t *queue_len,
498306632Srmacklem		  long double *busy_pct)
499306632Srmacklem{
500306632Srmacklem	uint64_t total_bytes = 0, total_operations = 0;
501306632Srmacklem	struct bintime total_time_bt;
502306632Srmacklem	struct timespec total_time_ts;
503306632Srmacklem
504306632Srmacklem	bzero(&total_time_bt, sizeof(total_time_bt));
505306632Srmacklem	bzero(&total_time_ts, sizeof(total_time_ts));
506306632Srmacklem
507306632Srmacklem	total_bytes = cur_stats->srvbytes[curop];
508306632Srmacklem	total_operations = cur_stats->srvops[curop];
509306632Srmacklem	if (prev_stats != NULL) {
510306632Srmacklem		total_bytes -= prev_stats->srvbytes[curop];
511306632Srmacklem		total_operations -= prev_stats->srvops[curop];
512306632Srmacklem	}
513306632Srmacklem
514306632Srmacklem	*mbsec = total_bytes;
515306632Srmacklem	*mbsec /= 1024 * 1024;
516306632Srmacklem	if (etime > 0.0) {
517306632Srmacklem		*busy_pct = DELTA_T(busytime);
518306632Srmacklem		if (*busy_pct < 0)
519306632Srmacklem			*busy_pct = 0;
520306632Srmacklem		*busy_pct /= etime;
521306632Srmacklem		*busy_pct *= 100;
522306632Srmacklem		if (*busy_pct < 0)
523306632Srmacklem			*busy_pct = 0;
524306632Srmacklem		*mbsec /= etime;
525306632Srmacklem	} else {
526306632Srmacklem		*busy_pct = 0;
527306632Srmacklem		*mbsec = 0;
528306632Srmacklem	}
529306632Srmacklem	*kb_per_transfer = total_bytes;
530306632Srmacklem	*kb_per_transfer /= 1024;
531306632Srmacklem	if (total_operations > 0)
532306632Srmacklem		*kb_per_transfer /= total_operations;
533306632Srmacklem	else
534306632Srmacklem		*kb_per_transfer = 0;
535306632Srmacklem	if (etime > 0.0) {
536306632Srmacklem		*transfers_per_second = total_operations;
537306632Srmacklem		*transfers_per_second /= etime;
538306632Srmacklem	} else {
539306632Srmacklem		*transfers_per_second = 0.0;
540306632Srmacklem	}
541306632Srmacklem
542306632Srmacklem	if (total_operations > 0) {
543306632Srmacklem		*ms_per_transfer = DELTA_T(srvduration[curop]);
544306632Srmacklem		*ms_per_transfer /= total_operations;
545306632Srmacklem		*ms_per_transfer *= 1000;
546306632Srmacklem	} else
547306632Srmacklem		*ms_per_transfer = 0.0;
548306632Srmacklem
549306632Srmacklem	*queue_len = cur_stats->srvstartcnt - cur_stats->srvdonecnt;
550306632Srmacklem}
551306632Srmacklem
552306632Srmacklem/*
553192762Srmacklem * Print a description of the nfs stats for the experimental client/server.
554192762Srmacklem */
555281888Straszstatic void
556192762Srmacklemexp_intpr(int clientOnly, int serverOnly)
557192762Srmacklem{
558221440Srmacklem	int nfssvc_flag;
559192762Srmacklem
560306632Srmacklem	nfssvc_flag = NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT;
561221440Srmacklem	if (zflag != 0) {
562221440Srmacklem		if (clientOnly != 0)
563221440Srmacklem			nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
564221440Srmacklem		if (serverOnly != 0)
565221440Srmacklem			nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
566221440Srmacklem	}
567306632Srmacklem	ext_nfsstats.vers = NFSSTATS_V1;
568221440Srmacklem	if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
569221440Srmacklem		err(1, "Can't get stats");
570192762Srmacklem	if (clientOnly != 0) {
571192762Srmacklem		if (printtitle) {
572192762Srmacklem			printf("Client Info:\n");
573192762Srmacklem			printf("Rpc Counts:\n");
574192762Srmacklem			printf(
575192762Srmacklem			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
576192762Srmacklem			    , "Getattr", "Setattr", "Lookup", "Readlink",
577192762Srmacklem			    "Read", "Write", "Create", "Remove");
578192762Srmacklem		}
579306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
580306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETATTR],
581306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETATTR],
582306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
583306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READLINK],
584306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READ],
585306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_WRITE],
586306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATE],
587306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
588192762Srmacklem		if (printtitle)
589192762Srmacklem			printf(
590192762Srmacklem			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
591192762Srmacklem			    , "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
592192762Srmacklem			    "Readdir", "RdirPlus", "Access");
593306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
594306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RENAME],
595306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LINK],
596306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
597306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKDIR],
598306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RMDIR],
599306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIR],
600306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
601306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
602192762Srmacklem		if (printtitle)
603192762Srmacklem			printf(
604192762Srmacklem			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
605192762Srmacklem			    , "Mknod", "Fsstat", "Fsinfo", "PathConf",
606192762Srmacklem			    "Commit", "SetClId", "SetClIdCf", "Lock");
607306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
608306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKNOD],
609306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
610306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSINFO],
611306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
612306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_COMMIT],
613306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID],
614306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM],
615306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCK]);
616192762Srmacklem		if (printtitle)
617192762Srmacklem			printf("%9.9s %9.9s %9.9s %9.9s\n",
618192762Srmacklem			    "LockT", "LockU", "Open", "OpenCfr");
619306632Srmacklem		printf("%9ju %9ju %9ju %9ju\n",
620306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCKT],
621306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCKU],
622306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPEN],
623306632Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM]);
624192762Srmacklem		if (printtitle)
625192762Srmacklem			printf(
626192762Srmacklem			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
627192762Srmacklem			    , "OpenOwner", "Opens", "LockOwner",
628192762Srmacklem			    "Locks", "Delegs", "LocalOwn",
629192762Srmacklem			    "LocalOpen", "LocalLOwn");
630306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
631306632Srmacklem		    (uintmax_t)ext_nfsstats.clopenowners,
632306632Srmacklem		    (uintmax_t)ext_nfsstats.clopens,
633306632Srmacklem		    (uintmax_t)ext_nfsstats.cllockowners,
634306632Srmacklem		    (uintmax_t)ext_nfsstats.cllocks,
635306632Srmacklem		    (uintmax_t)ext_nfsstats.cldelegates,
636306632Srmacklem		    (uintmax_t)ext_nfsstats.cllocalopenowners,
637306632Srmacklem		    (uintmax_t)ext_nfsstats.cllocalopens,
638306632Srmacklem		    (uintmax_t)ext_nfsstats.cllocallockowners);
639192762Srmacklem		if (printtitle)
640192762Srmacklem			printf("%9.9s\n", "LocalLock");
641306632Srmacklem		printf("%9ju\n", (uintmax_t)ext_nfsstats.cllocallocks);
642192762Srmacklem		if (printtitle) {
643192762Srmacklem			printf("Rpc Info:\n");
644192762Srmacklem			printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
645192762Srmacklem			    "TimedOut", "Invalid", "X Replies", "Retries",
646192762Srmacklem			    "Requests");
647192762Srmacklem		}
648306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju\n",
649306632Srmacklem		    (uintmax_t)ext_nfsstats.rpctimeouts,
650306632Srmacklem		    (uintmax_t)ext_nfsstats.rpcinvalid,
651306632Srmacklem		    (uintmax_t)ext_nfsstats.rpcunexpected,
652306632Srmacklem		    (uintmax_t)ext_nfsstats.rpcretries,
653306632Srmacklem		    (uintmax_t)ext_nfsstats.rpcrequests);
654192762Srmacklem		if (printtitle) {
655192762Srmacklem			printf("Cache Info:\n");
656192762Srmacklem			printf("%9.9s %9.9s %9.9s %9.9s",
657192762Srmacklem			    "Attr Hits", "Misses", "Lkup Hits", "Misses");
658192762Srmacklem			printf(" %9.9s %9.9s %9.9s %9.9s\n",
659192762Srmacklem			    "BioR Hits", "Misses", "BioW Hits", "Misses");
660192762Srmacklem		}
661306632Srmacklem		printf("%9ju %9ju %9ju %9ju",
662306632Srmacklem		    (uintmax_t)ext_nfsstats.attrcache_hits,
663306632Srmacklem		    (uintmax_t)ext_nfsstats.attrcache_misses,
664306632Srmacklem		    (uintmax_t)ext_nfsstats.lookupcache_hits,
665306632Srmacklem		    (uintmax_t)ext_nfsstats.lookupcache_misses);
666306632Srmacklem		printf(" %9ju %9ju %9ju %9ju\n",
667306632Srmacklem		    (uintmax_t)(ext_nfsstats.biocache_reads -
668306632Srmacklem		    ext_nfsstats.read_bios),
669306632Srmacklem		    (uintmax_t)ext_nfsstats.read_bios,
670306632Srmacklem		    (uintmax_t)(ext_nfsstats.biocache_writes -
671306632Srmacklem		    ext_nfsstats.write_bios),
672306632Srmacklem		    (uintmax_t)ext_nfsstats.write_bios);
673192762Srmacklem		if (printtitle) {
674192762Srmacklem			printf("%9.9s %9.9s %9.9s %9.9s",
675192762Srmacklem			    "BioRLHits", "Misses", "BioD Hits", "Misses");
676192762Srmacklem			printf(" %9.9s %9.9s\n", "DirE Hits", "Misses");
677192762Srmacklem		}
678306632Srmacklem		printf("%9ju %9ju %9ju %9ju",
679306632Srmacklem		    (uintmax_t)(ext_nfsstats.biocache_readlinks -
680306632Srmacklem		    ext_nfsstats.readlink_bios),
681306632Srmacklem		    (uintmax_t)ext_nfsstats.readlink_bios,
682306632Srmacklem		    (uintmax_t)(ext_nfsstats.biocache_readdirs -
683306632Srmacklem		    ext_nfsstats.readdir_bios),
684306632Srmacklem		    (uintmax_t)ext_nfsstats.readdir_bios);
685306632Srmacklem		printf(" %9ju %9ju\n",
686306632Srmacklem		    (uintmax_t)ext_nfsstats.direofcache_hits,
687306632Srmacklem		    (uintmax_t)ext_nfsstats.direofcache_misses);
688192762Srmacklem	}
689192762Srmacklem	if (serverOnly != 0) {
690192762Srmacklem		if (printtitle) {
691192762Srmacklem			printf("\nServer Info:\n");
692192762Srmacklem			printf(
693192762Srmacklem			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
694192762Srmacklem			    , "Getattr", "Setattr", "Lookup", "Readlink",
695192762Srmacklem			    "Read", "Write", "Create", "Remove");
696192762Srmacklem		}
697306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
698306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
699306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
700306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
701306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
702306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READ],
703306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
704306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE],
705306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
706192762Srmacklem		if (printtitle)
707192762Srmacklem			printf(
708192762Srmacklem			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
709192762Srmacklem			    , "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
710192762Srmacklem			    "Readdir", "RdirPlus", "Access");
711306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
712306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
713306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
714306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
715306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
716306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
717306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
718306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
719306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
720192762Srmacklem		if (printtitle)
721192762Srmacklem			printf(
722192762Srmacklem			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
723192762Srmacklem			    , "Mknod", "Fsstat", "Fsinfo", "PathConf",
724192762Srmacklem			    "Commit", "LookupP", "SetClId", "SetClIdCf");
725306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
726306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
727306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
728306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
729306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
730306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT],
731306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP],
732306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID],
733306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]);
734192762Srmacklem		if (printtitle)
735192762Srmacklem			printf(
736192762Srmacklem			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
737192762Srmacklem			    , "Open", "OpenAttr", "OpenDwnGr", "OpenCfrm",
738192762Srmacklem			    "DelePurge", "DeleRet", "GetFH", "Lock");
739306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
740306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPEN],
741306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR],
742306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE],
743306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM],
744306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE],
745306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN],
746306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETFH],
747306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCK]);
748192762Srmacklem		if (printtitle)
749192762Srmacklem			printf(
750192762Srmacklem			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
751192762Srmacklem			    , "LockT", "LockU", "Close", "Verify", "NVerify",
752192762Srmacklem			    "PutFH", "PutPubFH", "PutRootFH");
753306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
754306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT],
755306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU],
756306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE],
757306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY],
758306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY],
759306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH],
760306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH],
761306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH]);
762192762Srmacklem		if (printtitle)
763192762Srmacklem			printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
764192762Srmacklem			    "Renew", "RestoreFH", "SaveFH", "Secinfo",
765192762Srmacklem			    "RelLckOwn", "V4Create");
766306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju\n",
767306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENEW],
768306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH],
769306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH],
770306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO],
771306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN],
772306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]);
773192762Srmacklem		if (printtitle) {
774192762Srmacklem			printf("Server:\n");
775192762Srmacklem			printf("%9.9s %9.9s %9.9s\n",
776192762Srmacklem			    "Retfailed", "Faults", "Clients");
777192762Srmacklem		}
778306632Srmacklem		printf("%9ju %9ju %9ju\n",
779306632Srmacklem		    (uintmax_t)ext_nfsstats.srv_errs,
780306632Srmacklem		    (uintmax_t)ext_nfsstats.srvrpc_errs,
781306632Srmacklem		    (uintmax_t)ext_nfsstats.srvclients);
782192762Srmacklem		if (printtitle)
783192762Srmacklem			printf("%9.9s %9.9s %9.9s %9.9s %9.9s \n",
784192762Srmacklem			    "OpenOwner", "Opens", "LockOwner",
785192762Srmacklem			    "Locks", "Delegs");
786306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju \n",
787306632Srmacklem		    (uintmax_t)ext_nfsstats.srvopenowners,
788306632Srmacklem		    (uintmax_t)ext_nfsstats.srvopens,
789306632Srmacklem		    (uintmax_t)ext_nfsstats.srvlockowners,
790306632Srmacklem		    (uintmax_t)ext_nfsstats.srvlocks,
791306632Srmacklem		    (uintmax_t)ext_nfsstats.srvdelegates);
792192762Srmacklem		if (printtitle) {
793192762Srmacklem			printf("Server Cache Stats:\n");
794192762Srmacklem			printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
795192762Srmacklem			    "Inprog", "Idem", "Non-idem", "Misses",
796192762Srmacklem			    "CacheSize", "TCPPeak");
797192762Srmacklem		}
798306632Srmacklem		printf("%9ju %9ju %9ju %9ju %9ju %9ju\n",
799306632Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_inproghits,
800306632Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_idemdonehits,
801306632Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_nonidemdonehits,
802306632Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_misses,
803306632Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_size,
804306632Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_tcppeak);
805192762Srmacklem	}
806192762Srmacklem}
807192762Srmacklem
808309831Srmacklem/*
809309831Srmacklem * Print a description of the nfs stats for the client/server,
810309831Srmacklem * including NFSv4.1.
811309831Srmacklem */
812306632Srmacklemstatic void
813309831Srmacklemexp41_intpr(int clientOnly, int serverOnly)
814309831Srmacklem{
815309831Srmacklem	int nfssvc_flag;
816309831Srmacklem
817309831Srmacklem	nfssvc_flag = NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT;
818309831Srmacklem	if (zflag != 0) {
819309831Srmacklem		if (clientOnly != 0)
820309831Srmacklem			nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
821309831Srmacklem		if (serverOnly != 0)
822309831Srmacklem			nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
823309831Srmacklem	}
824309831Srmacklem	ext_nfsstats.vers = NFSSTATS_V1;
825309831Srmacklem	if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
826309831Srmacklem		err(1, "Can't get stats");
827309831Srmacklem	if (clientOnly != 0) {
828309831Srmacklem		if (printtitle) {
829309831Srmacklem			printf("Client Info:\n");
830309831Srmacklem			printf("RPC Counts:\n");
831309831Srmacklem			printf(
832309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
833309831Srmacklem			    "Getattr", "Setattr", "Lookup", "Readlink", "Read",
834309831Srmacklem			    "Write");
835309831Srmacklem		}
836309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
837309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETATTR],
838309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETATTR],
839309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
840309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READLINK],
841309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READ],
842309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_WRITE]);
843309831Srmacklem		if (printtitle)
844309831Srmacklem			printf(
845309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
846309831Srmacklem			    "Create", "Remove", "Rename", "Link", "Symlink",
847309831Srmacklem			    "Mkdir");
848309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
849309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATE],
850309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_REMOVE],
851309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RENAME],
852309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LINK],
853309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
854309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKDIR]);
855309831Srmacklem		if (printtitle)
856309831Srmacklem			printf(
857309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
858309831Srmacklem			    "Rmdir", "Readdir", "RdirPlus", "Access", "Mknod",
859309831Srmacklem			    "Fsstat");
860309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
861309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RMDIR],
862309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIR],
863309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
864309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_ACCESS],
865309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKNOD],
866309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSSTAT]);
867309831Srmacklem		if (printtitle)
868309831Srmacklem			printf(
869309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
870309831Srmacklem			    "Fsinfo", "PathConf", "Commit", "SetClId",
871309831Srmacklem			    "SetClIdCf", "Lock");
872309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
873309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSINFO],
874309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
875309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_COMMIT],
876309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID],
877309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM],
878309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCK]);
879309831Srmacklem		if (printtitle)
880309831Srmacklem			printf(
881309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
882309831Srmacklem			    "LockT", "LockU", "Open", "OpenCfr", "OpenDownGr",
883309831Srmacklem			    "Close");
884309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
885309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCKT],
886309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCKU],
887309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPEN],
888309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM],
889309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPENDOWNGRADE],
890309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CLOSE]);
891309831Srmacklem		if (printtitle)
892309831Srmacklem			printf(
893309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
894309831Srmacklem			    "RelLckOwn", "FreeStateID", "PutRootFH", "DelegRet",
895309831Srmacklem			    "GetACL", "SetACL");
896309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
897309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RELEASELCKOWN],
898309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FREESTATEID],
899309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_PUTROOTFH],
900309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_DELEGRETURN],
901309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETACL],
902309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETACL]);
903309831Srmacklem		if (printtitle)
904309831Srmacklem			printf(
905309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
906309831Srmacklem			    "ExchangeID", "CreateSess", "DestroySess",
907309831Srmacklem			    "DestroyClId", "LayoutGet", "GetDevInfo");
908309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
909309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_EXCHANGEID],
910309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATESESSION],
911309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_DESTROYSESSION],
912309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_DESTROYCLIENT],
913309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LAYOUTGET],
914309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETDEVICEINFO]);
915309831Srmacklem		if (printtitle)
916309831Srmacklem			printf(
917309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
918309831Srmacklem			    "LayoutCommit", "LayoutReturn", "ReclaimCompl",
919309831Srmacklem			    "ReadDataS", "WriteDataS", "CommitDataS");
920309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
921309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LAYOUTCOMMIT],
922309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LAYOUTRETURN],
923309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RECLAIMCOMPL],
924309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDS],
925309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_WRITEDS],
926309831Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_COMMITDS]);
927309831Srmacklem		if (printtitle)
928309831Srmacklem			printf(
929321000Srmacklem			    "%12.12s %12.12s\n",
930321000Srmacklem			    "OpenLayout", "CreateLayout");
931321000Srmacklem		printf("%12ju %12ju\n",
932321000Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPENLAYGET],
933321000Srmacklem		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATELAYGET]);
934321000Srmacklem		if (printtitle)
935321000Srmacklem			printf(
936309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
937309831Srmacklem			    "OpenOwner", "Opens", "LockOwner", "Locks",
938309831Srmacklem			    "Delegs", "LocalOwn");
939309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
940309831Srmacklem		    (uintmax_t)ext_nfsstats.clopenowners,
941309831Srmacklem		    (uintmax_t)ext_nfsstats.clopens,
942309831Srmacklem		    (uintmax_t)ext_nfsstats.cllockowners,
943309831Srmacklem		    (uintmax_t)ext_nfsstats.cllocks,
944309831Srmacklem		    (uintmax_t)ext_nfsstats.cldelegates,
945309831Srmacklem		    (uintmax_t)ext_nfsstats.cllocalopenowners);
946309831Srmacklem		if (printtitle)
947309831Srmacklem			printf("%12.12s %12.12s %12.12s\n",
948309831Srmacklem			    "LocalOpen", "LocalLOwn", "LocalLock");
949309831Srmacklem		printf("%12ju %12ju %12ju\n",
950309831Srmacklem		    (uintmax_t)ext_nfsstats.cllocalopens,
951309831Srmacklem		    (uintmax_t)ext_nfsstats.cllocallockowners,
952309831Srmacklem		    (uintmax_t)ext_nfsstats.cllocallocks);
953309831Srmacklem		if (printtitle) {
954309831Srmacklem			printf("Rpc Info:\n");
955309831Srmacklem			printf("%12.12s %12.12s %12.12s %12.12s %12.12s\n",
956309831Srmacklem			    "TimedOut", "Invalid", "X Replies", "Retries",
957309831Srmacklem			    "Requests");
958309831Srmacklem		}
959309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju\n",
960309831Srmacklem		    (uintmax_t)ext_nfsstats.rpctimeouts,
961309831Srmacklem		    (uintmax_t)ext_nfsstats.rpcinvalid,
962309831Srmacklem		    (uintmax_t)ext_nfsstats.rpcunexpected,
963309831Srmacklem		    (uintmax_t)ext_nfsstats.rpcretries,
964309831Srmacklem		    (uintmax_t)ext_nfsstats.rpcrequests);
965309831Srmacklem		if (printtitle) {
966309831Srmacklem			printf("Cache Info:\n");
967309831Srmacklem			printf("%12.12s %12.12s %12.12s %12.12s\n",
968309831Srmacklem			    "Attr Hits", "Misses", "Lkup Hits", "Misses");
969309831Srmacklem		}
970309831Srmacklem		printf("%12ju %12ju %12ju %12ju\n",
971309831Srmacklem		    (uintmax_t)ext_nfsstats.attrcache_hits,
972309831Srmacklem		    (uintmax_t)ext_nfsstats.attrcache_misses,
973309831Srmacklem		    (uintmax_t)ext_nfsstats.lookupcache_hits,
974309831Srmacklem		    (uintmax_t)ext_nfsstats.lookupcache_misses);
975309831Srmacklem		if (printtitle)
976309831Srmacklem			printf("%12.12s %12.12s %12.12s %12.12s\n",
977309831Srmacklem			    "BioR Hits", "Misses", "BioW Hits", "Misses");
978309831Srmacklem		printf("%12ju %12ju %12ju %12ju\n",
979309831Srmacklem		    (uintmax_t)(ext_nfsstats.biocache_reads -
980309831Srmacklem		    ext_nfsstats.read_bios),
981309831Srmacklem		    (uintmax_t)ext_nfsstats.read_bios,
982309831Srmacklem		    (uintmax_t)(ext_nfsstats.biocache_writes -
983309831Srmacklem		    ext_nfsstats.write_bios),
984309831Srmacklem		    (uintmax_t)ext_nfsstats.write_bios);
985309831Srmacklem		if (printtitle)
986309831Srmacklem			printf("%12.12s %12.12s %12.12s %12.12s\n",
987309831Srmacklem			    "BioRLHits", "Misses", "BioD Hits", "Misses");
988309831Srmacklem		printf("%12ju %12ju %12ju %12ju\n",
989309831Srmacklem		    (uintmax_t)(ext_nfsstats.biocache_readlinks -
990309831Srmacklem		    ext_nfsstats.readlink_bios),
991309831Srmacklem		    (uintmax_t)ext_nfsstats.readlink_bios,
992309831Srmacklem		    (uintmax_t)(ext_nfsstats.biocache_readdirs -
993309831Srmacklem		    ext_nfsstats.readdir_bios),
994309831Srmacklem		    (uintmax_t)ext_nfsstats.readdir_bios);
995309831Srmacklem		if (printtitle)
996309831Srmacklem			printf("%12.12s %12.12s\n", "DirE Hits", "Misses");
997309831Srmacklem		printf("%12ju %12ju\n",
998309831Srmacklem		    (uintmax_t)ext_nfsstats.direofcache_hits,
999309831Srmacklem		    (uintmax_t)ext_nfsstats.direofcache_misses);
1000309831Srmacklem	}
1001309831Srmacklem	if (serverOnly != 0) {
1002309831Srmacklem		if (printtitle) {
1003309831Srmacklem			printf("\nServer Info:\n");
1004309831Srmacklem			printf(
1005309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1006309831Srmacklem			    "Getattr", "Setattr", "Lookup", "Readlink",
1007309831Srmacklem			    "Read", "Write");
1008309831Srmacklem		}
1009309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1010309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
1011309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
1012309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
1013309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
1014309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READ],
1015309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE]);
1016309831Srmacklem		if (printtitle)
1017309831Srmacklem			printf(
1018309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1019309831Srmacklem			    "Create", "Remove", "Rename", "Link", "Symlink",
1020309831Srmacklem			    "Mkdir");
1021309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1022309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE],
1023309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE],
1024309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
1025309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
1026309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
1027309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR]);
1028309831Srmacklem		if (printtitle)
1029309831Srmacklem			printf(
1030309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1031309831Srmacklem			    "Rmdir", "Readdir", "RdirPlus", "Access", "Mknod",
1032309831Srmacklem			    "Fsstat");
1033309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1034309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
1035309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
1036309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
1037309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS],
1038309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
1039309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT]);
1040309831Srmacklem		if (printtitle)
1041309831Srmacklem			printf(
1042309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1043309831Srmacklem			    "Fsinfo", "PathConf", "Commit", "LookupP",
1044309831Srmacklem			    "SetClId", "SetClIdCf");
1045309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1046309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
1047309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
1048309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT],
1049309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP],
1050309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID],
1051309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]);
1052309831Srmacklem		if (printtitle)
1053309831Srmacklem			printf(
1054309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1055309831Srmacklem			    "Open", "OpenAttr", "OpenDwnGr", "OpenCfrm",
1056309831Srmacklem			    "DelePurge", "DeleRet");
1057309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1058309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPEN],
1059309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR],
1060309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE],
1061309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM],
1062309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE],
1063309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN]);
1064309831Srmacklem		if (printtitle)
1065309831Srmacklem			printf(
1066309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1067309831Srmacklem			    "GetFH", "Lock", "LockT", "LockU", "Close",
1068309831Srmacklem			    "Verify");
1069309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1070309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETFH],
1071309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCK],
1072309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT],
1073309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU],
1074309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE],
1075309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY]);
1076309831Srmacklem		if (printtitle)
1077309831Srmacklem			printf(
1078309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1079309831Srmacklem			    "NVerify", "PutFH", "PutPubFH", "PutRootFH",
1080309831Srmacklem			    "Renew", "RestoreFH");
1081309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1082309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY],
1083309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH],
1084309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH],
1085309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH],
1086309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENEW],
1087309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH]);
1088309831Srmacklem		if (printtitle)
1089309831Srmacklem			printf(
1090309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1091309831Srmacklem			    "SaveFH", "Secinfo", "RelLckOwn", "V4Create",
1092309831Srmacklem			    "BackChannelCtrl", "BindConnToSess");
1093309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1094309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH],
1095309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO],
1096309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN],
1097309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CREATE],
1098309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_BACKCHANNELCTL],
1099309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_BINDCONNTOSESS]);
1100309831Srmacklem		if (printtitle)
1101309831Srmacklem			printf(
1102309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1103309831Srmacklem			    "ExchangeID", "CreateSess", "DestroySess",
1104309831Srmacklem			    "FreeStateID", "GetDirDeleg", "GetDevInfo");
1105309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1106309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_EXCHANGEID],
1107309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CREATESESSION],
1108309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DESTROYSESSION],
1109309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FREESTATEID],
1110309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETDIRDELEG],
1111309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETDEVINFO]);
1112309831Srmacklem		if (printtitle)
1113309831Srmacklem			printf(
1114309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1115309831Srmacklem			    "GetDevList", "LayoutCommit", "LayoutGet",
1116309831Srmacklem			    "LayoutReturn", "SecInfNoName", "Sequence");
1117309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1118309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETDEVLIST],
1119309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LAYOUTCOMMIT],
1120309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LAYOUTGET],
1121309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LAYOUTRETURN],
1122309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SECINFONONAME],
1123309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SEQUENCE]);
1124309831Srmacklem		if (printtitle)
1125309831Srmacklem			printf(
1126309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s\n",
1127309831Srmacklem			    "SetSSV", "TestStateID", "WantDeleg",
1128309831Srmacklem			    "DestroyClID", "ReclaimCompl");
1129309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju\n",
1130309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETSSV],
1131309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_TESTSTATEID],
1132309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WANTDELEG],
1133309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DESTROYCLIENTID],
1134309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RECLAIMCOMPL]);
1135309831Srmacklem		if (printtitle) {
1136309831Srmacklem			printf("Server:\n");
1137309831Srmacklem			printf("%12.12s %12.12s %12.12s\n",
1138309831Srmacklem			    "Retfailed", "Faults", "Clients");
1139309831Srmacklem		}
1140309831Srmacklem		printf("%12ju %12ju %12ju\n",
1141309831Srmacklem		    (uintmax_t)ext_nfsstats.srv_errs,
1142309831Srmacklem		    (uintmax_t)ext_nfsstats.srvrpc_errs,
1143309831Srmacklem		    (uintmax_t)ext_nfsstats.srvclients);
1144309831Srmacklem		if (printtitle)
1145309831Srmacklem			printf("%12.12s %12.12s %12.12s %12.12s %12.12s\n",
1146309831Srmacklem			    "OpenOwner", "Opens", "LockOwner",
1147309831Srmacklem			    "Locks", "Delegs");
1148309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju\n",
1149309831Srmacklem		    (uintmax_t)ext_nfsstats.srvopenowners,
1150309831Srmacklem		    (uintmax_t)ext_nfsstats.srvopens,
1151309831Srmacklem		    (uintmax_t)ext_nfsstats.srvlockowners,
1152309831Srmacklem		    (uintmax_t)ext_nfsstats.srvlocks,
1153309831Srmacklem		    (uintmax_t)ext_nfsstats.srvdelegates);
1154309831Srmacklem		if (printtitle) {
1155309831Srmacklem			printf("Server Cache Stats:\n");
1156309831Srmacklem			printf(
1157309831Srmacklem			    "%12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n",
1158309831Srmacklem			    "Inprog", "Idem", "Non-idem", "Misses",
1159309831Srmacklem			    "CacheSize", "TCPPeak");
1160309831Srmacklem		}
1161309831Srmacklem		printf("%12ju %12ju %12ju %12ju %12ju %12ju\n",
1162309831Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_inproghits,
1163309831Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_idemdonehits,
1164309831Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_nonidemdonehits,
1165309831Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_misses,
1166309831Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_size,
1167309831Srmacklem		    (uintmax_t)ext_nfsstats.srvcache_tcppeak);
1168309831Srmacklem	}
1169309831Srmacklem}
1170309831Srmacklem
1171309831Srmacklemstatic void
1172306632Srmacklemcompute_totals(struct nfsstatsv1 *total_stats, struct nfsstatsv1 *cur_stats)
1173306632Srmacklem{
1174306632Srmacklem	int i;
1175306632Srmacklem
1176306632Srmacklem	bzero(total_stats, sizeof(*total_stats));
1177306632Srmacklem	for (i = 0; i < (NFSV42_NOPS + NFSV4OP_FAKENOPS); i++) {
1178306632Srmacklem		total_stats->srvbytes[0] += cur_stats->srvbytes[i];
1179306632Srmacklem		total_stats->srvops[0] += cur_stats->srvops[i];
1180306632Srmacklem		bintime_add(&total_stats->srvduration[0],
1181306632Srmacklem			    &cur_stats->srvduration[i]);
1182306632Srmacklem		total_stats->srvrpccnt[i] = cur_stats->srvrpccnt[i];
1183306632Srmacklem	}
1184306632Srmacklem	total_stats->srvstartcnt = cur_stats->srvstartcnt;
1185306632Srmacklem	total_stats->srvdonecnt = cur_stats->srvdonecnt;
1186306632Srmacklem	total_stats->busytime = cur_stats->busytime;
1187306632Srmacklem
1188306632Srmacklem}
1189306632Srmacklem
1190192762Srmacklem/*
1191192762Srmacklem * Print a running summary of nfs statistics for the experimental client and/or
1192192762Srmacklem * server.
1193192762Srmacklem * Repeat display every interval seconds, showing statistics
1194192762Srmacklem * collected over that interval.  Assumes that interval is non-zero.
1195192762Srmacklem * First line printed at top of screen is always cumulative.
1196192762Srmacklem */
1197281888Straszstatic void
1198306632Srmacklemexp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly,
1199306632Srmacklem    int newStats)
1200192762Srmacklem{
1201306632Srmacklem	struct nfsstatsv1 nfsstats, lastst, *ext_nfsstatsp;
1202306632Srmacklem	struct nfsstatsv1 curtotal, lasttotal;
1203306632Srmacklem	struct timespec ts, lastts;
1204192762Srmacklem	int hdrcnt = 1;
1205192762Srmacklem
1206192762Srmacklem	ext_nfsstatsp = &lastst;
1207306632Srmacklem	ext_nfsstatsp->vers = NFSSTATS_V1;
1208306632Srmacklem	if (nfssvc(NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT, ext_nfsstatsp) < 0)
1209192762Srmacklem		err(1, "Can't get stats");
1210306632Srmacklem	clock_gettime(CLOCK_MONOTONIC, &lastts);
1211306632Srmacklem	compute_totals(&lasttotal, ext_nfsstatsp);
1212192762Srmacklem	sleep(interval);
1213192762Srmacklem
1214192762Srmacklem	for (;;) {
1215192762Srmacklem		ext_nfsstatsp = &nfsstats;
1216306632Srmacklem		ext_nfsstatsp->vers = NFSSTATS_V1;
1217306632Srmacklem		if (nfssvc(NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT, ext_nfsstatsp)
1218306632Srmacklem		    < 0)
1219192762Srmacklem			err(1, "Can't get stats");
1220306632Srmacklem		clock_gettime(CLOCK_MONOTONIC, &ts);
1221192762Srmacklem
1222192762Srmacklem		if (--hdrcnt == 0) {
1223306632Srmacklem			printhdr(clientOnly, serverOnly, newStats);
1224306632Srmacklem			if (newStats)
1225306632Srmacklem				hdrcnt = 20;
1226306632Srmacklem			else if (clientOnly && serverOnly)
1227192762Srmacklem				hdrcnt = 10;
1228192762Srmacklem			else
1229192762Srmacklem				hdrcnt = 20;
1230192762Srmacklem		}
1231306632Srmacklem		if (clientOnly && newStats == 0) {
1232306632Srmacklem		    printf("%s %6ju %6ju %6ju %6ju %6ju %6ju %6ju %6ju",
1233192762Srmacklem			((clientOnly && serverOnly) ? "Client:" : ""),
1234306632Srmacklem			(uintmax_t)DELTA(rpccnt[NFSPROC_GETATTR]),
1235306632Srmacklem			(uintmax_t)DELTA(rpccnt[NFSPROC_LOOKUP]),
1236306632Srmacklem			(uintmax_t)DELTA(rpccnt[NFSPROC_READLINK]),
1237306632Srmacklem			(uintmax_t)DELTA(rpccnt[NFSPROC_READ]),
1238306632Srmacklem			(uintmax_t)DELTA(rpccnt[NFSPROC_WRITE]),
1239306632Srmacklem			(uintmax_t)DELTA(rpccnt[NFSPROC_RENAME]),
1240306632Srmacklem			(uintmax_t)DELTA(rpccnt[NFSPROC_ACCESS]),
1241306632Srmacklem			(uintmax_t)(DELTA(rpccnt[NFSPROC_READDIR]) +
1242306632Srmacklem			DELTA(rpccnt[NFSPROC_READDIRPLUS]))
1243192762Srmacklem		    );
1244192762Srmacklem		    if (widemode) {
1245192762Srmacklem			    printf(" %s %s %s %s %s %s",
1246192762Srmacklem				sperc1(DELTA(attrcache_hits),
1247192762Srmacklem				    DELTA(attrcache_misses)),
1248192762Srmacklem				sperc1(DELTA(lookupcache_hits),
1249192762Srmacklem				    DELTA(lookupcache_misses)),
1250192762Srmacklem				sperc2(DELTA(biocache_reads),
1251192762Srmacklem				    DELTA(read_bios)),
1252192762Srmacklem				sperc2(DELTA(biocache_writes),
1253192762Srmacklem				    DELTA(write_bios)),
1254192762Srmacklem				sperc1(DELTA(accesscache_hits),
1255192762Srmacklem				    DELTA(accesscache_misses)),
1256192762Srmacklem				sperc2(DELTA(biocache_readdirs),
1257192762Srmacklem				    DELTA(readdir_bios))
1258192762Srmacklem			    );
1259192762Srmacklem		    }
1260192762Srmacklem		    printf("\n");
1261192762Srmacklem		}
1262306632Srmacklem
1263306632Srmacklem		if (serverOnly && newStats) {
1264306632Srmacklem			long double cur_secs, last_secs, etime;
1265306632Srmacklem			long double mbsec;
1266306632Srmacklem			long double kb_per_transfer;
1267306632Srmacklem			long double transfers_per_second;
1268306632Srmacklem			long double ms_per_transfer;
1269306632Srmacklem			uint64_t queue_len;
1270306632Srmacklem			long double busy_pct;
1271306632Srmacklem			int i;
1272306632Srmacklem
1273306632Srmacklem			cur_secs = ts.tv_sec +
1274306632Srmacklem			    ((long double)ts.tv_nsec / 1000000000);
1275306632Srmacklem			last_secs = lastts.tv_sec +
1276306632Srmacklem			    ((long double)lastts.tv_nsec / 1000000000);
1277306632Srmacklem			etime = cur_secs - last_secs;
1278306632Srmacklem
1279306632Srmacklem			compute_totals(&curtotal, &nfsstats);
1280306632Srmacklem
1281306632Srmacklem			for (i = 0; i < NUM_STAT_TYPES; i++) {
1282306632Srmacklem				compute_new_stats(&nfsstats, &lastst,
1283306632Srmacklem				    STAT_TYPE_TO_NFS(i), etime, &mbsec,
1284306632Srmacklem				    &kb_per_transfer,
1285306632Srmacklem				    &transfers_per_second,
1286306632Srmacklem				    &ms_per_transfer, &queue_len,
1287306632Srmacklem				    &busy_pct);
1288306632Srmacklem
1289306632Srmacklem				if (i == STAT_TYPE_COMMIT) {
1290306632Srmacklem					if (widemode == 0)
1291306632Srmacklem						continue;
1292306632Srmacklem
1293306632Srmacklem					printf("%2.0Lf %7.2Lf ",
1294306632Srmacklem					    transfers_per_second,
1295306632Srmacklem					    ms_per_transfer);
1296306632Srmacklem				} else {
1297306632Srmacklem					printf("%5.2Lf %5.0Lf %7.2Lf ",
1298306632Srmacklem					    kb_per_transfer,
1299306632Srmacklem					    transfers_per_second, mbsec);
1300306632Srmacklem					if (widemode)
1301306632Srmacklem						printf("%5.2Lf ",
1302306632Srmacklem						    ms_per_transfer);
1303306632Srmacklem				}
1304306632Srmacklem			}
1305306632Srmacklem
1306306632Srmacklem			compute_new_stats(&curtotal, &lasttotal, 0, etime,
1307306632Srmacklem			    &mbsec, &kb_per_transfer, &transfers_per_second,
1308306632Srmacklem			    &ms_per_transfer, &queue_len, &busy_pct);
1309306632Srmacklem
1310306632Srmacklem			printf("%5.2Lf %5.0Lf %7.2Lf %5.2Lf %3ju %3.0Lf\n",
1311306632Srmacklem			    kb_per_transfer, transfers_per_second, mbsec,
1312306632Srmacklem			    ms_per_transfer, queue_len, busy_pct);
1313306632Srmacklem		} else if (serverOnly) {
1314306632Srmacklem		    printf("%s %6ju %6ju %6ju %6ju %6ju %6ju %6ju %6ju",
1315192762Srmacklem			((clientOnly && serverOnly) ? "Server:" : ""),
1316306632Srmacklem			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_GETATTR]),
1317306632Srmacklem			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_LOOKUP]),
1318306632Srmacklem			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_READLINK]),
1319306632Srmacklem			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_READ]),
1320306632Srmacklem			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_WRITE]),
1321306632Srmacklem			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_RENAME]),
1322306632Srmacklem			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_ACCESS]),
1323306632Srmacklem			(uintmax_t)(DELTA(srvrpccnt[NFSV4OP_READDIR]) +
1324306632Srmacklem			DELTA(srvrpccnt[NFSV4OP_READDIRPLUS])));
1325192762Srmacklem		    printf("\n");
1326192762Srmacklem		}
1327306632Srmacklem		bcopy(&nfsstats, &lastst, sizeof(lastst));
1328306632Srmacklem		bcopy(&curtotal, &lasttotal, sizeof(lasttotal));
1329306632Srmacklem		lastts = ts;
1330192762Srmacklem		fflush(stdout);
1331192762Srmacklem		sleep(interval);
1332192762Srmacklem	}
1333192762Srmacklem	/*NOTREACHED*/
1334192762Srmacklem}
1335