nfsstat.c revision 14516
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 443819Swollman/*static char sccsid[] = "From: @(#)nfsstat.c 8.1 (Berkeley) 6/6/93";*/ 453819Swollmanstatic const char rcsid[] = 4614516Shsu "$Id: nfsstat.c,v 1.5 1995/10/30 15:44:44 phk Exp $"; 471590Srgrimes#endif /* not lint */ 481590Srgrimes 491590Srgrimes#include <sys/param.h> 501590Srgrimes#include <sys/mount.h> 5111936Sphk#include <sys/time.h> 523819Swollman#include <sys/sysctl.h> 539336Sdfr#include <nfs/rpcv2.h> 549336Sdfr#include <nfs/nfsproto.h> 551590Srgrimes#include <nfs/nfs.h> 561590Srgrimes#include <signal.h> 571590Srgrimes#include <fcntl.h> 581590Srgrimes#include <ctype.h> 591590Srgrimes#include <errno.h> 601590Srgrimes#include <kvm.h> 611590Srgrimes#include <nlist.h> 621590Srgrimes#include <unistd.h> 631590Srgrimes#include <stdio.h> 641590Srgrimes#include <stdlib.h> 651590Srgrimes#include <string.h> 661590Srgrimes#include <paths.h> 673819Swollman#include <err.h> 681590Srgrimes 691590Srgrimesstruct nlist nl[] = { 701590Srgrimes#define N_NFSSTAT 0 711590Srgrimes { "_nfsstats" }, 721590Srgrimes "", 731590Srgrimes}; 741590Srgrimeskvm_t *kd; 751590Srgrimes 763819Swollmanstatic int deadkernel = 0; 771590Srgrimes 789336Sdfrvoid intpr __P((void)); 799336Sdfrvoid printhdr __P((void)); 809336Sdfrvoid sidewaysintpr __P((u_int)); 819336Sdfrvoid usage __P((void)); 823819Swollman 831590Srgrimesmain(argc, argv) 841590Srgrimes int argc; 851590Srgrimes char **argv; 861590Srgrimes{ 871590Srgrimes extern int optind; 881590Srgrimes extern char *optarg; 891590Srgrimes u_int interval; 901590Srgrimes int ch; 911590Srgrimes char *memf, *nlistf; 921590Srgrimes char errbuf[80]; 931590Srgrimes 941590Srgrimes interval = 0; 951590Srgrimes memf = nlistf = NULL; 961590Srgrimes while ((ch = getopt(argc, argv, "M:N:w:")) != EOF) 971590Srgrimes switch(ch) { 981590Srgrimes case 'M': 991590Srgrimes memf = optarg; 1001590Srgrimes break; 1011590Srgrimes case 'N': 1021590Srgrimes nlistf = optarg; 1031590Srgrimes break; 1041590Srgrimes case 'w': 1051590Srgrimes interval = atoi(optarg); 1061590Srgrimes break; 1071590Srgrimes case '?': 1081590Srgrimes default: 1091590Srgrimes usage(); 1101590Srgrimes } 1111590Srgrimes argc -= optind; 1121590Srgrimes argv += optind; 1131590Srgrimes 1141590Srgrimes#define BACKWARD_COMPATIBILITY 1151590Srgrimes#ifdef BACKWARD_COMPATIBILITY 1161590Srgrimes if (*argv) { 1171590Srgrimes interval = atoi(*argv); 1181590Srgrimes if (*++argv) { 1191590Srgrimes nlistf = *argv; 1201590Srgrimes if (*++argv) 1211590Srgrimes memf = *argv; 1221590Srgrimes } 1231590Srgrimes } 1241590Srgrimes#endif 1251590Srgrimes /* 1261590Srgrimes * Discard setgid privileges if not the running kernel so that bad 1271590Srgrimes * guys can't print interesting stuff from kernel memory. 1281590Srgrimes */ 1293819Swollman if (nlistf != NULL || memf != NULL) { 1301590Srgrimes setgid(getgid()); 1313819Swollman deadkernel = 1; 1321590Srgrimes 1333819Swollman if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, 1343819Swollman errbuf)) == 0) { 1353819Swollman errx(1, "kvm_openfiles: %s", errbuf); 1363819Swollman } 1373819Swollman if (kvm_nlist(kd, nl) != 0) { 1383819Swollman errx(1, "kvm_nlist: can't get names"); 1393819Swollman } 1401590Srgrimes } 1411590Srgrimes 1421590Srgrimes if (interval) 1433819Swollman sidewaysintpr(interval); 1441590Srgrimes else 1453819Swollman intpr(); 1461590Srgrimes exit(0); 1471590Srgrimes} 1481590Srgrimes 1491590Srgrimes/* 1503819Swollman * Read the nfs stats using sysctl(3) for live kernels, or kvm_read 1513819Swollman * for dead ones. 1523819Swollman */ 1533819Swollmanvoid 1549336Sdfrreadstats(stp) 1559336Sdfr struct nfsstats *stp; 1563819Swollman{ 1573819Swollman if(deadkernel) { 1583819Swollman if(kvm_read(kd, (u_long)nl[N_NFSSTAT].n_value, stp, 1593819Swollman sizeof *stp) < 0) { 1603819Swollman err(1, "kvm_read"); 1613819Swollman } 1623819Swollman } else { 1633819Swollman int name[3]; 1643819Swollman size_t buflen = sizeof *stp; 1653819Swollman 16614516Shsu name[0] = CTL_VFS; 1673819Swollman name[1] = MOUNT_NFS; 1683819Swollman name[2] = NFS_NFSSTATS; 1693819Swollman 1703819Swollman if(sysctl(name, 3, stp, &buflen, (void *)0, (size_t)0) < 0) { 1713819Swollman err(1, "sysctl"); 1723819Swollman } 1733819Swollman } 1743819Swollman} 1753819Swollman 1763819Swollman/* 1771590Srgrimes * Print a description of the nfs stats. 1781590Srgrimes */ 1791590Srgrimesvoid 1809336Sdfrintpr() 1811590Srgrimes{ 1821590Srgrimes struct nfsstats nfsstats; 1831590Srgrimes 1843819Swollman readstats(&nfsstats); 1853819Swollman 1861590Srgrimes printf("Client Info:\n"); 1871590Srgrimes printf("Rpc Counts:\n"); 1881590Srgrimes printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 1891590Srgrimes "Getattr", "Setattr", "Lookup", "Readlink", "Read", 1901590Srgrimes "Write", "Create", "Remove"); 1911590Srgrimes printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 1921590Srgrimes nfsstats.rpccnt[NFSPROC_GETATTR], 1931590Srgrimes nfsstats.rpccnt[NFSPROC_SETATTR], 1941590Srgrimes nfsstats.rpccnt[NFSPROC_LOOKUP], 1951590Srgrimes nfsstats.rpccnt[NFSPROC_READLINK], 1961590Srgrimes nfsstats.rpccnt[NFSPROC_READ], 1971590Srgrimes nfsstats.rpccnt[NFSPROC_WRITE], 1981590Srgrimes nfsstats.rpccnt[NFSPROC_CREATE], 1991590Srgrimes nfsstats.rpccnt[NFSPROC_REMOVE]); 2001590Srgrimes printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 2011590Srgrimes "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 2029336Sdfr "Readdir", "RdirPlus", "Access"); 2031590Srgrimes printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 2041590Srgrimes nfsstats.rpccnt[NFSPROC_RENAME], 2051590Srgrimes nfsstats.rpccnt[NFSPROC_LINK], 2061590Srgrimes nfsstats.rpccnt[NFSPROC_SYMLINK], 2071590Srgrimes nfsstats.rpccnt[NFSPROC_MKDIR], 2081590Srgrimes nfsstats.rpccnt[NFSPROC_RMDIR], 2091590Srgrimes nfsstats.rpccnt[NFSPROC_READDIR], 2109336Sdfr nfsstats.rpccnt[NFSPROC_READDIRPLUS], 2119336Sdfr nfsstats.rpccnt[NFSPROC_ACCESS]); 2129336Sdfr printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 2139336Sdfr "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit", 2141590Srgrimes "GLease", "Vacate", "Evict"); 2159336Sdfr printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 2169336Sdfr nfsstats.rpccnt[NFSPROC_MKNOD], 2179336Sdfr nfsstats.rpccnt[NFSPROC_FSSTAT], 2189336Sdfr nfsstats.rpccnt[NFSPROC_FSINFO], 2199336Sdfr nfsstats.rpccnt[NFSPROC_PATHCONF], 2209336Sdfr nfsstats.rpccnt[NFSPROC_COMMIT], 2211590Srgrimes nfsstats.rpccnt[NQNFSPROC_GETLEASE], 2221590Srgrimes nfsstats.rpccnt[NQNFSPROC_VACATED], 2231590Srgrimes nfsstats.rpccnt[NQNFSPROC_EVICTED]); 2241590Srgrimes printf("Rpc Info:\n"); 2251590Srgrimes printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 2261590Srgrimes "TimedOut", "Invalid", "X Replies", "Retries", "Requests"); 2271590Srgrimes printf("%9d %9d %9d %9d %9d\n", 2281590Srgrimes nfsstats.rpctimeouts, 2291590Srgrimes nfsstats.rpcinvalid, 2301590Srgrimes nfsstats.rpcunexpected, 2311590Srgrimes nfsstats.rpcretries, 2321590Srgrimes nfsstats.rpcrequests); 2331590Srgrimes printf("Cache Info:\n"); 2341590Srgrimes printf("%9.9s %9.9s %9.9s %9.9s", 2351590Srgrimes "Attr Hits", "Misses", "Lkup Hits", "Misses"); 2361590Srgrimes printf(" %9.9s %9.9s %9.9s %9.9s\n", 2371590Srgrimes "BioR Hits", "Misses", "BioW Hits", "Misses"); 2381590Srgrimes printf("%9d %9d %9d %9d", 2391590Srgrimes nfsstats.attrcache_hits, nfsstats.attrcache_misses, 2401590Srgrimes nfsstats.lookupcache_hits, nfsstats.lookupcache_misses); 2411590Srgrimes printf(" %9d %9d %9d %9d\n", 2421590Srgrimes nfsstats.biocache_reads-nfsstats.read_bios, 2431590Srgrimes nfsstats.read_bios, 2441590Srgrimes nfsstats.biocache_writes-nfsstats.write_bios, 2451590Srgrimes nfsstats.write_bios); 2461590Srgrimes printf("%9.9s %9.9s %9.9s %9.9s", 2471590Srgrimes "BioRLHits", "Misses", "BioD Hits", "Misses"); 2481590Srgrimes printf(" %9.9s %9.9s\n", "DirE Hits", "Misses"); 2491590Srgrimes printf("%9d %9d %9d %9d", 2501590Srgrimes nfsstats.biocache_readlinks-nfsstats.readlink_bios, 2511590Srgrimes nfsstats.readlink_bios, 2521590Srgrimes nfsstats.biocache_readdirs-nfsstats.readdir_bios, 2531590Srgrimes nfsstats.readdir_bios); 2541590Srgrimes printf(" %9d %9d\n", 2551590Srgrimes nfsstats.direofcache_hits, nfsstats.direofcache_misses); 2561590Srgrimes printf("\nServer Info:\n"); 2571590Srgrimes printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 2581590Srgrimes "Getattr", "Setattr", "Lookup", "Readlink", "Read", 2591590Srgrimes "Write", "Create", "Remove"); 2601590Srgrimes printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 2611590Srgrimes nfsstats.srvrpccnt[NFSPROC_GETATTR], 2621590Srgrimes nfsstats.srvrpccnt[NFSPROC_SETATTR], 2631590Srgrimes nfsstats.srvrpccnt[NFSPROC_LOOKUP], 2641590Srgrimes nfsstats.srvrpccnt[NFSPROC_READLINK], 2651590Srgrimes nfsstats.srvrpccnt[NFSPROC_READ], 2661590Srgrimes nfsstats.srvrpccnt[NFSPROC_WRITE], 2671590Srgrimes nfsstats.srvrpccnt[NFSPROC_CREATE], 2681590Srgrimes nfsstats.srvrpccnt[NFSPROC_REMOVE]); 2691590Srgrimes printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 2701590Srgrimes "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 2719336Sdfr "Readdir", "RdirPlus", "Access"); 2721590Srgrimes printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 2731590Srgrimes nfsstats.srvrpccnt[NFSPROC_RENAME], 2741590Srgrimes nfsstats.srvrpccnt[NFSPROC_LINK], 2751590Srgrimes nfsstats.srvrpccnt[NFSPROC_SYMLINK], 2761590Srgrimes nfsstats.srvrpccnt[NFSPROC_MKDIR], 2771590Srgrimes nfsstats.srvrpccnt[NFSPROC_RMDIR], 2781590Srgrimes nfsstats.srvrpccnt[NFSPROC_READDIR], 2799336Sdfr nfsstats.srvrpccnt[NFSPROC_READDIRPLUS], 2809336Sdfr nfsstats.srvrpccnt[NFSPROC_ACCESS]); 2819336Sdfr printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 2829336Sdfr "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit", 2831590Srgrimes "GLease", "Vacate", "Evict"); 2849336Sdfr printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 2859336Sdfr nfsstats.srvrpccnt[NFSPROC_MKNOD], 2869336Sdfr nfsstats.srvrpccnt[NFSPROC_FSSTAT], 2879336Sdfr nfsstats.srvrpccnt[NFSPROC_FSINFO], 2889336Sdfr nfsstats.srvrpccnt[NFSPROC_PATHCONF], 2899336Sdfr nfsstats.srvrpccnt[NFSPROC_COMMIT], 2901590Srgrimes nfsstats.srvrpccnt[NQNFSPROC_GETLEASE], 2911590Srgrimes nfsstats.srvrpccnt[NQNFSPROC_VACATED], 2921590Srgrimes nfsstats.srvrpccnt[NQNFSPROC_EVICTED]); 2931590Srgrimes printf("Server Ret-Failed\n"); 2941590Srgrimes printf("%17d\n", nfsstats.srvrpc_errs); 2951590Srgrimes printf("Server Faults\n"); 2961590Srgrimes printf("%13d\n", nfsstats.srv_errs); 2971590Srgrimes printf("Server Cache Stats:\n"); 2981590Srgrimes printf("%9.9s %9.9s %9.9s %9.9s\n", 2991590Srgrimes "Inprog", "Idem", "Non-idem", "Misses"); 3001590Srgrimes printf("%9d %9d %9d %9d\n", 3011590Srgrimes nfsstats.srvcache_inproghits, 3021590Srgrimes nfsstats.srvcache_idemdonehits, 3031590Srgrimes nfsstats.srvcache_nonidemdonehits, 3041590Srgrimes nfsstats.srvcache_misses); 3051590Srgrimes printf("Server Lease Stats:\n"); 3061590Srgrimes printf("%9.9s %9.9s %9.9s\n", 3071590Srgrimes "Leases", "PeakL", "GLeases"); 3081590Srgrimes printf("%9d %9d %9d\n", 3091590Srgrimes nfsstats.srvnqnfs_leases, 3101590Srgrimes nfsstats.srvnqnfs_maxleases, 3111590Srgrimes nfsstats.srvnqnfs_getleases); 3129336Sdfr printf("Server Write Gathering:\n"); 3139336Sdfr printf("%9.9s %9.9s %9.9s\n", 3149336Sdfr "WriteOps", "WriteRPC", "Opsaved"); 3159336Sdfr printf("%9d %9d %9d\n", 3169336Sdfr nfsstats.srvvop_writes, 3179336Sdfr nfsstats.srvrpccnt[NFSPROC_WRITE], 3189336Sdfr nfsstats.srvrpccnt[NFSPROC_WRITE] - nfsstats.srvvop_writes); 3191590Srgrimes} 3201590Srgrimes 3211590Srgrimesu_char signalled; /* set if alarm goes off "early" */ 3221590Srgrimes 3231590Srgrimes/* 3241590Srgrimes * Print a running summary of nfs statistics. 3251590Srgrimes * Repeat display every interval seconds, showing statistics 3261590Srgrimes * collected over that interval. Assumes that interval is non-zero. 3271590Srgrimes * First line printed at top of screen is always cumulative. 3281590Srgrimes */ 3291590Srgrimesvoid 3303819Swollmansidewaysintpr(interval) 3311590Srgrimes u_int interval; 3321590Srgrimes{ 3331590Srgrimes struct nfsstats nfsstats, lastst; 3341590Srgrimes int hdrcnt, oldmask; 3351590Srgrimes void catchalarm(); 3361590Srgrimes 3371590Srgrimes (void)signal(SIGALRM, catchalarm); 3381590Srgrimes signalled = 0; 3391590Srgrimes (void)alarm(interval); 3401590Srgrimes bzero((caddr_t)&lastst, sizeof(lastst)); 3411590Srgrimes 3421590Srgrimes for (hdrcnt = 1;;) { 3431590Srgrimes if (!--hdrcnt) { 3441590Srgrimes printhdr(); 3451590Srgrimes hdrcnt = 20; 3461590Srgrimes } 3473819Swollman readstats(&nfsstats); 3481590Srgrimes printf("Client: %8d %8d %8d %8d %8d %8d %8d %8d\n", 3499336Sdfr nfsstats.rpccnt[NFSPROC_GETATTR]-lastst.rpccnt[NFSPROC_GETATTR], 3509336Sdfr nfsstats.rpccnt[NFSPROC_LOOKUP]-lastst.rpccnt[NFSPROC_LOOKUP], 3519336Sdfr nfsstats.rpccnt[NFSPROC_READLINK]-lastst.rpccnt[NFSPROC_READLINK], 3529336Sdfr nfsstats.rpccnt[NFSPROC_READ]-lastst.rpccnt[NFSPROC_READ], 3539336Sdfr nfsstats.rpccnt[NFSPROC_WRITE]-lastst.rpccnt[NFSPROC_WRITE], 3549336Sdfr nfsstats.rpccnt[NFSPROC_RENAME]-lastst.rpccnt[NFSPROC_RENAME], 3559336Sdfr nfsstats.rpccnt[NFSPROC_ACCESS]-lastst.rpccnt[NFSPROC_ACCESS], 3569336Sdfr (nfsstats.rpccnt[NFSPROC_READDIR]-lastst.rpccnt[NFSPROC_READDIR]) 3579336Sdfr +(nfsstats.rpccnt[NFSPROC_READDIRPLUS]-lastst.rpccnt[NFSPROC_READDIRPLUS])); 3581590Srgrimes printf("Server: %8d %8d %8d %8d %8d %8d %8d %8d\n", 3599336Sdfr nfsstats.srvrpccnt[NFSPROC_GETATTR]-lastst.srvrpccnt[NFSPROC_GETATTR], 3609336Sdfr nfsstats.srvrpccnt[NFSPROC_LOOKUP]-lastst.srvrpccnt[NFSPROC_LOOKUP], 3619336Sdfr nfsstats.srvrpccnt[NFSPROC_READLINK]-lastst.srvrpccnt[NFSPROC_READLINK], 3629336Sdfr nfsstats.srvrpccnt[NFSPROC_READ]-lastst.srvrpccnt[NFSPROC_READ], 3639336Sdfr nfsstats.srvrpccnt[NFSPROC_WRITE]-lastst.srvrpccnt[NFSPROC_WRITE], 3649336Sdfr nfsstats.srvrpccnt[NFSPROC_RENAME]-lastst.srvrpccnt[NFSPROC_RENAME], 3659336Sdfr nfsstats.srvrpccnt[NFSPROC_ACCESS]-lastst.srvrpccnt[NFSPROC_ACCESS], 3669336Sdfr (nfsstats.srvrpccnt[NFSPROC_READDIR]-lastst.srvrpccnt[NFSPROC_READDIR]) 3679336Sdfr +(nfsstats.srvrpccnt[NFSPROC_READDIRPLUS]-lastst.srvrpccnt[NFSPROC_READDIRPLUS])); 3681590Srgrimes lastst = nfsstats; 3691590Srgrimes fflush(stdout); 3701590Srgrimes oldmask = sigblock(sigmask(SIGALRM)); 3711590Srgrimes if (!signalled) 3721590Srgrimes sigpause(0); 3731590Srgrimes sigsetmask(oldmask); 3741590Srgrimes signalled = 0; 3751590Srgrimes (void)alarm(interval); 3761590Srgrimes } 3771590Srgrimes /*NOTREACHED*/ 3781590Srgrimes} 3791590Srgrimes 3801590Srgrimesvoid 3811590Srgrimesprinthdr() 3821590Srgrimes{ 3831590Srgrimes printf(" %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s\n", 3841590Srgrimes "Getattr", "Lookup", "Readlink", "Read", "Write", "Rename", 3859336Sdfr "Access", "Readdir"); 3861590Srgrimes fflush(stdout); 3871590Srgrimes} 3881590Srgrimes 3891590Srgrimes/* 3901590Srgrimes * Called if an interval expires before sidewaysintpr has completed a loop. 3911590Srgrimes * Sets a flag to not wait for the alarm. 3921590Srgrimes */ 3931590Srgrimesvoid 3941590Srgrimescatchalarm() 3951590Srgrimes{ 3961590Srgrimes signalled = 1; 3971590Srgrimes} 3981590Srgrimes 3991590Srgrimesvoid 4001590Srgrimesusage() 4011590Srgrimes{ 4021590Srgrimes (void)fprintf(stderr, 4031590Srgrimes "usage: nfsstat [-M core] [-N system] [-w interval]\n"); 4041590Srgrimes exit(1); 4051590Srgrimes} 406