nfsstat.c revision 221440
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 221440 2011-05-04 13:50:37Z 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, 654 ext_nfsstats.read_bios, 655 ext_nfsstats.biocache_writes, 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.biocache_readdirs, 666 ext_nfsstats.readdir_bios); 667 printf(" %9d %9d\n", 668 ext_nfsstats.direofcache_hits, 669 ext_nfsstats.direofcache_misses); 670 } 671 if (serverOnly != 0) { 672 if (printtitle) { 673 printf("\nServer Info:\n"); 674 printf( 675 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 676 , "Getattr", "Setattr", "Lookup", "Readlink", 677 "Read", "Write", "Create", "Remove"); 678 } 679 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 680 ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR], 681 ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR], 682 ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP], 683 ext_nfsstats.srvrpccnt[NFSV4OP_READLINK], 684 ext_nfsstats.srvrpccnt[NFSV4OP_READ], 685 ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 686 ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE], 687 ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]); 688 if (printtitle) 689 printf( 690 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 691 , "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 692 "Readdir", "RdirPlus", "Access"); 693 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 694 ext_nfsstats.srvrpccnt[NFSV4OP_RENAME], 695 ext_nfsstats.srvrpccnt[NFSV4OP_LINK], 696 ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK], 697 ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR], 698 ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR], 699 ext_nfsstats.srvrpccnt[NFSV4OP_READDIR], 700 ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS], 701 ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]); 702 if (printtitle) 703 printf( 704 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 705 , "Mknod", "Fsstat", "Fsinfo", "PathConf", 706 "Commit", "LookupP", "SetClId", "SetClIdCf"); 707 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 708 ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD], 709 ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT], 710 ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO], 711 ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF], 712 ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT], 713 ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP], 714 ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID], 715 ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]); 716 if (printtitle) 717 printf( 718 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 719 , "Open", "OpenAttr", "OpenDwnGr", "OpenCfrm", 720 "DelePurge", "DeleRet", "GetFH", "Lock"); 721 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 722 ext_nfsstats.srvrpccnt[NFSV4OP_OPEN], 723 ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR], 724 ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE], 725 ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM], 726 ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE], 727 ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN], 728 ext_nfsstats.srvrpccnt[NFSV4OP_GETFH], 729 ext_nfsstats.srvrpccnt[NFSV4OP_LOCK]); 730 if (printtitle) 731 printf( 732 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 733 , "LockT", "LockU", "Close", "Verify", "NVerify", 734 "PutFH", "PutPubFH", "PutRootFH"); 735 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 736 ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT], 737 ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU], 738 ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE], 739 ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY], 740 ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY], 741 ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH], 742 ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH], 743 ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH]); 744 if (printtitle) 745 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 746 "Renew", "RestoreFH", "SaveFH", "Secinfo", 747 "RelLckOwn", "V4Create"); 748 printf("%9d %9d %9d %9d %9d %9d\n", 749 ext_nfsstats.srvrpccnt[NFSV4OP_RENEW], 750 ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH], 751 ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH], 752 ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO], 753 ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN], 754 ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]); 755 if (printtitle) { 756 printf("Server:\n"); 757 printf("%9.9s %9.9s %9.9s\n", 758 "Retfailed", "Faults", "Clients"); 759 } 760 printf("%9d %9d %9d\n", 761 ext_nfsstats.srv_errs, ext_nfsstats.srvrpc_errs, 762 ext_nfsstats.srvclients); 763 if (printtitle) 764 printf("%9.9s %9.9s %9.9s %9.9s %9.9s \n", 765 "OpenOwner", "Opens", "LockOwner", 766 "Locks", "Delegs"); 767 printf("%9d %9d %9d %9d %9d \n", 768 ext_nfsstats.srvopenowners, 769 ext_nfsstats.srvopens, 770 ext_nfsstats.srvlockowners, 771 ext_nfsstats.srvlocks, 772 ext_nfsstats.srvdelegates); 773 if (printtitle) { 774 printf("Server Cache Stats:\n"); 775 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 776 "Inprog", "Idem", "Non-idem", "Misses", 777 "CacheSize", "TCPPeak"); 778 } 779 printf("%9d %9d %9d %9d %9d %9d\n", 780 ext_nfsstats.srvcache_inproghits, 781 ext_nfsstats.srvcache_idemdonehits, 782 ext_nfsstats.srvcache_nonidemdonehits, 783 ext_nfsstats.srvcache_misses, 784 ext_nfsstats.srvcache_size, 785 ext_nfsstats.srvcache_tcppeak); 786 } 787} 788 789/* 790 * Print a running summary of nfs statistics for the experimental client and/or 791 * server. 792 * Repeat display every interval seconds, showing statistics 793 * collected over that interval. Assumes that interval is non-zero. 794 * First line printed at top of screen is always cumulative. 795 */ 796void 797exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly) 798{ 799 struct ext_nfsstats nfsstats, lastst, *ext_nfsstatsp; 800 int hdrcnt = 1; 801 802 ext_nfsstatsp = &lastst; 803 if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0) 804 err(1, "Can't get stats"); 805 sleep(interval); 806 807 for (;;) { 808 ext_nfsstatsp = &nfsstats; 809 if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0) 810 err(1, "Can't get stats"); 811 812 if (--hdrcnt == 0) { 813 printhdr(clientOnly, serverOnly); 814 if (clientOnly && serverOnly) 815 hdrcnt = 10; 816 else 817 hdrcnt = 20; 818 } 819 if (clientOnly) { 820 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 821 ((clientOnly && serverOnly) ? "Client:" : ""), 822 DELTA(attrcache_hits) + DELTA(attrcache_misses), 823 DELTA(lookupcache_hits) + DELTA(lookupcache_misses), 824 DELTA(biocache_readlinks), 825 DELTA(biocache_reads), 826 DELTA(biocache_writes), 827 nfsstats.rpccnt[NFSPROC_RENAME] - 828 lastst.rpccnt[NFSPROC_RENAME], 829 DELTA(accesscache_hits) + DELTA(accesscache_misses), 830 DELTA(biocache_readdirs) 831 ); 832 if (widemode) { 833 printf(" %s %s %s %s %s %s", 834 sperc1(DELTA(attrcache_hits), 835 DELTA(attrcache_misses)), 836 sperc1(DELTA(lookupcache_hits), 837 DELTA(lookupcache_misses)), 838 sperc2(DELTA(biocache_reads), 839 DELTA(read_bios)), 840 sperc2(DELTA(biocache_writes), 841 DELTA(write_bios)), 842 sperc1(DELTA(accesscache_hits), 843 DELTA(accesscache_misses)), 844 sperc2(DELTA(biocache_readdirs), 845 DELTA(readdir_bios)) 846 ); 847 } 848 printf("\n"); 849 lastst = nfsstats; 850 } 851 if (serverOnly) { 852 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 853 ((clientOnly && serverOnly) ? "Server:" : ""), 854 nfsstats.srvrpccnt[NFSPROC_GETATTR] - 855 lastst.srvrpccnt[NFSPROC_GETATTR], 856 nfsstats.srvrpccnt[NFSPROC_LOOKUP] - 857 lastst.srvrpccnt[NFSPROC_LOOKUP], 858 nfsstats.srvrpccnt[NFSPROC_READLINK] - 859 lastst.srvrpccnt[NFSPROC_READLINK], 860 nfsstats.srvrpccnt[NFSPROC_READ] - 861 lastst.srvrpccnt[NFSPROC_READ], 862 nfsstats.srvrpccnt[NFSPROC_WRITE] - 863 lastst.srvrpccnt[NFSPROC_WRITE], 864 nfsstats.srvrpccnt[NFSPROC_RENAME] - 865 lastst.srvrpccnt[NFSPROC_RENAME], 866 nfsstats.srvrpccnt[NFSPROC_ACCESS] - 867 lastst.srvrpccnt[NFSPROC_ACCESS], 868 (nfsstats.srvrpccnt[NFSPROC_READDIR] - 869 lastst.srvrpccnt[NFSPROC_READDIR]) + 870 (nfsstats.srvrpccnt[NFSPROC_READDIRPLUS] - 871 lastst.srvrpccnt[NFSPROC_READDIRPLUS])); 872 printf("\n"); 873 lastst = nfsstats; 874 } 875 fflush(stdout); 876 sleep(interval); 877 } 878 /*NOTREACHED*/ 879} 880 881