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