nfsstat.c revision 194190
1/* 2 * Copyright (c) 1983, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38static char copyright[] = 39"@(#) Copyright (c) 1983, 1989, 1993\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif /* not lint */ 42 43#ifndef lint 44#if 0 45static char sccsid[] = "@(#)nfsstat.c 8.2 (Berkeley) 3/31/95"; 46#endif 47static const char rcsid[] = 48 "$FreeBSD: head/usr.bin/nfsstat/nfsstat.c 194190 2009-06-14 12:47:27Z ed $"; 49#endif /* not lint */ 50 51#include <sys/param.h> 52#include <sys/module.h> 53#include <sys/mount.h> 54#include <sys/time.h> 55#include <sys/sysctl.h> 56#include <nfs/rpcv2.h> 57#include <nfs/nfsproto.h> 58#include <nfsclient/nfs.h> 59#include <nfsserver/nfs.h> 60#include <nfs/nfssvc.h> 61 62#include <fs/nfs/nfsport.h> 63 64#include <signal.h> 65#include <fcntl.h> 66#include <ctype.h> 67#include <errno.h> 68#include <kvm.h> 69#include <limits.h> 70#include <nlist.h> 71#include <unistd.h> 72#include <stdio.h> 73#include <stdlib.h> 74#include <string.h> 75#include <paths.h> 76#include <err.h> 77 78struct nlist nl[] = { 79#define N_NFSSTAT 0 80 { "nfsstats" }, 81#define N_NFSRVSTAT 1 82 { "nfsrvstats" }, 83 "", 84}; 85kvm_t *kd; 86 87static int deadkernel = 0; 88static int widemode = 0; 89static int zflag = 0; 90static int run_v4 = 0; 91static int printtitle = 1; 92static struct ext_nfsstats ext_nfsstats; 93 94void intpr(int, int); 95void printhdr(int, int); 96void sidewaysintpr(u_int, int, int); 97void usage(void); 98char *sperc1(int, int); 99char *sperc2(int, int); 100void exp_intpr(int, int); 101void exp_sidewaysintpr(u_int, int, int); 102 103#define DELTA(field) (nfsstats.field - lastst.field) 104 105int 106main(int argc, char **argv) 107{ 108 u_int interval; 109 int clientOnly = -1; 110 int serverOnly = -1; 111 int ch; 112 char *memf, *nlistf; 113 char errbuf[_POSIX2_LINE_MAX]; 114 115 interval = 0; 116 memf = nlistf = NULL; 117 while ((ch = getopt(argc, argv, "cesWM:N:w:z")) != -1) 118 switch(ch) { 119 case 'M': 120 memf = optarg; 121 break; 122 case 'N': 123 nlistf = optarg; 124 break; 125 case 'W': 126 widemode = 1; 127 break; 128 case 'w': 129 interval = atoi(optarg); 130 break; 131 case 'c': 132 clientOnly = 1; 133 if (serverOnly < 0) 134 serverOnly = 0; 135 break; 136 case 's': 137 serverOnly = 1; 138 if (clientOnly < 0) 139 clientOnly = 0; 140 break; 141 case 'z': 142 zflag = 1; 143 break; 144 case 'e': 145 run_v4 = 1; 146 break; 147 case '?': 148 default: 149 usage(); 150 } 151 argc -= optind; 152 argv += optind; 153 154#define BACKWARD_COMPATIBILITY 155#ifdef BACKWARD_COMPATIBILITY 156 if (*argv) { 157 interval = atoi(*argv); 158 if (*++argv) { 159 nlistf = *argv; 160 if (*++argv) 161 memf = *argv; 162 } 163 } 164#endif 165 if (run_v4 != 0 && modfind("nfscommon") < 0) 166 errx(1, "experimental client/server not loaded"); 167 168 if (run_v4 != 0) { 169 if (nfssvc(NFSSVC_GETSTATS, &ext_nfsstats) < 0) 170 err(1, "Can't get stats"); 171 } else if (nlistf != NULL || memf != NULL) { 172 deadkernel = 1; 173 174 if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, 175 errbuf)) == 0) { 176 errx(1, "kvm_openfiles: %s", errbuf); 177 } 178 if (kvm_nlist(kd, nl) != 0) { 179 errx(1, "kvm_nlist: can't get names"); 180 } 181 } 182 183 if (interval) { 184 if (run_v4 > 0) 185 exp_sidewaysintpr(interval, clientOnly, serverOnly); 186 else 187 sidewaysintpr(interval, clientOnly, serverOnly); 188 } else { 189 if (run_v4 > 0) 190 exp_intpr(clientOnly, serverOnly); 191 else 192 intpr(clientOnly, serverOnly); 193 } 194 exit(0); 195} 196 197/* 198 * Read the nfs stats using sysctl(3) for live kernels, or kvm_read 199 * for dead ones. 200 */ 201void 202readstats(struct nfsstats **stp, struct nfsrvstats **srvstp, int zero) 203{ 204 union { 205 struct nfsstats client; 206 struct nfsrvstats server; 207 } zerostat; 208 size_t buflen; 209 210 if (deadkernel) { 211 if (*stp != NULL && kvm_read(kd, (u_long)nl[N_NFSSTAT].n_value, 212 *stp, sizeof(struct nfsstats)) < 0) { 213 *stp = NULL; 214 } 215 if (*srvstp != NULL && kvm_read(kd, 216 (u_long)nl[N_NFSRVSTAT].n_value, *srvstp, 217 sizeof(struct nfsrvstats)) < 0) { 218 *srvstp = NULL; 219 } 220 } else { 221 if (zero) 222 bzero(&zerostat, sizeof(zerostat)); 223 buflen = sizeof(struct nfsstats); 224 if (*stp != NULL && sysctlbyname("vfs.nfs.nfsstats", *stp, 225 &buflen, zero ? &zerostat : NULL, zero ? buflen : 0) < 0) { 226 if (errno != ENOENT) 227 err(1, "sysctl: vfs.nfs.nfsstats"); 228 *stp = NULL; 229 } 230 buflen = sizeof(struct nfsrvstats); 231 if (*srvstp != NULL && sysctlbyname("vfs.nfsrv.nfsrvstats", 232 *srvstp, &buflen, zero ? &zerostat : NULL, 233 zero ? buflen : 0) < 0) { 234 if (errno != ENOENT) 235 err(1, "sysctl: vfs.nfsrv.nfsrvstats"); 236 *srvstp = NULL; 237 } 238 } 239} 240 241/* 242 * Print a description of the nfs stats. 243 */ 244void 245intpr(int clientOnly, int serverOnly) 246{ 247 struct nfsstats nfsstats, *nfsstatsp; 248 struct nfsrvstats nfsrvstats, *nfsrvstatsp; 249 250 /* 251 * Only read the stats we are going to display to avoid zeroing 252 * stats the user didn't request. 253 */ 254 if (clientOnly) 255 nfsstatsp = &nfsstats; 256 else 257 nfsstatsp = NULL; 258 if (serverOnly) 259 nfsrvstatsp = &nfsrvstats; 260 else 261 nfsrvstatsp = NULL; 262 263 readstats(&nfsstatsp, &nfsrvstatsp, zflag); 264 265 if (clientOnly && !nfsstatsp) { 266 printf("Client not present!\n"); 267 clientOnly = 0; 268 } 269 if (clientOnly) { 270 printf("Client Info:\n"); 271 printf("Rpc Counts:\n"); 272 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 273 "Getattr", "Setattr", "Lookup", "Readlink", "Read", 274 "Write", "Create", "Remove"); 275 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 276 nfsstats.rpccnt[NFSPROC_GETATTR], 277 nfsstats.rpccnt[NFSPROC_SETATTR], 278 nfsstats.rpccnt[NFSPROC_LOOKUP], 279 nfsstats.rpccnt[NFSPROC_READLINK], 280 nfsstats.rpccnt[NFSPROC_READ], 281 nfsstats.rpccnt[NFSPROC_WRITE], 282 nfsstats.rpccnt[NFSPROC_CREATE], 283 nfsstats.rpccnt[NFSPROC_REMOVE]); 284 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 285 "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 286 "Readdir", "RdirPlus", "Access"); 287 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 288 nfsstats.rpccnt[NFSPROC_RENAME], 289 nfsstats.rpccnt[NFSPROC_LINK], 290 nfsstats.rpccnt[NFSPROC_SYMLINK], 291 nfsstats.rpccnt[NFSPROC_MKDIR], 292 nfsstats.rpccnt[NFSPROC_RMDIR], 293 nfsstats.rpccnt[NFSPROC_READDIR], 294 nfsstats.rpccnt[NFSPROC_READDIRPLUS], 295 nfsstats.rpccnt[NFSPROC_ACCESS]); 296 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 297 "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit"); 298 printf("%9d %9d %9d %9d %9d\n", 299 nfsstats.rpccnt[NFSPROC_MKNOD], 300 nfsstats.rpccnt[NFSPROC_FSSTAT], 301 nfsstats.rpccnt[NFSPROC_FSINFO], 302 nfsstats.rpccnt[NFSPROC_PATHCONF], 303 nfsstats.rpccnt[NFSPROC_COMMIT]); 304 printf("Rpc Info:\n"); 305 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 306 "TimedOut", "Invalid", "X Replies", "Retries", 307 "Requests"); 308 printf("%9d %9d %9d %9d %9d\n", 309 nfsstats.rpctimeouts, 310 nfsstats.rpcinvalid, 311 nfsstats.rpcunexpected, 312 nfsstats.rpcretries, 313 nfsstats.rpcrequests); 314 printf("Cache Info:\n"); 315 printf("%9.9s %9.9s %9.9s %9.9s", 316 "Attr Hits", "Misses", "Lkup Hits", "Misses"); 317 printf(" %9.9s %9.9s %9.9s %9.9s\n", 318 "BioR Hits", "Misses", "BioW Hits", "Misses"); 319 printf("%9d %9d %9d %9d", 320 nfsstats.attrcache_hits, nfsstats.attrcache_misses, 321 nfsstats.lookupcache_hits, nfsstats.lookupcache_misses); 322 printf(" %9d %9d %9d %9d\n", 323 nfsstats.biocache_reads-nfsstats.read_bios, 324 nfsstats.read_bios, 325 nfsstats.biocache_writes-nfsstats.write_bios, 326 nfsstats.write_bios); 327 printf("%9.9s %9.9s %9.9s %9.9s", 328 "BioRLHits", "Misses", "BioD Hits", "Misses"); 329 printf(" %9.9s %9.9s\n", "DirE Hits", "Misses"); 330 printf("%9d %9d %9d %9d", 331 nfsstats.biocache_readlinks-nfsstats.readlink_bios, 332 nfsstats.readlink_bios, 333 nfsstats.biocache_readdirs-nfsstats.readdir_bios, 334 nfsstats.readdir_bios); 335 printf(" %9d %9d\n", 336 nfsstats.direofcache_hits, nfsstats.direofcache_misses); 337 } 338 if (serverOnly && !nfsrvstatsp) { 339 printf("Server not present!\n"); 340 serverOnly = 0; 341 } 342 if (serverOnly) { 343 printf("\nServer Info:\n"); 344 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 345 "Getattr", "Setattr", "Lookup", "Readlink", "Read", 346 "Write", "Create", "Remove"); 347 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 348 nfsrvstats.srvrpccnt[NFSPROC_GETATTR], 349 nfsrvstats.srvrpccnt[NFSPROC_SETATTR], 350 nfsrvstats.srvrpccnt[NFSPROC_LOOKUP], 351 nfsrvstats.srvrpccnt[NFSPROC_READLINK], 352 nfsrvstats.srvrpccnt[NFSPROC_READ], 353 nfsrvstats.srvrpccnt[NFSPROC_WRITE], 354 nfsrvstats.srvrpccnt[NFSPROC_CREATE], 355 nfsrvstats.srvrpccnt[NFSPROC_REMOVE]); 356 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 357 "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 358 "Readdir", "RdirPlus", "Access"); 359 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 360 nfsrvstats.srvrpccnt[NFSPROC_RENAME], 361 nfsrvstats.srvrpccnt[NFSPROC_LINK], 362 nfsrvstats.srvrpccnt[NFSPROC_SYMLINK], 363 nfsrvstats.srvrpccnt[NFSPROC_MKDIR], 364 nfsrvstats.srvrpccnt[NFSPROC_RMDIR], 365 nfsrvstats.srvrpccnt[NFSPROC_READDIR], 366 nfsrvstats.srvrpccnt[NFSPROC_READDIRPLUS], 367 nfsrvstats.srvrpccnt[NFSPROC_ACCESS]); 368 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 369 "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit"); 370 printf("%9d %9d %9d %9d %9d\n", 371 nfsrvstats.srvrpccnt[NFSPROC_MKNOD], 372 nfsrvstats.srvrpccnt[NFSPROC_FSSTAT], 373 nfsrvstats.srvrpccnt[NFSPROC_FSINFO], 374 nfsrvstats.srvrpccnt[NFSPROC_PATHCONF], 375 nfsrvstats.srvrpccnt[NFSPROC_COMMIT]); 376 printf("Server Ret-Failed\n"); 377 printf("%17d\n", nfsrvstats.srvrpc_errs); 378 printf("Server Faults\n"); 379 printf("%13d\n", nfsrvstats.srv_errs); 380 printf("Server Cache Stats:\n"); 381 printf("%9.9s %9.9s %9.9s %9.9s\n", 382 "Inprog", "Idem", "Non-idem", "Misses"); 383 printf("%9d %9d %9d %9d\n", 384 nfsrvstats.srvcache_inproghits, 385 nfsrvstats.srvcache_idemdonehits, 386 nfsrvstats.srvcache_nonidemdonehits, 387 nfsrvstats.srvcache_misses); 388 printf("Server Write Gathering:\n"); 389 printf("%9.9s %9.9s %9.9s\n", 390 "WriteOps", "WriteRPC", "Opsaved"); 391 printf("%9d %9d %9d\n", 392 nfsrvstats.srvvop_writes, 393 nfsrvstats.srvrpccnt[NFSPROC_WRITE], 394 nfsrvstats.srvrpccnt[NFSPROC_WRITE] - 395 nfsrvstats.srvvop_writes); 396 } 397} 398 399u_char signalled; /* set if alarm goes off "early" */ 400 401/* 402 * Print a running summary of nfs statistics. 403 * Repeat display every interval seconds, showing statistics 404 * collected over that interval. Assumes that interval is non-zero. 405 * First line printed at top of screen is always cumulative. 406 */ 407void 408sidewaysintpr(u_int interval, int clientOnly, int serverOnly) 409{ 410 struct nfsstats nfsstats, lastst, *nfsstatsp; 411 struct nfsrvstats nfsrvstats, lastsrvst, *nfsrvstatsp; 412 int hdrcnt = 1; 413 414 nfsstatsp = &lastst; 415 nfsrvstatsp = &lastsrvst; 416 readstats(&nfsstatsp, &nfsrvstatsp, 0); 417 if (clientOnly && !nfsstatsp) { 418 printf("Client not present!\n"); 419 clientOnly = 0; 420 } 421 if (serverOnly && !nfsrvstatsp) { 422 printf("Server not present!\n"); 423 serverOnly = 0; 424 } 425 sleep(interval); 426 427 for (;;) { 428 nfsstatsp = &nfsstats; 429 nfsrvstatsp = &nfsrvstats; 430 readstats(&nfsstatsp, &nfsrvstatsp, 0); 431 432 if (--hdrcnt == 0) { 433 printhdr(clientOnly, serverOnly); 434 if (clientOnly && serverOnly) 435 hdrcnt = 10; 436 else 437 hdrcnt = 20; 438 } 439 if (clientOnly) { 440 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 441 ((clientOnly && serverOnly) ? "Client:" : ""), 442 DELTA(attrcache_hits) + DELTA(attrcache_misses), 443 DELTA(lookupcache_hits) + DELTA(lookupcache_misses), 444 DELTA(biocache_readlinks), 445 DELTA(biocache_reads), 446 DELTA(biocache_writes), 447 nfsstats.rpccnt[NFSPROC_RENAME]-lastst.rpccnt[NFSPROC_RENAME], 448 DELTA(accesscache_hits) + DELTA(accesscache_misses), 449 DELTA(biocache_readdirs) 450 ); 451 if (widemode) { 452 printf(" %s %s %s %s %s %s", 453 sperc1(DELTA(attrcache_hits), 454 DELTA(attrcache_misses)), 455 sperc1(DELTA(lookupcache_hits), 456 DELTA(lookupcache_misses)), 457 sperc2(DELTA(biocache_reads), 458 DELTA(read_bios)), 459 sperc2(DELTA(biocache_writes), 460 DELTA(write_bios)), 461 sperc1(DELTA(accesscache_hits), 462 DELTA(accesscache_misses)), 463 sperc2(DELTA(biocache_readdirs), 464 DELTA(readdir_bios)) 465 ); 466 } 467 printf("\n"); 468 lastst = nfsstats; 469 } 470 if (serverOnly) { 471 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 472 ((clientOnly && serverOnly) ? "Server:" : ""), 473 nfsrvstats.srvrpccnt[NFSPROC_GETATTR]-lastsrvst.srvrpccnt[NFSPROC_GETATTR], 474 nfsrvstats.srvrpccnt[NFSPROC_LOOKUP]-lastsrvst.srvrpccnt[NFSPROC_LOOKUP], 475 nfsrvstats.srvrpccnt[NFSPROC_READLINK]-lastsrvst.srvrpccnt[NFSPROC_READLINK], 476 nfsrvstats.srvrpccnt[NFSPROC_READ]-lastsrvst.srvrpccnt[NFSPROC_READ], 477 nfsrvstats.srvrpccnt[NFSPROC_WRITE]-lastsrvst.srvrpccnt[NFSPROC_WRITE], 478 nfsrvstats.srvrpccnt[NFSPROC_RENAME]-lastsrvst.srvrpccnt[NFSPROC_RENAME], 479 nfsrvstats.srvrpccnt[NFSPROC_ACCESS]-lastsrvst.srvrpccnt[NFSPROC_ACCESS], 480 (nfsrvstats.srvrpccnt[NFSPROC_READDIR]-lastsrvst.srvrpccnt[NFSPROC_READDIR]) 481 +(nfsrvstats.srvrpccnt[NFSPROC_READDIRPLUS]-lastsrvst.srvrpccnt[NFSPROC_READDIRPLUS])); 482 printf("\n"); 483 lastsrvst = nfsrvstats; 484 } 485 fflush(stdout); 486 sleep(interval); 487 } 488 /*NOTREACHED*/ 489} 490 491void 492printhdr(int clientOnly, int serverOnly) 493{ 494 printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s", 495 ((serverOnly && clientOnly) ? " " : " "), 496 "GtAttr", "Lookup", "Rdlink", "Read", "Write", "Rename", 497 "Access", "Rddir"); 498 if (widemode && clientOnly) { 499 printf(" Attr Lkup BioR BioW Accs BioD"); 500 } 501 printf("\n"); 502 fflush(stdout); 503} 504 505void 506usage(void) 507{ 508 (void)fprintf(stderr, 509 "usage: nfsstat [-ceszW] [-M core] [-N system] [-w interval]\n"); 510 exit(1); 511} 512 513static char SPBuf[64][8]; 514static int SPIndex; 515 516char * 517sperc1(int hits, int misses) 518{ 519 char *p = SPBuf[SPIndex]; 520 521 if (hits + misses) { 522 sprintf(p, "%3d%%", 523 (int)(char)((quad_t)hits * 100 / (hits + misses))); 524 } else { 525 sprintf(p, " -"); 526 } 527 SPIndex = (SPIndex + 1) & 63; 528 return(p); 529} 530 531char * 532sperc2(int ttl, int misses) 533{ 534 char *p = SPBuf[SPIndex]; 535 536 if (ttl) { 537 sprintf(p, "%3d%%", 538 (int)(char)((quad_t)(ttl - misses) * 100 / ttl)); 539 } else { 540 sprintf(p, " -"); 541 } 542 SPIndex = (SPIndex + 1) & 63; 543 return(p); 544} 545 546/* 547 * Print a description of the nfs stats for the experimental client/server. 548 */ 549void 550exp_intpr(int clientOnly, int serverOnly) 551{ 552 553 if (clientOnly != 0) { 554 if (printtitle) { 555 printf("Client Info:\n"); 556 printf("Rpc Counts:\n"); 557 printf( 558 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 559 , "Getattr", "Setattr", "Lookup", "Readlink", 560 "Read", "Write", "Create", "Remove"); 561 } 562 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 563 ext_nfsstats.rpccnt[NFSPROC_GETATTR], 564 ext_nfsstats.rpccnt[NFSPROC_SETATTR], 565 ext_nfsstats.rpccnt[NFSPROC_LOOKUP], 566 ext_nfsstats.rpccnt[NFSPROC_READLINK], 567 ext_nfsstats.rpccnt[NFSPROC_READ], 568 ext_nfsstats.rpccnt[NFSPROC_WRITE], 569 ext_nfsstats.rpccnt[NFSPROC_CREATE], 570 ext_nfsstats.rpccnt[NFSPROC_REMOVE]); 571 if (printtitle) 572 printf( 573 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 574 , "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 575 "Readdir", "RdirPlus", "Access"); 576 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 577 ext_nfsstats.rpccnt[NFSPROC_RENAME], 578 ext_nfsstats.rpccnt[NFSPROC_LINK], 579 ext_nfsstats.rpccnt[NFSPROC_SYMLINK], 580 ext_nfsstats.rpccnt[NFSPROC_MKDIR], 581 ext_nfsstats.rpccnt[NFSPROC_RMDIR], 582 ext_nfsstats.rpccnt[NFSPROC_READDIR], 583 ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS], 584 ext_nfsstats.rpccnt[NFSPROC_ACCESS]); 585 if (printtitle) 586 printf( 587 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 588 , "Mknod", "Fsstat", "Fsinfo", "PathConf", 589 "Commit", "SetClId", "SetClIdCf", "Lock"); 590 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 591 ext_nfsstats.rpccnt[NFSPROC_MKNOD], 592 ext_nfsstats.rpccnt[NFSPROC_FSSTAT], 593 ext_nfsstats.rpccnt[NFSPROC_FSINFO], 594 ext_nfsstats.rpccnt[NFSPROC_PATHCONF], 595 ext_nfsstats.rpccnt[NFSPROC_COMMIT], 596 ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID], 597 ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM], 598 ext_nfsstats.rpccnt[NFSPROC_LOCK]); 599 if (printtitle) 600 printf("%9.9s %9.9s %9.9s %9.9s\n", 601 "LockT", "LockU", "Open", "OpenCfr"); 602 printf("%9d %9d %9d %9d\n", 603 ext_nfsstats.rpccnt[NFSPROC_LOCKT], 604 ext_nfsstats.rpccnt[NFSPROC_LOCKU], 605 ext_nfsstats.rpccnt[NFSPROC_OPEN], 606 ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM]); 607 if (printtitle) 608 printf( 609 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 610 , "OpenOwner", "Opens", "LockOwner", 611 "Locks", "Delegs", "LocalOwn", 612 "LocalOpen", "LocalLOwn"); 613 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 614 ext_nfsstats.clopenowners, 615 ext_nfsstats.clopens, 616 ext_nfsstats.cllockowners, 617 ext_nfsstats.cllocks, 618 ext_nfsstats.cldelegates, 619 ext_nfsstats.cllocalopenowners, 620 ext_nfsstats.cllocalopens, 621 ext_nfsstats.cllocallockowners); 622 if (printtitle) 623 printf("%9.9s\n", "LocalLock"); 624 printf("%9d\n", ext_nfsstats.cllocallocks); 625 if (printtitle) { 626 printf("Rpc Info:\n"); 627 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 628 "TimedOut", "Invalid", "X Replies", "Retries", 629 "Requests"); 630 } 631 printf("%9d %9d %9d %9d %9d\n", 632 ext_nfsstats.rpctimeouts, 633 ext_nfsstats.rpcinvalid, 634 ext_nfsstats.rpcunexpected, 635 ext_nfsstats.rpcretries, 636 ext_nfsstats.rpcrequests); 637 if (printtitle) { 638 printf("Cache Info:\n"); 639 printf("%9.9s %9.9s %9.9s %9.9s", 640 "Attr Hits", "Misses", "Lkup Hits", "Misses"); 641 printf(" %9.9s %9.9s %9.9s %9.9s\n", 642 "BioR Hits", "Misses", "BioW Hits", "Misses"); 643 } 644 printf("%9d %9d %9d %9d", 645 ext_nfsstats.attrcache_hits, 646 ext_nfsstats.attrcache_misses, 647 ext_nfsstats.lookupcache_hits, 648 ext_nfsstats.lookupcache_misses); 649 printf(" %9d %9d %9d %9d\n", 650 ext_nfsstats.biocache_reads, 651 ext_nfsstats.read_bios, 652 ext_nfsstats.biocache_writes, 653 ext_nfsstats.write_bios); 654 if (printtitle) { 655 printf("%9.9s %9.9s %9.9s %9.9s", 656 "BioRLHits", "Misses", "BioD Hits", "Misses"); 657 printf(" %9.9s %9.9s\n", "DirE Hits", "Misses"); 658 } 659 printf("%9d %9d %9d %9d", 660 ext_nfsstats.biocache_readlinks, 661 ext_nfsstats.readlink_bios, 662 ext_nfsstats.biocache_readdirs, 663 ext_nfsstats.readdir_bios); 664 printf(" %9d %9d\n", 665 ext_nfsstats.direofcache_hits, 666 ext_nfsstats.direofcache_misses); 667 } 668 if (serverOnly != 0) { 669 if (printtitle) { 670 printf("\nServer Info:\n"); 671 printf( 672 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 673 , "Getattr", "Setattr", "Lookup", "Readlink", 674 "Read", "Write", "Create", "Remove"); 675 } 676 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 677 ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR], 678 ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR], 679 ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP], 680 ext_nfsstats.srvrpccnt[NFSV4OP_READLINK], 681 ext_nfsstats.srvrpccnt[NFSV4OP_READ], 682 ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 683 ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE], 684 ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]); 685 if (printtitle) 686 printf( 687 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 688 , "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 689 "Readdir", "RdirPlus", "Access"); 690 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 691 ext_nfsstats.srvrpccnt[NFSV4OP_RENAME], 692 ext_nfsstats.srvrpccnt[NFSV4OP_LINK], 693 ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK], 694 ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR], 695 ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR], 696 ext_nfsstats.srvrpccnt[NFSV4OP_READDIR], 697 ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS], 698 ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]); 699 if (printtitle) 700 printf( 701 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 702 , "Mknod", "Fsstat", "Fsinfo", "PathConf", 703 "Commit", "LookupP", "SetClId", "SetClIdCf"); 704 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 705 ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD], 706 ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT], 707 ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO], 708 ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF], 709 ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT], 710 ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP], 711 ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID], 712 ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]); 713 if (printtitle) 714 printf( 715 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 716 , "Open", "OpenAttr", "OpenDwnGr", "OpenCfrm", 717 "DelePurge", "DeleRet", "GetFH", "Lock"); 718 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 719 ext_nfsstats.srvrpccnt[NFSV4OP_OPEN], 720 ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR], 721 ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE], 722 ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM], 723 ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE], 724 ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN], 725 ext_nfsstats.srvrpccnt[NFSV4OP_GETFH], 726 ext_nfsstats.srvrpccnt[NFSV4OP_LOCK]); 727 if (printtitle) 728 printf( 729 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 730 , "LockT", "LockU", "Close", "Verify", "NVerify", 731 "PutFH", "PutPubFH", "PutRootFH"); 732 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 733 ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT], 734 ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU], 735 ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE], 736 ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY], 737 ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY], 738 ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH], 739 ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH], 740 ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH]); 741 if (printtitle) 742 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 743 "Renew", "RestoreFH", "SaveFH", "Secinfo", 744 "RelLckOwn", "V4Create"); 745 printf("%9d %9d %9d %9d %9d %9d\n", 746 ext_nfsstats.srvrpccnt[NFSV4OP_RENEW], 747 ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH], 748 ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH], 749 ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO], 750 ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN], 751 ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]); 752 if (printtitle) { 753 printf("Server:\n"); 754 printf("%9.9s %9.9s %9.9s\n", 755 "Retfailed", "Faults", "Clients"); 756 } 757 printf("%9d %9d %9d\n", 758 ext_nfsstats.srv_errs, ext_nfsstats.srvrpc_errs, 759 ext_nfsstats.srvclients); 760 if (printtitle) 761 printf("%9.9s %9.9s %9.9s %9.9s %9.9s \n", 762 "OpenOwner", "Opens", "LockOwner", 763 "Locks", "Delegs"); 764 printf("%9d %9d %9d %9d %9d \n", 765 ext_nfsstats.srvopenowners, 766 ext_nfsstats.srvopens, 767 ext_nfsstats.srvlockowners, 768 ext_nfsstats.srvlocks, 769 ext_nfsstats.srvdelegates); 770 if (printtitle) { 771 printf("Server Cache Stats:\n"); 772 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 773 "Inprog", "Idem", "Non-idem", "Misses", 774 "CacheSize", "TCPPeak"); 775 } 776 printf("%9d %9d %9d %9d %9d %9d\n", 777 ext_nfsstats.srvcache_inproghits, 778 ext_nfsstats.srvcache_idemdonehits, 779 ext_nfsstats.srvcache_nonidemdonehits, 780 ext_nfsstats.srvcache_misses, 781 ext_nfsstats.srvcache_size, 782 ext_nfsstats.srvcache_tcppeak); 783 } 784} 785 786/* 787 * Print a running summary of nfs statistics for the experimental client and/or 788 * server. 789 * Repeat display every interval seconds, showing statistics 790 * collected over that interval. Assumes that interval is non-zero. 791 * First line printed at top of screen is always cumulative. 792 */ 793void 794exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly) 795{ 796 struct ext_nfsstats nfsstats, lastst, *ext_nfsstatsp; 797 int hdrcnt = 1; 798 799 ext_nfsstatsp = &lastst; 800 if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0) 801 err(1, "Can't get stats"); 802 sleep(interval); 803 804 for (;;) { 805 ext_nfsstatsp = &nfsstats; 806 if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0) 807 err(1, "Can't get stats"); 808 809 if (--hdrcnt == 0) { 810 printhdr(clientOnly, serverOnly); 811 if (clientOnly && serverOnly) 812 hdrcnt = 10; 813 else 814 hdrcnt = 20; 815 } 816 if (clientOnly) { 817 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 818 ((clientOnly && serverOnly) ? "Client:" : ""), 819 DELTA(attrcache_hits) + DELTA(attrcache_misses), 820 DELTA(lookupcache_hits) + DELTA(lookupcache_misses), 821 DELTA(biocache_readlinks), 822 DELTA(biocache_reads), 823 DELTA(biocache_writes), 824 nfsstats.rpccnt[NFSPROC_RENAME] - 825 lastst.rpccnt[NFSPROC_RENAME], 826 DELTA(accesscache_hits) + DELTA(accesscache_misses), 827 DELTA(biocache_readdirs) 828 ); 829 if (widemode) { 830 printf(" %s %s %s %s %s %s", 831 sperc1(DELTA(attrcache_hits), 832 DELTA(attrcache_misses)), 833 sperc1(DELTA(lookupcache_hits), 834 DELTA(lookupcache_misses)), 835 sperc2(DELTA(biocache_reads), 836 DELTA(read_bios)), 837 sperc2(DELTA(biocache_writes), 838 DELTA(write_bios)), 839 sperc1(DELTA(accesscache_hits), 840 DELTA(accesscache_misses)), 841 sperc2(DELTA(biocache_readdirs), 842 DELTA(readdir_bios)) 843 ); 844 } 845 printf("\n"); 846 lastst = nfsstats; 847 } 848 if (serverOnly) { 849 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 850 ((clientOnly && serverOnly) ? "Server:" : ""), 851 nfsstats.srvrpccnt[NFSPROC_GETATTR] - 852 lastst.srvrpccnt[NFSPROC_GETATTR], 853 nfsstats.srvrpccnt[NFSPROC_LOOKUP] - 854 lastst.srvrpccnt[NFSPROC_LOOKUP], 855 nfsstats.srvrpccnt[NFSPROC_READLINK] - 856 lastst.srvrpccnt[NFSPROC_READLINK], 857 nfsstats.srvrpccnt[NFSPROC_READ] - 858 lastst.srvrpccnt[NFSPROC_READ], 859 nfsstats.srvrpccnt[NFSPROC_WRITE] - 860 lastst.srvrpccnt[NFSPROC_WRITE], 861 nfsstats.srvrpccnt[NFSPROC_RENAME] - 862 lastst.srvrpccnt[NFSPROC_RENAME], 863 nfsstats.srvrpccnt[NFSPROC_ACCESS] - 864 lastst.srvrpccnt[NFSPROC_ACCESS], 865 (nfsstats.srvrpccnt[NFSPROC_READDIR] - 866 lastst.srvrpccnt[NFSPROC_READDIR]) + 867 (nfsstats.srvrpccnt[NFSPROC_READDIRPLUS] - 868 lastst.srvrpccnt[NFSPROC_READDIRPLUS])); 869 printf("\n"); 870 lastst = nfsstats; 871 } 872 fflush(stdout); 873 sleep(interval); 874 } 875 /*NOTREACHED*/ 876} 877 878