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