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