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 34 static 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 41 static char sccsid[] = "@(#)nfsstat.c 8.2 (Berkeley) 3/31/95"; 42 #endif 43 static const char rcsid[] = 44 "$FreeBSD$"; 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 73 struct 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 }; 80 kvm_t *kd; 81 82 static int deadkernel = 0; 83 static int widemode = 0; 84 static int zflag = 0; 85 static int run_v4 = 0; 86 static int printtitle = 1; 87 static struct ext_nfsstats ext_nfsstats; 88 89 void intpr(int, int); 90 void printhdr(int, int); 91 void sidewaysintpr(u_int, int, int); 92 void usage(void); 93 char *sperc1(int, int); 94 char *sperc2(int, int); 95 void exp_intpr(int, int); 96 void exp_sidewaysintpr(u_int, int, int); 97 98 #define DELTA(field) (nfsstats.field - lastst.field) 99 100 int 101 main(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 */ 196 static void 197 readstats(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 */ 239 void 240 intpr(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\n", "DirE 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\n", 331 nfsstats.direofcache_hits, nfsstats.direofcache_misses); 332 } 333 if (serverOnly && !nfsrvstatsp) { 334 printf("Server not present!\n"); 335 serverOnly = 0; 336 } 337 if (serverOnly) { 338 printf("\nServer Info:\n"); 339 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 340 "Getattr", "Setattr", "Lookup", "Readlink", "Read", 341 "Write", "Create", "Remove"); 342 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 343 nfsrvstats.srvrpccnt[NFSPROC_GETATTR], 344 nfsrvstats.srvrpccnt[NFSPROC_SETATTR], 345 nfsrvstats.srvrpccnt[NFSPROC_LOOKUP], 346 nfsrvstats.srvrpccnt[NFSPROC_READLINK], 347 nfsrvstats.srvrpccnt[NFSPROC_READ], 348 nfsrvstats.srvrpccnt[NFSPROC_WRITE], 349 nfsrvstats.srvrpccnt[NFSPROC_CREATE], 350 nfsrvstats.srvrpccnt[NFSPROC_REMOVE]); 351 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 352 "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 353 "Readdir", "RdirPlus", "Access"); 354 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 355 nfsrvstats.srvrpccnt[NFSPROC_RENAME], 356 nfsrvstats.srvrpccnt[NFSPROC_LINK], 357 nfsrvstats.srvrpccnt[NFSPROC_SYMLINK], 358 nfsrvstats.srvrpccnt[NFSPROC_MKDIR], 359 nfsrvstats.srvrpccnt[NFSPROC_RMDIR], 360 nfsrvstats.srvrpccnt[NFSPROC_READDIR], 361 nfsrvstats.srvrpccnt[NFSPROC_READDIRPLUS], 362 nfsrvstats.srvrpccnt[NFSPROC_ACCESS]); 363 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 364 "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit"); 365 printf("%9d %9d %9d %9d %9d\n", 366 nfsrvstats.srvrpccnt[NFSPROC_MKNOD], 367 nfsrvstats.srvrpccnt[NFSPROC_FSSTAT], 368 nfsrvstats.srvrpccnt[NFSPROC_FSINFO], 369 nfsrvstats.srvrpccnt[NFSPROC_PATHCONF], 370 nfsrvstats.srvrpccnt[NFSPROC_COMMIT]); 371 printf("Server Ret-Failed\n"); 372 printf("%17d\n", nfsrvstats.srvrpc_errs); 373 printf("Server Faults\n"); 374 printf("%13d\n", nfsrvstats.srv_errs); 375 printf("Server Cache Stats:\n"); 376 printf("%9.9s %9.9s %9.9s %9.9s\n", 377 "Inprog", "Idem", "Non-idem", "Misses"); 378 printf("%9d %9d %9d %9d\n", 379 nfsrvstats.srvcache_inproghits, 380 nfsrvstats.srvcache_idemdonehits, 381 nfsrvstats.srvcache_nonidemdonehits, 382 nfsrvstats.srvcache_misses); 383 printf("Server Write Gathering:\n"); 384 printf("%9.9s %9.9s %9.9s\n", 385 "WriteOps", "WriteRPC", "Opsaved"); 386 printf("%9d %9d %9d\n", 387 nfsrvstats.srvvop_writes, 388 nfsrvstats.srvrpccnt[NFSPROC_WRITE], 389 nfsrvstats.srvrpccnt[NFSPROC_WRITE] - 390 nfsrvstats.srvvop_writes); 391 } 392 } 393 394 u_char signalled; /* set if alarm goes off "early" */ 395 396 /* 397 * Print a running summary of nfs statistics. 398 * Repeat display every interval seconds, showing statistics 399 * collected over that interval. Assumes that interval is non-zero. 400 * First line printed at top of screen is always cumulative. 401 */ 402 void 403 sidewaysintpr(u_int interval, int clientOnly, int serverOnly) 404 { 405 struct nfsstats nfsstats, lastst, *nfsstatsp; 406 struct nfsrvstats nfsrvstats, lastsrvst, *nfsrvstatsp; 407 int hdrcnt = 1; 408 409 nfsstatsp = &lastst; 410 nfsrvstatsp = &lastsrvst; 411 readstats(&nfsstatsp, &nfsrvstatsp, 0); 412 if (clientOnly && !nfsstatsp) { 413 printf("Client not present!\n"); 414 clientOnly = 0; 415 } 416 if (serverOnly && !nfsrvstatsp) { 417 printf("Server not present!\n"); 418 serverOnly = 0; 419 } 420 sleep(interval); 421 422 for (;;) { 423 nfsstatsp = &nfsstats; 424 nfsrvstatsp = &nfsrvstats; 425 readstats(&nfsstatsp, &nfsrvstatsp, 0); 426 427 if (--hdrcnt == 0) { 428 printhdr(clientOnly, serverOnly); 429 if (clientOnly && serverOnly) 430 hdrcnt = 10; 431 else 432 hdrcnt = 20; 433 } 434 if (clientOnly) { 435 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 436 ((clientOnly && serverOnly) ? "Client:" : ""), 437 DELTA(attrcache_hits) + DELTA(attrcache_misses), 438 DELTA(lookupcache_hits) + DELTA(lookupcache_misses), 439 DELTA(biocache_readlinks), 440 DELTA(biocache_reads), 441 DELTA(biocache_writes), 442 nfsstats.rpccnt[NFSPROC_RENAME]-lastst.rpccnt[NFSPROC_RENAME], 443 DELTA(accesscache_hits) + DELTA(accesscache_misses), 444 DELTA(biocache_readdirs) 445 ); 446 if (widemode) { 447 printf(" %s %s %s %s %s %s", 448 sperc1(DELTA(attrcache_hits), 449 DELTA(attrcache_misses)), 450 sperc1(DELTA(lookupcache_hits), 451 DELTA(lookupcache_misses)), 452 sperc2(DELTA(biocache_reads), 453 DELTA(read_bios)), 454 sperc2(DELTA(biocache_writes), 455 DELTA(write_bios)), 456 sperc1(DELTA(accesscache_hits), 457 DELTA(accesscache_misses)), 458 sperc2(DELTA(biocache_readdirs), 459 DELTA(readdir_bios)) 460 ); 461 } 462 printf("\n"); 463 lastst = nfsstats; 464 } 465 if (serverOnly) { 466 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 467 ((clientOnly && serverOnly) ? "Server:" : ""), 468 nfsrvstats.srvrpccnt[NFSPROC_GETATTR]-lastsrvst.srvrpccnt[NFSPROC_GETATTR], 469 nfsrvstats.srvrpccnt[NFSPROC_LOOKUP]-lastsrvst.srvrpccnt[NFSPROC_LOOKUP], 470 nfsrvstats.srvrpccnt[NFSPROC_READLINK]-lastsrvst.srvrpccnt[NFSPROC_READLINK], 471 nfsrvstats.srvrpccnt[NFSPROC_READ]-lastsrvst.srvrpccnt[NFSPROC_READ], 472 nfsrvstats.srvrpccnt[NFSPROC_WRITE]-lastsrvst.srvrpccnt[NFSPROC_WRITE], 473 nfsrvstats.srvrpccnt[NFSPROC_RENAME]-lastsrvst.srvrpccnt[NFSPROC_RENAME], 474 nfsrvstats.srvrpccnt[NFSPROC_ACCESS]-lastsrvst.srvrpccnt[NFSPROC_ACCESS], 475 (nfsrvstats.srvrpccnt[NFSPROC_READDIR]-lastsrvst.srvrpccnt[NFSPROC_READDIR]) 476 +(nfsrvstats.srvrpccnt[NFSPROC_READDIRPLUS]-lastsrvst.srvrpccnt[NFSPROC_READDIRPLUS])); 477 printf("\n"); 478 lastsrvst = nfsrvstats; 479 } 480 fflush(stdout); 481 sleep(interval); 482 } 483 /*NOTREACHED*/ 484 } 485 486 void 487 printhdr(int clientOnly, int serverOnly) 488 { 489 printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s", 490 ((serverOnly && clientOnly) ? " " : " "), 491 "GtAttr", "Lookup", "Rdlink", "Read", "Write", "Rename", 492 "Access", "Rddir"); 493 if (widemode && clientOnly) { 494 printf(" Attr Lkup BioR BioW Accs BioD"); 495 } 496 printf("\n"); 497 fflush(stdout); 498 } 499 500 void 501 usage(void) 502 { 503 (void)fprintf(stderr, 504 "usage: nfsstat [-ceszW] [-M core] [-N system] [-w interval]\n"); 505 exit(1); 506 } 507 508 static char SPBuf[64][8]; 509 static int SPIndex; 510 511 char * 512 sperc1(int hits, int misses) 513 { 514 char *p = SPBuf[SPIndex]; 515 516 if (hits + misses) { 517 sprintf(p, "%3d%%", 518 (int)(char)((quad_t)hits * 100 / (hits + misses))); 519 } else { 520 sprintf(p, " -"); 521 } 522 SPIndex = (SPIndex + 1) & 63; 523 return(p); 524 } 525 526 char * 527 sperc2(int ttl, int misses) 528 { 529 char *p = SPBuf[SPIndex]; 530 531 if (ttl) { 532 sprintf(p, "%3d%%", 533 (int)(char)((quad_t)(ttl - misses) * 100 / ttl)); 534 } else { 535 sprintf(p, " -"); 536 } 537 SPIndex = (SPIndex + 1) & 63; 538 return(p); 539 } 540 541 /* 542 * Print a description of the nfs stats for the experimental client/server. 543 */ 544 void 545 exp_intpr(int clientOnly, int serverOnly) 546 { 547 548 if (clientOnly != 0) { 549 if (printtitle) { 550 printf("Client Info:\n"); 551 printf("Rpc Counts:\n"); 552 printf( 553 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 554 , "Getattr", "Setattr", "Lookup", "Readlink", 555 "Read", "Write", "Create", "Remove"); 556 } 557 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 558 ext_nfsstats.rpccnt[NFSPROC_GETATTR], 559 ext_nfsstats.rpccnt[NFSPROC_SETATTR], 560 ext_nfsstats.rpccnt[NFSPROC_LOOKUP], 561 ext_nfsstats.rpccnt[NFSPROC_READLINK], 562 ext_nfsstats.rpccnt[NFSPROC_READ], 563 ext_nfsstats.rpccnt[NFSPROC_WRITE], 564 ext_nfsstats.rpccnt[NFSPROC_CREATE], 565 ext_nfsstats.rpccnt[NFSPROC_REMOVE]); 566 if (printtitle) 567 printf( 568 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 569 , "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 570 "Readdir", "RdirPlus", "Access"); 571 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 572 ext_nfsstats.rpccnt[NFSPROC_RENAME], 573 ext_nfsstats.rpccnt[NFSPROC_LINK], 574 ext_nfsstats.rpccnt[NFSPROC_SYMLINK], 575 ext_nfsstats.rpccnt[NFSPROC_MKDIR], 576 ext_nfsstats.rpccnt[NFSPROC_RMDIR], 577 ext_nfsstats.rpccnt[NFSPROC_READDIR], 578 ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS], 579 ext_nfsstats.rpccnt[NFSPROC_ACCESS]); 580 if (printtitle) 581 printf( 582 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 583 , "Mknod", "Fsstat", "Fsinfo", "PathConf", 584 "Commit", "SetClId", "SetClIdCf", "Lock"); 585 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 586 ext_nfsstats.rpccnt[NFSPROC_MKNOD], 587 ext_nfsstats.rpccnt[NFSPROC_FSSTAT], 588 ext_nfsstats.rpccnt[NFSPROC_FSINFO], 589 ext_nfsstats.rpccnt[NFSPROC_PATHCONF], 590 ext_nfsstats.rpccnt[NFSPROC_COMMIT], 591 ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID], 592 ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM], 593 ext_nfsstats.rpccnt[NFSPROC_LOCK]); 594 if (printtitle) 595 printf("%9.9s %9.9s %9.9s %9.9s\n", 596 "LockT", "LockU", "Open", "OpenCfr"); 597 printf("%9d %9d %9d %9d\n", 598 ext_nfsstats.rpccnt[NFSPROC_LOCKT], 599 ext_nfsstats.rpccnt[NFSPROC_LOCKU], 600 ext_nfsstats.rpccnt[NFSPROC_OPEN], 601 ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM]); 602 if (printtitle) 603 printf( 604 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 605 , "OpenOwner", "Opens", "LockOwner", 606 "Locks", "Delegs", "LocalOwn", 607 "LocalOpen", "LocalLOwn"); 608 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 609 ext_nfsstats.clopenowners, 610 ext_nfsstats.clopens, 611 ext_nfsstats.cllockowners, 612 ext_nfsstats.cllocks, 613 ext_nfsstats.cldelegates, 614 ext_nfsstats.cllocalopenowners, 615 ext_nfsstats.cllocalopens, 616 ext_nfsstats.cllocallockowners); 617 if (printtitle) 618 printf("%9.9s\n", "LocalLock"); 619 printf("%9d\n", ext_nfsstats.cllocallocks); 620 if (printtitle) { 621 printf("Rpc Info:\n"); 622 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 623 "TimedOut", "Invalid", "X Replies", "Retries", 624 "Requests"); 625 } 626 printf("%9d %9d %9d %9d %9d\n", 627 ext_nfsstats.rpctimeouts, 628 ext_nfsstats.rpcinvalid, 629 ext_nfsstats.rpcunexpected, 630 ext_nfsstats.rpcretries, 631 ext_nfsstats.rpcrequests); 632 if (printtitle) { 633 printf("Cache Info:\n"); 634 printf("%9.9s %9.9s %9.9s %9.9s", 635 "Attr Hits", "Misses", "Lkup Hits", "Misses"); 636 printf(" %9.9s %9.9s %9.9s %9.9s\n", 637 "BioR Hits", "Misses", "BioW Hits", "Misses"); 638 } 639 printf("%9d %9d %9d %9d", 640 ext_nfsstats.attrcache_hits, 641 ext_nfsstats.attrcache_misses, 642 ext_nfsstats.lookupcache_hits, 643 ext_nfsstats.lookupcache_misses); 644 printf(" %9d %9d %9d %9d\n", 645 ext_nfsstats.biocache_reads, 646 ext_nfsstats.read_bios, 647 ext_nfsstats.biocache_writes, 648 ext_nfsstats.write_bios); 649 if (printtitle) { 650 printf("%9.9s %9.9s %9.9s %9.9s", 651 "BioRLHits", "Misses", "BioD Hits", "Misses"); 652 printf(" %9.9s %9.9s\n", "DirE Hits", "Misses"); 653 } 654 printf("%9d %9d %9d %9d", 655 ext_nfsstats.biocache_readlinks, 656 ext_nfsstats.readlink_bios, 657 ext_nfsstats.biocache_readdirs, 658 ext_nfsstats.readdir_bios); 659 printf(" %9d %9d\n", 660 ext_nfsstats.direofcache_hits, 661 ext_nfsstats.direofcache_misses); 662 } 663 if (serverOnly != 0) { 664 if (printtitle) { 665 printf("\nServer Info:\n"); 666 printf( 667 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 668 , "Getattr", "Setattr", "Lookup", "Readlink", 669 "Read", "Write", "Create", "Remove"); 670 } 671 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 672 ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR], 673 ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR], 674 ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP], 675 ext_nfsstats.srvrpccnt[NFSV4OP_READLINK], 676 ext_nfsstats.srvrpccnt[NFSV4OP_READ], 677 ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 678 ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE], 679 ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]); 680 if (printtitle) 681 printf( 682 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 683 , "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 684 "Readdir", "RdirPlus", "Access"); 685 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 686 ext_nfsstats.srvrpccnt[NFSV4OP_RENAME], 687 ext_nfsstats.srvrpccnt[NFSV4OP_LINK], 688 ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK], 689 ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR], 690 ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR], 691 ext_nfsstats.srvrpccnt[NFSV4OP_READDIR], 692 ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS], 693 ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]); 694 if (printtitle) 695 printf( 696 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 697 , "Mknod", "Fsstat", "Fsinfo", "PathConf", 698 "Commit", "LookupP", "SetClId", "SetClIdCf"); 699 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 700 ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD], 701 ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT], 702 ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO], 703 ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF], 704 ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT], 705 ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP], 706 ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID], 707 ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]); 708 if (printtitle) 709 printf( 710 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 711 , "Open", "OpenAttr", "OpenDwnGr", "OpenCfrm", 712 "DelePurge", "DeleRet", "GetFH", "Lock"); 713 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 714 ext_nfsstats.srvrpccnt[NFSV4OP_OPEN], 715 ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR], 716 ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE], 717 ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM], 718 ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE], 719 ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN], 720 ext_nfsstats.srvrpccnt[NFSV4OP_GETFH], 721 ext_nfsstats.srvrpccnt[NFSV4OP_LOCK]); 722 if (printtitle) 723 printf( 724 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 725 , "LockT", "LockU", "Close", "Verify", "NVerify", 726 "PutFH", "PutPubFH", "PutRootFH"); 727 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 728 ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT], 729 ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU], 730 ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE], 731 ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY], 732 ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY], 733 ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH], 734 ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH], 735 ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH]); 736 if (printtitle) 737 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 738 "Renew", "RestoreFH", "SaveFH", "Secinfo", 739 "RelLckOwn", "V4Create"); 740 printf("%9d %9d %9d %9d %9d %9d\n", 741 ext_nfsstats.srvrpccnt[NFSV4OP_RENEW], 742 ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH], 743 ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH], 744 ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO], 745 ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN], 746 ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]); 747 if (printtitle) { 748 printf("Server:\n"); 749 printf("%9.9s %9.9s %9.9s\n", 750 "Retfailed", "Faults", "Clients"); 751 } 752 printf("%9d %9d %9d\n", 753 ext_nfsstats.srv_errs, ext_nfsstats.srvrpc_errs, 754 ext_nfsstats.srvclients); 755 if (printtitle) 756 printf("%9.9s %9.9s %9.9s %9.9s %9.9s \n", 757 "OpenOwner", "Opens", "LockOwner", 758 "Locks", "Delegs"); 759 printf("%9d %9d %9d %9d %9d \n", 760 ext_nfsstats.srvopenowners, 761 ext_nfsstats.srvopens, 762 ext_nfsstats.srvlockowners, 763 ext_nfsstats.srvlocks, 764 ext_nfsstats.srvdelegates); 765 if (printtitle) { 766 printf("Server Cache Stats:\n"); 767 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 768 "Inprog", "Idem", "Non-idem", "Misses", 769 "CacheSize", "TCPPeak"); 770 } 771 printf("%9d %9d %9d %9d %9d %9d\n", 772 ext_nfsstats.srvcache_inproghits, 773 ext_nfsstats.srvcache_idemdonehits, 774 ext_nfsstats.srvcache_nonidemdonehits, 775 ext_nfsstats.srvcache_misses, 776 ext_nfsstats.srvcache_size, 777 ext_nfsstats.srvcache_tcppeak); 778 } 779 } 780 781 /* 782 * Print a running summary of nfs statistics for the experimental client and/or 783 * server. 784 * Repeat display every interval seconds, showing statistics 785 * collected over that interval. Assumes that interval is non-zero. 786 * First line printed at top of screen is always cumulative. 787 */ 788 void 789 exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly) 790 { 791 struct ext_nfsstats nfsstats, lastst, *ext_nfsstatsp; 792 int hdrcnt = 1; 793 794 ext_nfsstatsp = &lastst; 795 if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0) 796 err(1, "Can't get stats"); 797 sleep(interval); 798 799 for (;;) { 800 ext_nfsstatsp = &nfsstats; 801 if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0) 802 err(1, "Can't get stats"); 803 804 if (--hdrcnt == 0) { 805 printhdr(clientOnly, serverOnly); 806 if (clientOnly && serverOnly) 807 hdrcnt = 10; 808 else 809 hdrcnt = 20; 810 } 811 if (clientOnly) { 812 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 813 ((clientOnly && serverOnly) ? "Client:" : ""), 814 DELTA(attrcache_hits) + DELTA(attrcache_misses), 815 DELTA(lookupcache_hits) + DELTA(lookupcache_misses), 816 DELTA(biocache_readlinks), 817 DELTA(biocache_reads), 818 DELTA(biocache_writes), 819 nfsstats.rpccnt[NFSPROC_RENAME] - 820 lastst.rpccnt[NFSPROC_RENAME], 821 DELTA(accesscache_hits) + DELTA(accesscache_misses), 822 DELTA(biocache_readdirs) 823 ); 824 if (widemode) { 825 printf(" %s %s %s %s %s %s", 826 sperc1(DELTA(attrcache_hits), 827 DELTA(attrcache_misses)), 828 sperc1(DELTA(lookupcache_hits), 829 DELTA(lookupcache_misses)), 830 sperc2(DELTA(biocache_reads), 831 DELTA(read_bios)), 832 sperc2(DELTA(biocache_writes), 833 DELTA(write_bios)), 834 sperc1(DELTA(accesscache_hits), 835 DELTA(accesscache_misses)), 836 sperc2(DELTA(biocache_readdirs), 837 DELTA(readdir_bios)) 838 ); 839 } 840 printf("\n"); 841 lastst = nfsstats; 842 } 843 if (serverOnly) { 844 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 845 ((clientOnly && serverOnly) ? "Server:" : ""), 846 nfsstats.srvrpccnt[NFSPROC_GETATTR] - 847 lastst.srvrpccnt[NFSPROC_GETATTR], 848 nfsstats.srvrpccnt[NFSPROC_LOOKUP] - 849 lastst.srvrpccnt[NFSPROC_LOOKUP], 850 nfsstats.srvrpccnt[NFSPROC_READLINK] - 851 lastst.srvrpccnt[NFSPROC_READLINK], 852 nfsstats.srvrpccnt[NFSPROC_READ] - 853 lastst.srvrpccnt[NFSPROC_READ], 854 nfsstats.srvrpccnt[NFSPROC_WRITE] - 855 lastst.srvrpccnt[NFSPROC_WRITE], 856 nfsstats.srvrpccnt[NFSPROC_RENAME] - 857 lastst.srvrpccnt[NFSPROC_RENAME], 858 nfsstats.srvrpccnt[NFSPROC_ACCESS] - 859 lastst.srvrpccnt[NFSPROC_ACCESS], 860 (nfsstats.srvrpccnt[NFSPROC_READDIR] - 861 lastst.srvrpccnt[NFSPROC_READDIR]) + 862 (nfsstats.srvrpccnt[NFSPROC_READDIRPLUS] - 863 lastst.srvrpccnt[NFSPROC_READDIRPLUS])); 864 printf("\n"); 865 lastst = nfsstats; 866 } 867 fflush(stdout); 868 sleep(interval); 869 } 870 /*NOTREACHED*/ 871 } 872 873