nfsstat.c revision 281922
17055Sdg/*
221830Sjoerg * Copyright (c) 1983, 1989, 1993
321830Sjoerg *	The Regents of the University of California.  All rights reserved.
47055Sdg *
57055Sdg * This code is derived from software contributed to Berkeley by
67055Sdg * Rick Macklem at The University of Guelph.
77055Sdg *
87055Sdg * Redistribution and use in source and binary forms, with or without
97055Sdg * modification, are permitted provided that the following conditions
107055Sdg * are met:
117055Sdg * 1. Redistributions of source code must retain the above copyright
127055Sdg *    notice, this list of conditions and the following disclaimer.
137055Sdg * 2. Redistributions in binary form must reproduce the above copyright
147055Sdg *    notice, this list of conditions and the following disclaimer in the
157055Sdg *    documentation and/or other materials provided with the distribution.
167055Sdg * 4. Neither the name of the University nor the names of its contributors
177055Sdg *    may be used to endorse or promote products derived from this software
187055Sdg *    without specific prior written permission.
197055Sdg *
207055Sdg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
217055Sdg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
227055Sdg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
237055Sdg * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
247055Sdg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
257055Sdg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
267055Sdg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
277055Sdg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
287055Sdg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
297055Sdg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
307055Sdg * SUCH DAMAGE.
317055Sdg */
327055Sdg
337055Sdg#ifndef lint
347055Sdgstatic const char copyright[] =
357061Sdg"@(#) Copyright (c) 1983, 1989, 1993\n\
3650477Speter	The Regents of the University of California.  All rights reserved.\n";
377055Sdg#endif /* not lint */
387055Sdg
3932356Seivind#ifndef lint
4032350Seivind#if 0
4154263Sshinstatic char sccsid[] = "@(#)nfsstat.c	8.2 (Berkeley) 3/31/95";
4231742Seivind#endif
4331742Seivindstatic const char rcsid[] =
447055Sdg  "$FreeBSD: head/usr.bin/nfsstat/nfsstat.c 281922 2015-04-24 07:57:59Z trasz $";
457055Sdg#endif /* not lint */
467055Sdg
477055Sdg#include <sys/param.h>
4868315Sume#include <sys/module.h>
497055Sdg#include <sys/mount.h>
507055Sdg#include <sys/time.h>
517055Sdg#include <sys/sysctl.h>
527055Sdg#include <nfs/nfsproto.h>
537055Sdg#include <nfsclient/nfs.h>
547055Sdg#include <nfsserver/nfs.h>
557055Sdg#include <nfs/nfssvc.h>
567055Sdg
5754263Sshin#include <fs/nfs/nfsport.h>
587055Sdg
597055Sdg#include <signal.h>
6032350Seivind#include <fcntl.h>
617055Sdg#include <ctype.h>
6254263Sshin#include <errno.h>
6354263Sshin#include <kvm.h>
6454263Sshin#include <limits.h>
6521830Sjoerg#include <nlist.h>
667055Sdg#include <unistd.h>
6721830Sjoerg#include <stdio.h>
6821830Sjoerg#include <stdlib.h>
6921830Sjoerg#include <string.h>
707055Sdg#include <paths.h>
7111819Sjulian#include <err.h>
7221830Sjoerg
7311819Sjulianstatic int widemode = 0;
7411819Sjulianstatic int zflag = 0;
7511819Sjulianstatic int printtitle = 1;
767055Sdgstatic struct ext_nfsstats ext_nfsstats;
777055Sdgstatic int extra_output = 0;
787055Sdg
797055Sdgstatic void intpr(int, int);
807055Sdgstatic void printhdr(int, int);
817055Sdgstatic void usage(void);
827055Sdgstatic char *sperc1(int, int);
837055Sdgstatic char *sperc2(int, int);
847055Sdgstatic void exp_intpr(int, int);
8521830Sjoergstatic void exp_sidewaysintpr(u_int, int, int);
8621830Sjoerg
8721830Sjoerg#define DELTA(field)	(nfsstats.field - lastst.field)
8821830Sjoerg
8921830Sjoergint
9021830Sjoergmain(int argc, char **argv)
9121830Sjoerg{
9221830Sjoerg	u_int interval;
9321830Sjoerg	int clientOnly = -1;
9421830Sjoerg	int serverOnly = -1;
9521830Sjoerg	int ch;
9621830Sjoerg	char *memf, *nlistf;
9792725Salfred	int mntlen, i;
9893084Sbde	char buf[1024];
9968180Sume	struct statfs *mntbuf;
1007055Sdg	struct nfscl_dumpmntopts dumpmntopts;
1017055Sdg
1027055Sdg	interval = 0;
1037055Sdg	memf = nlistf = NULL;
1047055Sdg	while ((ch = getopt(argc, argv, "cesWM:mN:w:z")) != -1)
1057055Sdg		switch(ch) {
1067055Sdg		case 'M':
1077055Sdg			memf = optarg;
1087055Sdg			break;
10921830Sjoerg		case 'm':
11021830Sjoerg			/* Display mount options for NFS mount points. */
1117055Sdg			mntlen = getmntinfo(&mntbuf, MNT_NOWAIT);
11221830Sjoerg			for (i = 0; i < mntlen; i++) {
11321830Sjoerg				if (strcmp(mntbuf->f_fstypename, "nfs") == 0) {
1147055Sdg					dumpmntopts.ndmnt_fname =
1157055Sdg					    mntbuf->f_mntonname;
1167055Sdg					dumpmntopts.ndmnt_buf = buf;
1177055Sdg					dumpmntopts.ndmnt_blen = sizeof(buf);
1187055Sdg					if (nfssvc(NFSSVC_DUMPMNTOPTS,
1197055Sdg					    &dumpmntopts) >= 0)
1207055Sdg						printf("%s on %s\n%s\n",
1217055Sdg						    mntbuf->f_mntfromname,
1227055Sdg						    mntbuf->f_mntonname, buf);
1237055Sdg					else if (errno == EPERM)
12454799Sgreen						errx(1, "Only priviledged users"
12593367Smdodd						    " can use the -m option");
12654799Sgreen				}
1277055Sdg				mntbuf++;
1287055Sdg			}
1297055Sdg			exit(0);
13021830Sjoerg		case 'N':
13169152Sjlemon			nlistf = optarg;
13252248Smsmith			break;
13393367Smdodd		case 'W':
13493367Smdodd			widemode = 1;
1357055Sdg			break;
1367055Sdg		case 'w':
1377055Sdg			interval = atoi(optarg);
1387055Sdg			break;
13934961Sphk		case 'c':
14021830Sjoerg			clientOnly = 1;
14143305Sdillon			if (serverOnly < 0)
1427055Sdg				serverOnly = 0;
14343305Sdillon			break;
1447055Sdg		case 's':
14521830Sjoerg			serverOnly = 1;
1467055Sdg			if (clientOnly < 0)
1477055Sdg				clientOnly = 0;
1487055Sdg			break;
1497055Sdg		case 'z':
1507055Sdg			zflag = 1;
1517055Sdg			break;
1527055Sdg		case 'e':
1537055Sdg			extra_output = 1;
1547055Sdg			break;
1557055Sdg		case '?':
1567055Sdg		default:
1577055Sdg			usage();
1587055Sdg		}
1597055Sdg	argc -= optind;
16034961Sphk	argv += optind;
1617055Sdg
1627055Sdg#define	BACKWARD_COMPATIBILITY
16321830Sjoerg#ifdef	BACKWARD_COMPATIBILITY
1647055Sdg	if (*argv) {
1657055Sdg		interval = atoi(*argv);
1667055Sdg		if (*++argv) {
16721830Sjoerg			nlistf = *argv;
16821830Sjoerg			if (*++argv)
16984931Sfjoe				memf = *argv;
1707055Sdg		}
17121830Sjoerg	}
17221830Sjoerg#endif
17321830Sjoerg	if (modfind("nfscommon") < 0)
17421830Sjoerg		errx(1, "NFS client/server not loaded");
17521830Sjoerg
17621830Sjoerg	if (interval) {
1777055Sdg		exp_sidewaysintpr(interval, clientOnly, serverOnly);
17821830Sjoerg	} else {
1797055Sdg		if (extra_output != 0)
18054263Sshin			exp_intpr(clientOnly, serverOnly);
18154263Sshin		else
18254263Sshin			intpr(clientOnly, serverOnly);
18374093Sbmilekic	}
18454263Sshin	exit(0);
18554263Sshin}
18654263Sshin
18754263Sshin/*
18854263Sshin * Print a description of the nfs stats.
18911819Sjulian */
19011819Sjulianstatic void
19121830Sjoergintpr(int clientOnly, int serverOnly)
19211819Sjulian{
19311819Sjulian	int nfssvc_flag;
19411819Sjulian
19511819Sjulian	nfssvc_flag = NFSSVC_GETSTATS;
19621830Sjoerg	if (zflag != 0) {
19721830Sjoerg		if (clientOnly != 0)
19821830Sjoerg			nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
19936908Sjulian		if (serverOnly != 0)
20021830Sjoerg			nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
20121830Sjoerg	}
20221830Sjoerg	if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
20321830Sjoerg		err(1, "Can't get stats");
20430834Sjulian	if (clientOnly) {
20521830Sjoerg		printf("Client Info:\n");
20621830Sjoerg		printf("Rpc Counts:\n");
20721830Sjoerg		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
20821830Sjoerg			"Getattr", "Setattr", "Lookup", "Readlink", "Read",
20921830Sjoerg			"Write", "Create", "Remove");
21021830Sjoerg		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
21121830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_GETATTR],
21221830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_SETATTR],
21321830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
21421830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_READLINK],
21570254Sbmilekic			ext_nfsstats.rpccnt[NFSPROC_READ],
21621830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_WRITE],
21721830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_CREATE],
21821830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
21921830Sjoerg		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
22021830Sjoerg			"Rename", "Link", "Symlink", "Mkdir", "Rmdir",
22121830Sjoerg			"Readdir", "RdirPlus", "Access");
22221830Sjoerg		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
22321830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_RENAME],
22421830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_LINK],
22521830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
22621830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_MKDIR],
22721830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_RMDIR],
22821830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_READDIR],
22921830Sjoerg			ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
2307055Sdg			ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
2317055Sdg		printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
23221830Sjoerg			"Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
2337055Sdg		printf("%9d %9d %9d %9d %9d\n",
2347055Sdg			ext_nfsstats.rpccnt[NFSPROC_MKNOD],
2357055Sdg			ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
2367055Sdg			ext_nfsstats.rpccnt[NFSPROC_FSINFO],
2377055Sdg			ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
23852248Smsmith			ext_nfsstats.rpccnt[NFSPROC_COMMIT]);
23952248Smsmith		printf("Rpc Info:\n");
24052248Smsmith		printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
24152248Smsmith			"TimedOut", "Invalid", "X Replies", "Retries",
24252248Smsmith			"Requests");
24352248Smsmith		printf("%9d %9d %9d %9d %9d\n",
24452248Smsmith			ext_nfsstats.rpctimeouts,
24552248Smsmith			ext_nfsstats.rpcinvalid,
24652248Smsmith			ext_nfsstats.rpcunexpected,
2477055Sdg			ext_nfsstats.rpcretries,
2487055Sdg			ext_nfsstats.rpcrequests);
2497055Sdg		printf("Cache Info:\n");
25036992Sjulian		printf("%9.9s %9.9s %9.9s %9.9s",
2517055Sdg			"Attr Hits", "Misses", "Lkup Hits", "Misses");
2528384Sdg		printf(" %9.9s %9.9s %9.9s %9.9s\n",
2537055Sdg			"BioR Hits", "Misses", "BioW Hits", "Misses");
2547055Sdg		printf("%9d %9d %9d %9d",
2557055Sdg			ext_nfsstats.attrcache_hits,
2567055Sdg			ext_nfsstats.attrcache_misses,
2577055Sdg			ext_nfsstats.lookupcache_hits,
2587055Sdg			ext_nfsstats.lookupcache_misses);
2597055Sdg		printf(" %9d %9d %9d %9d\n",
2607055Sdg			ext_nfsstats.biocache_reads -
2617055Sdg			ext_nfsstats.read_bios,
2627055Sdg			ext_nfsstats.read_bios,
2637055Sdg			ext_nfsstats.biocache_writes -
2647055Sdg			ext_nfsstats.write_bios,
2657055Sdg			ext_nfsstats.write_bios);
2667055Sdg		printf("%9.9s %9.9s %9.9s %9.9s",
2677055Sdg			"BioRLHits", "Misses", "BioD Hits", "Misses");
2687055Sdg		printf(" %9.9s %9.9s %9.9s %9.9s\n", "DirE Hits", "Misses", "Accs Hits", "Misses");
2697055Sdg		printf("%9d %9d %9d %9d",
2707055Sdg			ext_nfsstats.biocache_readlinks -
2717055Sdg			ext_nfsstats.readlink_bios,
2727055Sdg			ext_nfsstats.readlink_bios,
2737055Sdg			ext_nfsstats.biocache_readdirs -
2747055Sdg			ext_nfsstats.readdir_bios,
2757055Sdg			ext_nfsstats.readdir_bios);
2767055Sdg		printf(" %9d %9d %9d %9d\n",
2777055Sdg			ext_nfsstats.direofcache_hits,
2787055Sdg			ext_nfsstats.direofcache_misses,
2797055Sdg			ext_nfsstats.accesscache_hits,
2807055Sdg			ext_nfsstats.accesscache_misses);
2817055Sdg	}
2827055Sdg	if (serverOnly) {
2837055Sdg		printf("\nServer Info:\n");
2847055Sdg		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
2857055Sdg			"Getattr", "Setattr", "Lookup", "Readlink", "Read",
2867055Sdg			"Write", "Create", "Remove");
2877055Sdg		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
2887055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
2897055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
2907055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
2917055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
2927055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_READ],
2937055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
2947055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_CREATE],
2957055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
2967055Sdg		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
2977055Sdg			"Rename", "Link", "Symlink", "Mkdir", "Rmdir",
2987055Sdg			"Readdir", "RdirPlus", "Access");
29993367Smdodd		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
3007055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
3017055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
3027055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
3037055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
3047055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
3057055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
3067055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
3078384Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
30821830Sjoerg		printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
3097055Sdg			"Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
31036908Sjulian		printf("%9d %9d %9d %9d %9d\n",
3117055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
3127055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
3137055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
3147055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
3157055Sdg			ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT]);
3167055Sdg		printf("Server Ret-Failed\n");
3177055Sdg		printf("%17d\n", ext_nfsstats.srvrpc_errs);
3187055Sdg		printf("Server Faults\n");
3197055Sdg		printf("%13d\n", ext_nfsstats.srv_errs);
3208384Sdg		printf("Server Cache Stats:\n");
3217055Sdg		printf("%9.9s %9.9s %9.9s %9.9s\n",
32252248Smsmith			"Inprog", "Idem", "Non-idem", "Misses");
32352248Smsmith		printf("%9d %9d %9d %9d\n",
32452248Smsmith			ext_nfsstats.srvcache_inproghits,
32552248Smsmith			ext_nfsstats.srvcache_idemdonehits,
32652248Smsmith			ext_nfsstats.srvcache_nonidemdonehits,
32752248Smsmith			ext_nfsstats.srvcache_misses);
32836908Sjulian		printf("Server Write Gathering:\n");
32936908Sjulian		printf("%9.9s %9.9s %9.9s\n",
33036908Sjulian			"WriteOps", "WriteRPC", "Opsaved");
33136908Sjulian		/*
33236908Sjulian		 * The new client doesn't do write gathering. It was
33336908Sjulian		 * only useful for NFSv2.
33436908Sjulian		 */
33536908Sjulian		printf("%9d %9d %9d\n",
33636908Sjulian			ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
33736992Sjulian			ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 0);
33836992Sjulian	}
33936908Sjulian}
34036908Sjulian
34136908Sjulianstatic void
34236908Sjulianprinthdr(int clientOnly, int serverOnly)
34360889Sarchie{
34436908Sjulian	printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
34536908Sjulian	    ((serverOnly && clientOnly) ? "        " : " "),
34636908Sjulian	    "GtAttr", "Lookup", "Rdlink", "Read", "Write", "Rename",
34760889Sarchie	    "Access", "Rddir");
34836908Sjulian	if (widemode && clientOnly) {
34936908Sjulian		printf(" Attr Lkup BioR BioW Accs BioD");
35036908Sjulian	}
35136908Sjulian	printf("\n");
35269152Sjlemon	fflush(stdout);
3537055Sdg}
3547055Sdg
3557055Sdgstatic void
3567055Sdgusage(void)
3577055Sdg{
3587055Sdg	(void)fprintf(stderr,
3597055Sdg	    "usage: nfsstat [-cemszW] [-M core] [-N system] [-w wait]\n");
3607055Sdg	exit(1);
3617055Sdg}
3627055Sdg
3637055Sdgstatic char SPBuf[64][8];
3647055Sdgstatic int SPIndex;
3657055Sdg
3667055Sdgstatic char *
3677055Sdgsperc1(int hits, int misses)
3687055Sdg{
3697055Sdg	char *p = SPBuf[SPIndex];
37093367Smdodd
3717055Sdg	if (hits + misses) {
3727055Sdg		sprintf(p, "%3d%%",
37393367Smdodd		    (int)(char)((quad_t)hits * 100 / (hits + misses)));
37493367Smdodd	} else {
3757055Sdg		sprintf(p, "   -");
3767055Sdg	}
3777055Sdg	SPIndex = (SPIndex + 1) & 63;
3787055Sdg	return(p);
3797055Sdg}
38034961Sphk
3817055Sdgstatic char *
38221830Sjoergsperc2(int ttl, int misses)
38321830Sjoerg{
38421830Sjoerg	char *p = SPBuf[SPIndex];
38521830Sjoerg
38621830Sjoerg	if (ttl) {
38721830Sjoerg		sprintf(p, "%3d%%",
3887055Sdg		    (int)(char)((quad_t)(ttl - misses) * 100 / ttl));
38923910Sjoerg	} else {
39023910Sjoerg		sprintf(p, "   -");
39123910Sjoerg	}
39223910Sjoerg	SPIndex = (SPIndex + 1) & 63;
39323910Sjoerg	return(p);
39421830Sjoerg}
3957055Sdg
39621830Sjoerg/*
39721830Sjoerg * Print a description of the nfs stats for the experimental client/server.
39821830Sjoerg */
39921830Sjoergstatic void
40021830Sjoergexp_intpr(int clientOnly, int serverOnly)
40121830Sjoerg{
40221830Sjoerg	int nfssvc_flag;
40321830Sjoerg
40421830Sjoerg	nfssvc_flag = NFSSVC_GETSTATS;
40521830Sjoerg	if (zflag != 0) {
4067055Sdg		if (clientOnly != 0)
4077055Sdg			nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
40854263Sshin		if (serverOnly != 0)
4097055Sdg			nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
4107055Sdg	}
41121830Sjoerg	if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
4127055Sdg		err(1, "Can't get stats");
4137055Sdg	if (clientOnly != 0) {
41421830Sjoerg		if (printtitle) {
41521830Sjoerg			printf("Client Info:\n");
41621830Sjoerg			printf("Rpc Counts:\n");
41721830Sjoerg			printf(
41821830Sjoerg			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
41921830Sjoerg			    , "Getattr", "Setattr", "Lookup", "Readlink",
42021830Sjoerg			    "Read", "Write", "Create", "Remove");
42121830Sjoerg		}
42221830Sjoerg		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
42321830Sjoerg		    ext_nfsstats.rpccnt[NFSPROC_GETATTR],
42421830Sjoerg		    ext_nfsstats.rpccnt[NFSPROC_SETATTR],
42521830Sjoerg		    ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
42621830Sjoerg		    ext_nfsstats.rpccnt[NFSPROC_READLINK],
42721830Sjoerg		    ext_nfsstats.rpccnt[NFSPROC_READ],
42821830Sjoerg		    ext_nfsstats.rpccnt[NFSPROC_WRITE],
42921830Sjoerg		    ext_nfsstats.rpccnt[NFSPROC_CREATE],
43021830Sjoerg		    ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
43121830Sjoerg		if (printtitle)
4327055Sdg			printf(
4337055Sdg			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
43421830Sjoerg			    , "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
4357055Sdg			    "Readdir", "RdirPlus", "Access");
43621830Sjoerg		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
4377055Sdg		    ext_nfsstats.rpccnt[NFSPROC_RENAME],
4387055Sdg		    ext_nfsstats.rpccnt[NFSPROC_LINK],
43936265Sdg		    ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
44036192Sdg		    ext_nfsstats.rpccnt[NFSPROC_MKDIR],
4417055Sdg		    ext_nfsstats.rpccnt[NFSPROC_RMDIR],
4427055Sdg		    ext_nfsstats.rpccnt[NFSPROC_READDIR],
4437055Sdg		    ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
4447055Sdg		    ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
4457055Sdg		if (printtitle)
44678295Sjlemon			printf(
44778295Sjlemon			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
4487055Sdg			    , "Mknod", "Fsstat", "Fsinfo", "PathConf",
4497055Sdg			    "Commit", "SetClId", "SetClIdCf", "Lock");
4507055Sdg		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
4517055Sdg		    ext_nfsstats.rpccnt[NFSPROC_MKNOD],
45254263Sshin		    ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
45354263Sshin		    ext_nfsstats.rpccnt[NFSPROC_FSINFO],
45454263Sshin		    ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
45554263Sshin		    ext_nfsstats.rpccnt[NFSPROC_COMMIT],
45654263Sshin		    ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID],
45754263Sshin		    ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM],
45821830Sjoerg		    ext_nfsstats.rpccnt[NFSPROC_LOCK]);
45921830Sjoerg		if (printtitle)
46021830Sjoerg			printf("%9.9s %9.9s %9.9s %9.9s\n",
46121830Sjoerg			    "LockT", "LockU", "Open", "OpenCfr");
46221830Sjoerg		printf("%9d %9d %9d %9d\n",
46321830Sjoerg		    ext_nfsstats.rpccnt[NFSPROC_LOCKT],
4647055Sdg		    ext_nfsstats.rpccnt[NFSPROC_LOCKU],
4657055Sdg		    ext_nfsstats.rpccnt[NFSPROC_OPEN],
4667055Sdg		    ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM]);
4677055Sdg		if (printtitle)
4687055Sdg			printf(
4697055Sdg			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
4707055Sdg			    , "OpenOwner", "Opens", "LockOwner",
47121830Sjoerg			    "Locks", "Delegs", "LocalOwn",
4727055Sdg			    "LocalOpen", "LocalLOwn");
4737055Sdg		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
4747055Sdg		    ext_nfsstats.clopenowners,
4757055Sdg		    ext_nfsstats.clopens,
47621830Sjoerg		    ext_nfsstats.cllockowners,
47721830Sjoerg		    ext_nfsstats.cllocks,
47821830Sjoerg		    ext_nfsstats.cldelegates,
47921830Sjoerg		    ext_nfsstats.cllocalopenowners,
48021830Sjoerg		    ext_nfsstats.cllocalopens,
48121830Sjoerg		    ext_nfsstats.cllocallockowners);
48221830Sjoerg		if (printtitle)
48321830Sjoerg			printf("%9.9s\n", "LocalLock");
48421830Sjoerg		printf("%9d\n", ext_nfsstats.cllocallocks);
48521830Sjoerg		if (printtitle) {
4867055Sdg			printf("Rpc Info:\n");
48721830Sjoerg			printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
4887055Sdg			    "TimedOut", "Invalid", "X Replies", "Retries",
4897055Sdg			    "Requests");
4907055Sdg		}
4917055Sdg		printf("%9d %9d %9d %9d %9d\n",
4927055Sdg		    ext_nfsstats.rpctimeouts,
4937055Sdg		    ext_nfsstats.rpcinvalid,
49421830Sjoerg		    ext_nfsstats.rpcunexpected,
4957055Sdg		    ext_nfsstats.rpcretries,
49621830Sjoerg		    ext_nfsstats.rpcrequests);
4977055Sdg		if (printtitle) {
4987055Sdg			printf("Cache Info:\n");
4997055Sdg			printf("%9.9s %9.9s %9.9s %9.9s",
5007055Sdg			    "Attr Hits", "Misses", "Lkup Hits", "Misses");
5017055Sdg			printf(" %9.9s %9.9s %9.9s %9.9s\n",
5027055Sdg			    "BioR Hits", "Misses", "BioW Hits", "Misses");
50369152Sjlemon		}
5047055Sdg		printf("%9d %9d %9d %9d",
5057055Sdg		    ext_nfsstats.attrcache_hits,
5067055Sdg		    ext_nfsstats.attrcache_misses,
5077055Sdg		    ext_nfsstats.lookupcache_hits,
50821830Sjoerg		    ext_nfsstats.lookupcache_misses);
50921830Sjoerg		printf(" %9d %9d %9d %9d\n",
51021830Sjoerg		    ext_nfsstats.biocache_reads - ext_nfsstats.read_bios,
51121830Sjoerg		    ext_nfsstats.read_bios,
5127055Sdg		    ext_nfsstats.biocache_writes - ext_nfsstats.write_bios,
5137055Sdg		    ext_nfsstats.write_bios);
51493367Smdodd		if (printtitle) {
5157055Sdg			printf("%9.9s %9.9s %9.9s %9.9s",
51693367Smdodd			    "BioRLHits", "Misses", "BioD Hits", "Misses");
51793367Smdodd			printf(" %9.9s %9.9s\n", "DirE Hits", "Misses");
5187055Sdg		}
5197055Sdg		printf("%9d %9d %9d %9d",
5207055Sdg		    ext_nfsstats.biocache_readlinks -
5217055Sdg		    ext_nfsstats.readlink_bios,
5227055Sdg		    ext_nfsstats.readlink_bios,
52368180Sume		    ext_nfsstats.biocache_readdirs -
52416063Sgpalmer		    ext_nfsstats.readdir_bios,
52521830Sjoerg		    ext_nfsstats.readdir_bios);
52621830Sjoerg		printf(" %9d %9d\n",
52721830Sjoerg		    ext_nfsstats.direofcache_hits,
52884931Sfjoe		    ext_nfsstats.direofcache_misses);
52921831Sjoerg	}
53083130Sjlemon	if (serverOnly != 0) {
53121831Sjoerg		if (printtitle) {
53221831Sjoerg			printf("\nServer Info:\n");
53321831Sjoerg			printf(
53421831Sjoerg			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
53521831Sjoerg			    , "Getattr", "Setattr", "Lookup", "Readlink",
53621830Sjoerg			    "Read", "Write", "Create", "Remove");
53771999Sphk		}
53821830Sjoerg		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
53921830Sjoerg		    ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
54021830Sjoerg		    ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
54121831Sjoerg		    ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
54221830Sjoerg		    ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
54321830Sjoerg		    ext_nfsstats.srvrpccnt[NFSV4OP_READ],
54421830Sjoerg		    ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
54521830Sjoerg		    ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE],
54621830Sjoerg		    ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
54721830Sjoerg		if (printtitle)
54821830Sjoerg			printf(
54921830Sjoerg			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
55021831Sjoerg			    , "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
5517055Sdg			    "Readdir", "RdirPlus", "Access");
55268180Sume		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
55368180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
55468180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
55568180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
55668180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
55768180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
55868180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
55968180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
56068180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
56168180Sume		if (printtitle)
56268180Sume			printf(
56368180Sume			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
56468180Sume			    , "Mknod", "Fsstat", "Fsinfo", "PathConf",
56568180Sume			    "Commit", "LookupP", "SetClId", "SetClIdCf");
56668180Sume		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
56768180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
56868180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
56968180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
57068180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
57168180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT],
57268180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP],
57368180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID],
57468180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]);
57568180Sume		if (printtitle)
57668180Sume			printf(
57768180Sume			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
57868180Sume			    , "Open", "OpenAttr", "OpenDwnGr", "OpenCfrm",
57968180Sume			    "DelePurge", "DeleRet", "GetFH", "Lock");
58068180Sume		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
58168180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_OPEN],
58268180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR],
58368180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE],
58468180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM],
58568180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE],
58668180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN],
58768180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_GETFH],
58868180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_LOCK]);
58968180Sume		if (printtitle)
59068180Sume			printf(
59168180Sume			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
59268180Sume			    , "LockT", "LockU", "Close", "Verify", "NVerify",
59368180Sume			    "PutFH", "PutPubFH", "PutRootFH");
59468180Sume		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
59568180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT],
59668180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU],
59768180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE],
59868180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY],
59968180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY],
60068180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH],
60168180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH],
60268180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH]);
60368180Sume		if (printtitle)
60468180Sume			printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
60568180Sume			    "Renew", "RestoreFH", "SaveFH", "Secinfo",
60668180Sume			    "RelLckOwn", "V4Create");
60768180Sume		printf("%9d %9d %9d %9d %9d %9d\n",
60868180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_RENEW],
60968180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH],
61068180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH],
61168180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO],
61268180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN],
61368180Sume		    ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]);
61468180Sume		if (printtitle) {
61568180Sume			printf("Server:\n");
61668180Sume			printf("%9.9s %9.9s %9.9s\n",
61768180Sume			    "Retfailed", "Faults", "Clients");
61868180Sume		}
61968180Sume		printf("%9d %9d %9d\n",
62068180Sume		    ext_nfsstats.srv_errs, ext_nfsstats.srvrpc_errs,
62168180Sume		    ext_nfsstats.srvclients);
62268180Sume		if (printtitle)
62368180Sume			printf("%9.9s %9.9s %9.9s %9.9s %9.9s \n",
62468180Sume			    "OpenOwner", "Opens", "LockOwner",
62568180Sume			    "Locks", "Delegs");
62668180Sume		printf("%9d %9d %9d %9d %9d \n",
62768180Sume		    ext_nfsstats.srvopenowners,
62868180Sume		    ext_nfsstats.srvopens,
62968180Sume		    ext_nfsstats.srvlockowners,
63068180Sume		    ext_nfsstats.srvlocks,
63168180Sume		    ext_nfsstats.srvdelegates);
63268180Sume		if (printtitle) {
63368180Sume			printf("Server Cache Stats:\n");
63468180Sume			printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
635			    "Inprog", "Idem", "Non-idem", "Misses",
636			    "CacheSize", "TCPPeak");
637		}
638		printf("%9d %9d %9d %9d %9d %9d\n",
639		    ext_nfsstats.srvcache_inproghits,
640		    ext_nfsstats.srvcache_idemdonehits,
641		    ext_nfsstats.srvcache_nonidemdonehits,
642		    ext_nfsstats.srvcache_misses,
643		    ext_nfsstats.srvcache_size,
644		    ext_nfsstats.srvcache_tcppeak);
645	}
646}
647
648/*
649 * Print a running summary of nfs statistics for the experimental client and/or
650 * server.
651 * Repeat display every interval seconds, showing statistics
652 * collected over that interval.  Assumes that interval is non-zero.
653 * First line printed at top of screen is always cumulative.
654 */
655static void
656exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly)
657{
658	struct ext_nfsstats nfsstats, lastst, *ext_nfsstatsp;
659	int hdrcnt = 1;
660
661	ext_nfsstatsp = &lastst;
662	if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0)
663		err(1, "Can't get stats");
664	sleep(interval);
665
666	for (;;) {
667		ext_nfsstatsp = &nfsstats;
668		if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0)
669			err(1, "Can't get stats");
670
671		if (--hdrcnt == 0) {
672			printhdr(clientOnly, serverOnly);
673			if (clientOnly && serverOnly)
674				hdrcnt = 10;
675			else
676				hdrcnt = 20;
677		}
678		if (clientOnly) {
679		    printf("%s %6d %6d %6d %6d %6d %6d %6d %6d",
680			((clientOnly && serverOnly) ? "Client:" : ""),
681			DELTA(rpccnt[NFSPROC_GETATTR]),
682			DELTA(rpccnt[NFSPROC_LOOKUP]),
683			DELTA(rpccnt[NFSPROC_READLINK]),
684			DELTA(rpccnt[NFSPROC_READ]),
685			DELTA(rpccnt[NFSPROC_WRITE]),
686			DELTA(rpccnt[NFSPROC_RENAME]),
687			DELTA(rpccnt[NFSPROC_ACCESS]),
688			DELTA(rpccnt[NFSPROC_READDIR]) +
689			DELTA(rpccnt[NFSPROC_READDIRPLUS])
690		    );
691		    if (widemode) {
692			    printf(" %s %s %s %s %s %s",
693				sperc1(DELTA(attrcache_hits),
694				    DELTA(attrcache_misses)),
695				sperc1(DELTA(lookupcache_hits),
696				    DELTA(lookupcache_misses)),
697				sperc2(DELTA(biocache_reads),
698				    DELTA(read_bios)),
699				sperc2(DELTA(biocache_writes),
700				    DELTA(write_bios)),
701				sperc1(DELTA(accesscache_hits),
702				    DELTA(accesscache_misses)),
703				sperc2(DELTA(biocache_readdirs),
704				    DELTA(readdir_bios))
705			    );
706		    }
707		    printf("\n");
708		}
709		if (serverOnly) {
710		    printf("%s %6d %6d %6d %6d %6d %6d %6d %6d",
711			((clientOnly && serverOnly) ? "Server:" : ""),
712			DELTA(srvrpccnt[NFSV4OP_GETATTR]),
713			DELTA(srvrpccnt[NFSV4OP_LOOKUP]),
714			DELTA(srvrpccnt[NFSV4OP_READLINK]),
715			DELTA(srvrpccnt[NFSV4OP_READ]),
716			DELTA(srvrpccnt[NFSV4OP_WRITE]),
717			DELTA(srvrpccnt[NFSV4OP_RENAME]),
718			DELTA(srvrpccnt[NFSV4OP_ACCESS]),
719			DELTA(srvrpccnt[NFSV4OP_READDIR]) +
720			DELTA(srvrpccnt[NFSV4OP_READDIRPLUS]));
721		    printf("\n");
722		}
723		lastst = nfsstats;
724		fflush(stdout);
725		sleep(interval);
726	}
727	/*NOTREACHED*/
728}
729