nfsstat.c revision 172759
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 * 3. All advertising materials mentioning features or use of this software 171590Srgrimes * must display the following acknowledgement: 181590Srgrimes * This product includes software developed by the University of 191590Srgrimes * California, Berkeley and its contributors. 201590Srgrimes * 4. Neither the name of the University nor the names of its contributors 211590Srgrimes * may be used to endorse or promote products derived from this software 221590Srgrimes * without specific prior written permission. 231590Srgrimes * 241590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341590Srgrimes * SUCH DAMAGE. 351590Srgrimes */ 361590Srgrimes 371590Srgrimes#ifndef lint 381590Srgrimesstatic char copyright[] = 391590Srgrimes"@(#) Copyright (c) 1983, 1989, 1993\n\ 401590Srgrimes The Regents of the University of California. All rights reserved.\n"; 411590Srgrimes#endif /* not lint */ 421590Srgrimes 431590Srgrimes#ifndef lint 4432649Sbde#if 0 4532649Sbdestatic char sccsid[] = "@(#)nfsstat.c 8.2 (Berkeley) 3/31/95"; 4632649Sbde#endif 473819Swollmanstatic const char rcsid[] = 4850477Speter "$FreeBSD: head/usr.bin/nfsstat/nfsstat.c 172759 2007-10-18 16:38:07Z jhb $"; 491590Srgrimes#endif /* not lint */ 501590Srgrimes 511590Srgrimes#include <sys/param.h> 521590Srgrimes#include <sys/mount.h> 5311936Sphk#include <sys/time.h> 543819Swollman#include <sys/sysctl.h> 559336Sdfr#include <nfs/rpcv2.h> 569336Sdfr#include <nfs/nfsproto.h> 5783653Speter#include <nfsclient/nfs.h> 5883653Speter#include <nfsserver/nfs.h> 591590Srgrimes#include <signal.h> 601590Srgrimes#include <fcntl.h> 611590Srgrimes#include <ctype.h> 621590Srgrimes#include <errno.h> 631590Srgrimes#include <kvm.h> 6477207Stmm#include <limits.h> 651590Srgrimes#include <nlist.h> 661590Srgrimes#include <unistd.h> 671590Srgrimes#include <stdio.h> 681590Srgrimes#include <stdlib.h> 691590Srgrimes#include <string.h> 701590Srgrimes#include <paths.h> 713819Swollman#include <err.h> 721590Srgrimes 731590Srgrimesstruct nlist nl[] = { 741590Srgrimes#define N_NFSSTAT 0 7583653Speter { "nfsstats" }, 7683653Speter#define N_NFSRVSTAT 1 7783653Speter { "nfsrvstats" }, 781590Srgrimes "", 791590Srgrimes}; 801590Srgrimeskvm_t *kd; 811590Srgrimes 823819Swollmanstatic int deadkernel = 0; 8352493Sdillonstatic int widemode = 0; 84172759Sjhbstatic int zflag = 0; 851590Srgrimes 8692921Simpvoid intpr(int, int); 8792921Simpvoid printhdr(int, int); 8892921Simpvoid sidewaysintpr(u_int, int, int); 8992921Simpvoid usage(void); 9092921Simpchar *sperc1(int, int); 9192921Simpchar *sperc2(int, int); 923819Swollman 9352493Sdillon#define DELTA(field) (nfsstats.field - lastst.field) 9452493Sdillon 95131990Sstefanfint 96172759Sjhbmain(int argc, char **argv) 971590Srgrimes{ 981590Srgrimes u_int interval; 9952493Sdillon int clientOnly = -1; 10052493Sdillon int serverOnly = -1; 1011590Srgrimes int ch; 1021590Srgrimes char *memf, *nlistf; 10377207Stmm char errbuf[_POSIX2_LINE_MAX]; 1041590Srgrimes 1051590Srgrimes interval = 0; 1061590Srgrimes memf = nlistf = NULL; 107172759Sjhb while ((ch = getopt(argc, argv, "csWM:N:w:z")) != -1) 1081590Srgrimes switch(ch) { 1091590Srgrimes case 'M': 1101590Srgrimes memf = optarg; 1111590Srgrimes break; 1121590Srgrimes case 'N': 1131590Srgrimes nlistf = optarg; 1141590Srgrimes break; 11552493Sdillon case 'W': 11652493Sdillon widemode = 1; 11752493Sdillon break; 1181590Srgrimes case 'w': 1191590Srgrimes interval = atoi(optarg); 1201590Srgrimes break; 12152493Sdillon case 'c': 12252493Sdillon clientOnly = 1; 12352493Sdillon if (serverOnly < 0) 12452493Sdillon serverOnly = 0; 12552493Sdillon break; 12652493Sdillon case 's': 12752493Sdillon serverOnly = 1; 12852493Sdillon if (clientOnly < 0) 12952493Sdillon clientOnly = 0; 13052493Sdillon break; 131172759Sjhb case 'z': 132172759Sjhb zflag = 1; 133172759Sjhb break; 1341590Srgrimes case '?': 1351590Srgrimes default: 1361590Srgrimes usage(); 1371590Srgrimes } 1381590Srgrimes argc -= optind; 1391590Srgrimes argv += optind; 1401590Srgrimes 1411590Srgrimes#define BACKWARD_COMPATIBILITY 1421590Srgrimes#ifdef BACKWARD_COMPATIBILITY 1431590Srgrimes if (*argv) { 1441590Srgrimes interval = atoi(*argv); 1451590Srgrimes if (*++argv) { 1461590Srgrimes nlistf = *argv; 1471590Srgrimes if (*++argv) 1481590Srgrimes memf = *argv; 1491590Srgrimes } 1501590Srgrimes } 1511590Srgrimes#endif 1523819Swollman if (nlistf != NULL || memf != NULL) { 1533819Swollman deadkernel = 1; 1541590Srgrimes 1553819Swollman if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, 1563819Swollman errbuf)) == 0) { 1573819Swollman errx(1, "kvm_openfiles: %s", errbuf); 1583819Swollman } 1593819Swollman if (kvm_nlist(kd, nl) != 0) { 1603819Swollman errx(1, "kvm_nlist: can't get names"); 1613819Swollman } 1621590Srgrimes } 1631590Srgrimes 1641590Srgrimes if (interval) 16552493Sdillon sidewaysintpr(interval, clientOnly, serverOnly); 1661590Srgrimes else 16752493Sdillon intpr(clientOnly, serverOnly); 1681590Srgrimes exit(0); 1691590Srgrimes} 1701590Srgrimes 1711590Srgrimes/* 1723819Swollman * Read the nfs stats using sysctl(3) for live kernels, or kvm_read 1733819Swollman * for dead ones. 1743819Swollman */ 1753819Swollmanvoid 176172759Sjhbreadstats(struct nfsstats **stp, struct nfsrvstats **srvstp, int zero) 1773819Swollman{ 178172759Sjhb union { 179172759Sjhb struct nfsstats client; 180172759Sjhb struct nfsrvstats server; 181172759Sjhb } zerostat; 18283653Speter size_t buflen; 18383653Speter 18483653Speter if (deadkernel) { 185172759Sjhb if (*stp != NULL && kvm_read(kd, (u_long)nl[N_NFSSTAT].n_value, 186172759Sjhb *stp, sizeof(struct nfsstats)) < 0) { 18783653Speter *stp = NULL; 1883819Swollman } 189172759Sjhb if (*srvstp != NULL && kvm_read(kd, 190172759Sjhb (u_long)nl[N_NFSRVSTAT].n_value, *srvstp, 191172759Sjhb sizeof(struct nfsrvstats)) < 0) { 19283653Speter *srvstp = NULL; 19383653Speter } 1943819Swollman } else { 195172759Sjhb if (zero) 196172759Sjhb bzero(&zerostat, sizeof(zerostat)); 19783653Speter buflen = sizeof(struct nfsstats); 198172759Sjhb if (*stp != NULL && sysctlbyname("vfs.nfs.nfsstats", *stp, 199172759Sjhb &buflen, zero ? &zerostat : NULL, zero ? buflen : 0) < 0) { 200172759Sjhb if (errno != ENOENT) 201172759Sjhb err(1, "sysctl: vfs.nfs.nfsstats"); 20283653Speter *stp = NULL; 2033819Swollman } 20483653Speter buflen = sizeof(struct nfsrvstats); 205172759Sjhb if (*srvstp != NULL && sysctlbyname("vfs.nfsrv.nfsrvstats", 206172759Sjhb *srvstp, &buflen, zero ? &zerostat : NULL, 207172759Sjhb zero ? buflen : 0) < 0) { 208172759Sjhb if (errno != ENOENT) 209172759Sjhb err(1, "sysctl: vfs.nfsrv.nfsrvstats"); 21083653Speter *srvstp = NULL; 21183653Speter } 2123819Swollman } 2133819Swollman} 2143819Swollman 2153819Swollman/* 2161590Srgrimes * Print a description of the nfs stats. 2171590Srgrimes */ 2181590Srgrimesvoid 21952493Sdillonintpr(int clientOnly, int serverOnly) 2201590Srgrimes{ 22183653Speter struct nfsstats nfsstats, *nfsstatsp; 22283653Speter struct nfsrvstats nfsrvstats, *nfsrvstatsp; 2231590Srgrimes 224172759Sjhb /* 225172759Sjhb * Only read the stats we are going to display to avoid zeroing 226172759Sjhb * stats the user didn't request. 227172759Sjhb */ 228172759Sjhb if (clientOnly) 229172759Sjhb nfsstatsp = &nfsstats; 230172759Sjhb else 231172759Sjhb nfsstatsp = NULL; 232172759Sjhb if (serverOnly) 233172759Sjhb nfsrvstatsp = &nfsrvstats; 234172759Sjhb else 235172759Sjhb nfsrvstatsp = NULL; 2363819Swollman 237172759Sjhb readstats(&nfsstatsp, &nfsrvstatsp, zflag); 23883653Speter 23983653Speter if (clientOnly && !nfsstatsp) { 24083653Speter printf("Client not present!\n"); 24183653Speter clientOnly = 0; 24283653Speter } 24352493Sdillon if (clientOnly) { 24452493Sdillon printf("Client Info:\n"); 24552493Sdillon printf("Rpc Counts:\n"); 24652493Sdillon printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 24752493Sdillon "Getattr", "Setattr", "Lookup", "Readlink", "Read", 24852493Sdillon "Write", "Create", "Remove"); 24952493Sdillon printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 25052493Sdillon nfsstats.rpccnt[NFSPROC_GETATTR], 25152493Sdillon nfsstats.rpccnt[NFSPROC_SETATTR], 25252493Sdillon nfsstats.rpccnt[NFSPROC_LOOKUP], 25352493Sdillon nfsstats.rpccnt[NFSPROC_READLINK], 25452493Sdillon nfsstats.rpccnt[NFSPROC_READ], 25552493Sdillon nfsstats.rpccnt[NFSPROC_WRITE], 25652493Sdillon nfsstats.rpccnt[NFSPROC_CREATE], 25752493Sdillon nfsstats.rpccnt[NFSPROC_REMOVE]); 25852493Sdillon printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 25952493Sdillon "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 26052493Sdillon "Readdir", "RdirPlus", "Access"); 26152493Sdillon printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 26252493Sdillon nfsstats.rpccnt[NFSPROC_RENAME], 26352493Sdillon nfsstats.rpccnt[NFSPROC_LINK], 26452493Sdillon nfsstats.rpccnt[NFSPROC_SYMLINK], 26552493Sdillon nfsstats.rpccnt[NFSPROC_MKDIR], 26652493Sdillon nfsstats.rpccnt[NFSPROC_RMDIR], 26752493Sdillon nfsstats.rpccnt[NFSPROC_READDIR], 26852493Sdillon nfsstats.rpccnt[NFSPROC_READDIRPLUS], 26952493Sdillon nfsstats.rpccnt[NFSPROC_ACCESS]); 27083653Speter printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 27183653Speter "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit"); 27283653Speter printf("%9d %9d %9d %9d %9d\n", 27352493Sdillon nfsstats.rpccnt[NFSPROC_MKNOD], 27452493Sdillon nfsstats.rpccnt[NFSPROC_FSSTAT], 27552493Sdillon nfsstats.rpccnt[NFSPROC_FSINFO], 27652493Sdillon nfsstats.rpccnt[NFSPROC_PATHCONF], 27783653Speter nfsstats.rpccnt[NFSPROC_COMMIT]); 27852493Sdillon printf("Rpc Info:\n"); 27952493Sdillon printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 28052493Sdillon "TimedOut", "Invalid", "X Replies", "Retries", 28152493Sdillon "Requests"); 28252493Sdillon printf("%9d %9d %9d %9d %9d\n", 28352493Sdillon nfsstats.rpctimeouts, 28452493Sdillon nfsstats.rpcinvalid, 28552493Sdillon nfsstats.rpcunexpected, 28652493Sdillon nfsstats.rpcretries, 28752493Sdillon nfsstats.rpcrequests); 28852493Sdillon printf("Cache Info:\n"); 28952493Sdillon printf("%9.9s %9.9s %9.9s %9.9s", 29052493Sdillon "Attr Hits", "Misses", "Lkup Hits", "Misses"); 29152493Sdillon printf(" %9.9s %9.9s %9.9s %9.9s\n", 29252493Sdillon "BioR Hits", "Misses", "BioW Hits", "Misses"); 29352493Sdillon printf("%9d %9d %9d %9d", 29452493Sdillon nfsstats.attrcache_hits, nfsstats.attrcache_misses, 29552493Sdillon nfsstats.lookupcache_hits, nfsstats.lookupcache_misses); 29652493Sdillon printf(" %9d %9d %9d %9d\n", 29752493Sdillon nfsstats.biocache_reads-nfsstats.read_bios, 29852493Sdillon nfsstats.read_bios, 29952493Sdillon nfsstats.biocache_writes-nfsstats.write_bios, 30052493Sdillon nfsstats.write_bios); 30152493Sdillon printf("%9.9s %9.9s %9.9s %9.9s", 30252493Sdillon "BioRLHits", "Misses", "BioD Hits", "Misses"); 30352493Sdillon printf(" %9.9s %9.9s\n", "DirE Hits", "Misses"); 30452493Sdillon printf("%9d %9d %9d %9d", 30552493Sdillon nfsstats.biocache_readlinks-nfsstats.readlink_bios, 30652493Sdillon nfsstats.readlink_bios, 30752493Sdillon nfsstats.biocache_readdirs-nfsstats.readdir_bios, 30852493Sdillon nfsstats.readdir_bios); 30952493Sdillon printf(" %9d %9d\n", 31052493Sdillon nfsstats.direofcache_hits, nfsstats.direofcache_misses); 31152493Sdillon } 31283653Speter if (serverOnly && !nfsrvstatsp) { 31383653Speter printf("Server not present!\n"); 31483653Speter serverOnly = 0; 31583653Speter } 31652493Sdillon if (serverOnly) { 31752493Sdillon printf("\nServer Info:\n"); 31852493Sdillon printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 31952493Sdillon "Getattr", "Setattr", "Lookup", "Readlink", "Read", 32052493Sdillon "Write", "Create", "Remove"); 32152493Sdillon printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 32283653Speter nfsrvstats.srvrpccnt[NFSPROC_GETATTR], 32383653Speter nfsrvstats.srvrpccnt[NFSPROC_SETATTR], 32483653Speter nfsrvstats.srvrpccnt[NFSPROC_LOOKUP], 32583653Speter nfsrvstats.srvrpccnt[NFSPROC_READLINK], 32683653Speter nfsrvstats.srvrpccnt[NFSPROC_READ], 32783653Speter nfsrvstats.srvrpccnt[NFSPROC_WRITE], 32883653Speter nfsrvstats.srvrpccnt[NFSPROC_CREATE], 32983653Speter nfsrvstats.srvrpccnt[NFSPROC_REMOVE]); 33052493Sdillon printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 33152493Sdillon "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 33252493Sdillon "Readdir", "RdirPlus", "Access"); 33352493Sdillon printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 33483653Speter nfsrvstats.srvrpccnt[NFSPROC_RENAME], 33583653Speter nfsrvstats.srvrpccnt[NFSPROC_LINK], 33683653Speter nfsrvstats.srvrpccnt[NFSPROC_SYMLINK], 33783653Speter nfsrvstats.srvrpccnt[NFSPROC_MKDIR], 33883653Speter nfsrvstats.srvrpccnt[NFSPROC_RMDIR], 33983653Speter nfsrvstats.srvrpccnt[NFSPROC_READDIR], 34083653Speter nfsrvstats.srvrpccnt[NFSPROC_READDIRPLUS], 34183653Speter nfsrvstats.srvrpccnt[NFSPROC_ACCESS]); 34283653Speter printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 34383653Speter "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit"); 34483653Speter printf("%9d %9d %9d %9d %9d\n", 34583653Speter nfsrvstats.srvrpccnt[NFSPROC_MKNOD], 34683653Speter nfsrvstats.srvrpccnt[NFSPROC_FSSTAT], 34783653Speter nfsrvstats.srvrpccnt[NFSPROC_FSINFO], 34883653Speter nfsrvstats.srvrpccnt[NFSPROC_PATHCONF], 34983653Speter nfsrvstats.srvrpccnt[NFSPROC_COMMIT]); 35052493Sdillon printf("Server Ret-Failed\n"); 35183653Speter printf("%17d\n", nfsrvstats.srvrpc_errs); 35252493Sdillon printf("Server Faults\n"); 35383653Speter printf("%13d\n", nfsrvstats.srv_errs); 35452493Sdillon printf("Server Cache Stats:\n"); 35552493Sdillon printf("%9.9s %9.9s %9.9s %9.9s\n", 35652493Sdillon "Inprog", "Idem", "Non-idem", "Misses"); 35752493Sdillon printf("%9d %9d %9d %9d\n", 35883653Speter nfsrvstats.srvcache_inproghits, 35983653Speter nfsrvstats.srvcache_idemdonehits, 36083653Speter nfsrvstats.srvcache_nonidemdonehits, 36183653Speter nfsrvstats.srvcache_misses); 36252493Sdillon printf("Server Write Gathering:\n"); 36352493Sdillon printf("%9.9s %9.9s %9.9s\n", 36452493Sdillon "WriteOps", "WriteRPC", "Opsaved"); 36552493Sdillon printf("%9d %9d %9d\n", 36683653Speter nfsrvstats.srvvop_writes, 36783653Speter nfsrvstats.srvrpccnt[NFSPROC_WRITE], 36883653Speter nfsrvstats.srvrpccnt[NFSPROC_WRITE] - 36983653Speter nfsrvstats.srvvop_writes); 37052493Sdillon } 3711590Srgrimes} 3721590Srgrimes 3731590Srgrimesu_char signalled; /* set if alarm goes off "early" */ 3741590Srgrimes 3751590Srgrimes/* 3761590Srgrimes * Print a running summary of nfs statistics. 3771590Srgrimes * Repeat display every interval seconds, showing statistics 3781590Srgrimes * collected over that interval. Assumes that interval is non-zero. 3791590Srgrimes * First line printed at top of screen is always cumulative. 3801590Srgrimes */ 3811590Srgrimesvoid 38252493Sdillonsidewaysintpr(u_int interval, int clientOnly, int serverOnly) 3831590Srgrimes{ 38483653Speter struct nfsstats nfsstats, lastst, *nfsstatsp; 38583653Speter struct nfsrvstats nfsrvstats, lastsrvst, *nfsrvstatsp; 38652493Sdillon int hdrcnt = 1; 3871590Srgrimes 38883653Speter nfsstatsp = &lastst; 38983653Speter nfsrvstatsp = &lastsrvst; 390172759Sjhb readstats(&nfsstatsp, &nfsrvstatsp, 0); 39183653Speter if (clientOnly && !nfsstatsp) { 39283653Speter printf("Client not present!\n"); 39383653Speter clientOnly = 0; 39483653Speter } 39583653Speter if (serverOnly && !nfsrvstatsp) { 39683653Speter printf("Server not present!\n"); 39783653Speter serverOnly = 0; 39883653Speter } 39952493Sdillon sleep(interval); 4001590Srgrimes 40152493Sdillon for (;;) { 40283653Speter nfsstatsp = &nfsstats; 40383653Speter nfsrvstatsp = &nfsrvstats; 404172759Sjhb readstats(&nfsstatsp, &nfsrvstatsp, 0); 40552493Sdillon 40652493Sdillon if (--hdrcnt == 0) { 40752493Sdillon printhdr(clientOnly, serverOnly); 40852493Sdillon if (clientOnly && serverOnly) 40952493Sdillon hdrcnt = 10; 41052493Sdillon else 41152493Sdillon hdrcnt = 20; 4121590Srgrimes } 41352493Sdillon if (clientOnly) { 41452493Sdillon printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 41552493Sdillon ((clientOnly && serverOnly) ? "Client:" : ""), 41652493Sdillon DELTA(attrcache_hits) + DELTA(attrcache_misses), 41752493Sdillon DELTA(lookupcache_hits) + DELTA(lookupcache_misses), 41852493Sdillon DELTA(biocache_readlinks), 41952493Sdillon DELTA(biocache_reads), 42052493Sdillon DELTA(biocache_writes), 42152493Sdillon nfsstats.rpccnt[NFSPROC_RENAME]-lastst.rpccnt[NFSPROC_RENAME], 42252493Sdillon DELTA(accesscache_hits) + DELTA(accesscache_misses), 42352493Sdillon DELTA(biocache_readdirs) 42452493Sdillon ); 42552493Sdillon if (widemode) { 42652493Sdillon printf(" %s %s %s %s %s %s", 42752493Sdillon sperc1(DELTA(attrcache_hits), 42852493Sdillon DELTA(attrcache_misses)), 42952493Sdillon sperc1(DELTA(lookupcache_hits), 43052493Sdillon DELTA(lookupcache_misses)), 43152493Sdillon sperc2(DELTA(biocache_reads), 43252493Sdillon DELTA(read_bios)), 43352493Sdillon sperc2(DELTA(biocache_writes), 43452493Sdillon DELTA(write_bios)), 43552493Sdillon sperc1(DELTA(accesscache_hits), 43652493Sdillon DELTA(accesscache_misses)), 43752493Sdillon sperc2(DELTA(biocache_readdirs), 43852493Sdillon DELTA(readdir_bios)) 43952493Sdillon ); 44052493Sdillon } 44152493Sdillon printf("\n"); 44283653Speter lastst = nfsstats; 44352493Sdillon } 44452493Sdillon if (serverOnly) { 44552493Sdillon printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 44652493Sdillon ((clientOnly && serverOnly) ? "Server:" : ""), 44783653Speter nfsrvstats.srvrpccnt[NFSPROC_GETATTR]-lastsrvst.srvrpccnt[NFSPROC_GETATTR], 44883653Speter nfsrvstats.srvrpccnt[NFSPROC_LOOKUP]-lastsrvst.srvrpccnt[NFSPROC_LOOKUP], 44983653Speter nfsrvstats.srvrpccnt[NFSPROC_READLINK]-lastsrvst.srvrpccnt[NFSPROC_READLINK], 45083653Speter nfsrvstats.srvrpccnt[NFSPROC_READ]-lastsrvst.srvrpccnt[NFSPROC_READ], 45183653Speter nfsrvstats.srvrpccnt[NFSPROC_WRITE]-lastsrvst.srvrpccnt[NFSPROC_WRITE], 45283653Speter nfsrvstats.srvrpccnt[NFSPROC_RENAME]-lastsrvst.srvrpccnt[NFSPROC_RENAME], 45383653Speter nfsrvstats.srvrpccnt[NFSPROC_ACCESS]-lastsrvst.srvrpccnt[NFSPROC_ACCESS], 45483653Speter (nfsrvstats.srvrpccnt[NFSPROC_READDIR]-lastsrvst.srvrpccnt[NFSPROC_READDIR]) 45583653Speter +(nfsrvstats.srvrpccnt[NFSPROC_READDIRPLUS]-lastsrvst.srvrpccnt[NFSPROC_READDIRPLUS])); 45652493Sdillon printf("\n"); 45783653Speter lastsrvst = nfsrvstats; 45852493Sdillon } 4591590Srgrimes fflush(stdout); 46052493Sdillon sleep(interval); 4611590Srgrimes } 4621590Srgrimes /*NOTREACHED*/ 4631590Srgrimes} 4641590Srgrimes 4651590Srgrimesvoid 46652493Sdillonprinthdr(int clientOnly, int serverOnly) 4671590Srgrimes{ 46852493Sdillon printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s", 46952493Sdillon ((serverOnly && clientOnly) ? " " : " "), 47052493Sdillon "GtAttr", "Lookup", "Rdlink", "Read", "Write", "Rename", 47152493Sdillon "Access", "Rddir"); 47252493Sdillon if (widemode && clientOnly) { 47352493Sdillon printf(" Attr Lkup BioR BioW Accs BioD"); 47452493Sdillon } 47552493Sdillon printf("\n"); 4761590Srgrimes fflush(stdout); 4771590Srgrimes} 4781590Srgrimes 4791590Srgrimesvoid 480172759Sjhbusage(void) 4811590Srgrimes{ 4821590Srgrimes (void)fprintf(stderr, 483172759Sjhb "usage: nfsstat [-cszW] [-M core] [-N system] [-w interval]\n"); 4841590Srgrimes exit(1); 4851590Srgrimes} 48652493Sdillon 48752493Sdillonstatic char SPBuf[64][8]; 48852493Sdillonstatic int SPIndex; 48952493Sdillon 49052493Sdillonchar * 49152493Sdillonsperc1(int hits, int misses) 49252493Sdillon{ 49352493Sdillon char *p = SPBuf[SPIndex]; 49452493Sdillon 49552493Sdillon if (hits + misses) { 49652493Sdillon sprintf(p, "%3d%%", 49752493Sdillon (int)(char)((quad_t)hits * 100 / (hits + misses))); 49852493Sdillon } else { 49952493Sdillon sprintf(p, " -"); 50052493Sdillon } 50152493Sdillon SPIndex = (SPIndex + 1) & 63; 50252493Sdillon return(p); 50352493Sdillon} 50452493Sdillon 50552493Sdillonchar * 50652493Sdillonsperc2(int ttl, int misses) 50752493Sdillon{ 50852493Sdillon char *p = SPBuf[SPIndex]; 50952493Sdillon 51052493Sdillon if (ttl) { 51152493Sdillon sprintf(p, "%3d%%", 51252493Sdillon (int)(char)((quad_t)(ttl - misses) * 100 / ttl)); 51352493Sdillon } else { 51452493Sdillon sprintf(p, " -"); 51552493Sdillon } 51652493Sdillon SPIndex = (SPIndex + 1) & 63; 51752493Sdillon return(p); 51852493Sdillon} 51952493Sdillon 520