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 static int widemode = 0; 74 static int zflag = 0; 75 static int printtitle = 1; 76 static struct ext_nfsstats ext_nfsstats; 77 static int extra_output = 0; 78 79 static void intpr(int, int); 80 static void printhdr(int, int); 81 static void usage(void); 82 static char *sperc1(int, int); 83 static char *sperc2(int, int); 84 static void exp_intpr(int, int); 85 static void exp_sidewaysintpr(u_int, int, int); 86 87 #define DELTA(field) (nfsstats.field - lastst.field) 88 89 int 90 main(int argc, char **argv) 91 { 92 u_int interval; 93 int clientOnly = -1; 94 int serverOnly = -1; 95 int ch; 96 char *memf, *nlistf; 97 int mntlen, i; 98 char buf[1024]; 99 struct statfs *mntbuf; 100 struct nfscl_dumpmntopts dumpmntopts; 101 102 interval = 0; 103 memf = nlistf = NULL; 104 while ((ch = getopt(argc, argv, "cesWM:mN:w:z")) != -1) 105 switch(ch) { 106 case 'M': 107 memf = optarg; 108 break; 109 case 'm': 110 /* Display mount options for NFS mount points. */ 111 mntlen = getmntinfo(&mntbuf, MNT_NOWAIT); 112 for (i = 0; i < mntlen; i++) { 113 if (strcmp(mntbuf->f_fstypename, "nfs") == 0) { 114 dumpmntopts.ndmnt_fname = 115 mntbuf->f_mntonname; 116 dumpmntopts.ndmnt_buf = buf; 117 dumpmntopts.ndmnt_blen = sizeof(buf); 118 if (nfssvc(NFSSVC_DUMPMNTOPTS, 119 &dumpmntopts) >= 0) 120 printf("%s on %s\n%s\n", 121 mntbuf->f_mntfromname, 122 mntbuf->f_mntonname, buf); 123 else if (errno == EPERM) 124 errx(1, "Only priviledged users" 125 " can use the -m option"); 126 } 127 mntbuf++; 128 } 129 exit(0); 130 case 'N': 131 nlistf = optarg; 132 break; 133 case 'W': 134 widemode = 1; 135 break; 136 case 'w': 137 interval = atoi(optarg); 138 break; 139 case 'c': 140 clientOnly = 1; 141 if (serverOnly < 0) 142 serverOnly = 0; 143 break; 144 case 's': 145 serverOnly = 1; 146 if (clientOnly < 0) 147 clientOnly = 0; 148 break; 149 case 'z': 150 zflag = 1; 151 break; 152 case 'e': 153 extra_output = 1; 154 break; 155 case '?': 156 default: 157 usage(); 158 } 159 argc -= optind; 160 argv += optind; 161 162 #define BACKWARD_COMPATIBILITY 163 #ifdef BACKWARD_COMPATIBILITY 164 if (*argv) { 165 interval = atoi(*argv); 166 if (*++argv) { 167 nlistf = *argv; 168 if (*++argv) 169 memf = *argv; 170 } 171 } 172 #endif 173 if (modfind("nfscommon") < 0) 174 errx(1, "NFS client/server not loaded"); 175 176 if (interval) { 177 exp_sidewaysintpr(interval, clientOnly, serverOnly); 178 } else { 179 if (extra_output != 0) 180 exp_intpr(clientOnly, serverOnly); 181 else 182 intpr(clientOnly, serverOnly); 183 } 184 exit(0); 185 } 186 187 /* 188 * Print a description of the nfs stats. 189 */ 190 static void 191 intpr(int clientOnly, int serverOnly) 192 { 193 int nfssvc_flag; 194 195 nfssvc_flag = NFSSVC_GETSTATS; 196 if (zflag != 0) { 197 if (clientOnly != 0) 198 nfssvc_flag |= NFSSVC_ZEROCLTSTATS; 199 if (serverOnly != 0) 200 nfssvc_flag |= NFSSVC_ZEROSRVSTATS; 201 } 202 if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0) 203 err(1, "Can't get stats"); 204 if (clientOnly) { 205 printf("Client Info:\n"); 206 printf("Rpc Counts:\n"); 207 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 208 "Getattr", "Setattr", "Lookup", "Readlink", "Read", 209 "Write", "Create", "Remove"); 210 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 211 ext_nfsstats.rpccnt[NFSPROC_GETATTR], 212 ext_nfsstats.rpccnt[NFSPROC_SETATTR], 213 ext_nfsstats.rpccnt[NFSPROC_LOOKUP], 214 ext_nfsstats.rpccnt[NFSPROC_READLINK], 215 ext_nfsstats.rpccnt[NFSPROC_READ], 216 ext_nfsstats.rpccnt[NFSPROC_WRITE], 217 ext_nfsstats.rpccnt[NFSPROC_CREATE], 218 ext_nfsstats.rpccnt[NFSPROC_REMOVE]); 219 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 220 "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 221 "Readdir", "RdirPlus", "Access"); 222 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 223 ext_nfsstats.rpccnt[NFSPROC_RENAME], 224 ext_nfsstats.rpccnt[NFSPROC_LINK], 225 ext_nfsstats.rpccnt[NFSPROC_SYMLINK], 226 ext_nfsstats.rpccnt[NFSPROC_MKDIR], 227 ext_nfsstats.rpccnt[NFSPROC_RMDIR], 228 ext_nfsstats.rpccnt[NFSPROC_READDIR], 229 ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS], 230 ext_nfsstats.rpccnt[NFSPROC_ACCESS]); 231 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 232 "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit"); 233 printf("%9d %9d %9d %9d %9d\n", 234 ext_nfsstats.rpccnt[NFSPROC_MKNOD], 235 ext_nfsstats.rpccnt[NFSPROC_FSSTAT], 236 ext_nfsstats.rpccnt[NFSPROC_FSINFO], 237 ext_nfsstats.rpccnt[NFSPROC_PATHCONF], 238 ext_nfsstats.rpccnt[NFSPROC_COMMIT]); 239 printf("Rpc Info:\n"); 240 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 241 "TimedOut", "Invalid", "X Replies", "Retries", 242 "Requests"); 243 printf("%9d %9d %9d %9d %9d\n", 244 ext_nfsstats.rpctimeouts, 245 ext_nfsstats.rpcinvalid, 246 ext_nfsstats.rpcunexpected, 247 ext_nfsstats.rpcretries, 248 ext_nfsstats.rpcrequests); 249 printf("Cache Info:\n"); 250 printf("%9.9s %9.9s %9.9s %9.9s", 251 "Attr Hits", "Misses", "Lkup Hits", "Misses"); 252 printf(" %9.9s %9.9s %9.9s %9.9s\n", 253 "BioR Hits", "Misses", "BioW Hits", "Misses"); 254 printf("%9d %9d %9d %9d", 255 ext_nfsstats.attrcache_hits, 256 ext_nfsstats.attrcache_misses, 257 ext_nfsstats.lookupcache_hits, 258 ext_nfsstats.lookupcache_misses); 259 printf(" %9d %9d %9d %9d\n", 260 ext_nfsstats.biocache_reads - 261 ext_nfsstats.read_bios, 262 ext_nfsstats.read_bios, 263 ext_nfsstats.biocache_writes - 264 ext_nfsstats.write_bios, 265 ext_nfsstats.write_bios); 266 printf("%9.9s %9.9s %9.9s %9.9s", 267 "BioRLHits", "Misses", "BioD Hits", "Misses"); 268 printf(" %9.9s %9.9s %9.9s %9.9s\n", "DirE Hits", "Misses", "Accs Hits", "Misses"); 269 printf("%9d %9d %9d %9d", 270 ext_nfsstats.biocache_readlinks - 271 ext_nfsstats.readlink_bios, 272 ext_nfsstats.readlink_bios, 273 ext_nfsstats.biocache_readdirs - 274 ext_nfsstats.readdir_bios, 275 ext_nfsstats.readdir_bios); 276 printf(" %9d %9d %9d %9d\n", 277 ext_nfsstats.direofcache_hits, 278 ext_nfsstats.direofcache_misses, 279 ext_nfsstats.accesscache_hits, 280 ext_nfsstats.accesscache_misses); 281 } 282 if (serverOnly) { 283 printf("\nServer Info:\n"); 284 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 285 "Getattr", "Setattr", "Lookup", "Readlink", "Read", 286 "Write", "Create", "Remove"); 287 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 288 ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR], 289 ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR], 290 ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP], 291 ext_nfsstats.srvrpccnt[NFSV4OP_READLINK], 292 ext_nfsstats.srvrpccnt[NFSV4OP_READ], 293 ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 294 ext_nfsstats.srvrpccnt[NFSV4OP_CREATE], 295 ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]); 296 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 297 "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 298 "Readdir", "RdirPlus", "Access"); 299 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 300 ext_nfsstats.srvrpccnt[NFSV4OP_RENAME], 301 ext_nfsstats.srvrpccnt[NFSV4OP_LINK], 302 ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK], 303 ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR], 304 ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR], 305 ext_nfsstats.srvrpccnt[NFSV4OP_READDIR], 306 ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS], 307 ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]); 308 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 309 "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit"); 310 printf("%9d %9d %9d %9d %9d\n", 311 ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD], 312 ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT], 313 ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO], 314 ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF], 315 ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT]); 316 printf("Server Ret-Failed\n"); 317 printf("%17d\n", ext_nfsstats.srvrpc_errs); 318 printf("Server Faults\n"); 319 printf("%13d\n", ext_nfsstats.srv_errs); 320 printf("Server Cache Stats:\n"); 321 printf("%9.9s %9.9s %9.9s %9.9s\n", 322 "Inprog", "Idem", "Non-idem", "Misses"); 323 printf("%9d %9d %9d %9d\n", 324 ext_nfsstats.srvcache_inproghits, 325 ext_nfsstats.srvcache_idemdonehits, 326 ext_nfsstats.srvcache_nonidemdonehits, 327 ext_nfsstats.srvcache_misses); 328 printf("Server Write Gathering:\n"); 329 printf("%9.9s %9.9s %9.9s\n", 330 "WriteOps", "WriteRPC", "Opsaved"); 331 /* 332 * The new client doesn't do write gathering. It was 333 * only useful for NFSv2. 334 */ 335 printf("%9d %9d %9d\n", 336 ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 337 ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 0); 338 } 339 } 340 341 static void 342 printhdr(int clientOnly, int serverOnly) 343 { 344 printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s", 345 ((serverOnly && clientOnly) ? " " : " "), 346 "GtAttr", "Lookup", "Rdlink", "Read", "Write", "Rename", 347 "Access", "Rddir"); 348 if (widemode && clientOnly) { 349 printf(" Attr Lkup BioR BioW Accs BioD"); 350 } 351 printf("\n"); 352 fflush(stdout); 353 } 354 355 static void 356 usage(void) 357 { 358 (void)fprintf(stderr, 359 "usage: nfsstat [-cemszW] [-M core] [-N system] [-w wait]\n"); 360 exit(1); 361 } 362 363 static char SPBuf[64][8]; 364 static int SPIndex; 365 366 static char * 367 sperc1(int hits, int misses) 368 { 369 char *p = SPBuf[SPIndex]; 370 371 if (hits + misses) { 372 sprintf(p, "%3d%%", 373 (int)(char)((quad_t)hits * 100 / (hits + misses))); 374 } else { 375 sprintf(p, " -"); 376 } 377 SPIndex = (SPIndex + 1) & 63; 378 return(p); 379 } 380 381 static char * 382 sperc2(int ttl, int misses) 383 { 384 char *p = SPBuf[SPIndex]; 385 386 if (ttl) { 387 sprintf(p, "%3d%%", 388 (int)(char)((quad_t)(ttl - misses) * 100 / ttl)); 389 } else { 390 sprintf(p, " -"); 391 } 392 SPIndex = (SPIndex + 1) & 63; 393 return(p); 394 } 395 396 /* 397 * Print a description of the nfs stats for the experimental client/server. 398 */ 399 static void 400 exp_intpr(int clientOnly, int serverOnly) 401 { 402 int nfssvc_flag; 403 404 nfssvc_flag = NFSSVC_GETSTATS; 405 if (zflag != 0) { 406 if (clientOnly != 0) 407 nfssvc_flag |= NFSSVC_ZEROCLTSTATS; 408 if (serverOnly != 0) 409 nfssvc_flag |= NFSSVC_ZEROSRVSTATS; 410 } 411 if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0) 412 err(1, "Can't get stats"); 413 if (clientOnly != 0) { 414 if (printtitle) { 415 printf("Client Info:\n"); 416 printf("Rpc Counts:\n"); 417 printf( 418 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 419 , "Getattr", "Setattr", "Lookup", "Readlink", 420 "Read", "Write", "Create", "Remove"); 421 } 422 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 423 ext_nfsstats.rpccnt[NFSPROC_GETATTR], 424 ext_nfsstats.rpccnt[NFSPROC_SETATTR], 425 ext_nfsstats.rpccnt[NFSPROC_LOOKUP], 426 ext_nfsstats.rpccnt[NFSPROC_READLINK], 427 ext_nfsstats.rpccnt[NFSPROC_READ], 428 ext_nfsstats.rpccnt[NFSPROC_WRITE], 429 ext_nfsstats.rpccnt[NFSPROC_CREATE], 430 ext_nfsstats.rpccnt[NFSPROC_REMOVE]); 431 if (printtitle) 432 printf( 433 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 434 , "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 435 "Readdir", "RdirPlus", "Access"); 436 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 437 ext_nfsstats.rpccnt[NFSPROC_RENAME], 438 ext_nfsstats.rpccnt[NFSPROC_LINK], 439 ext_nfsstats.rpccnt[NFSPROC_SYMLINK], 440 ext_nfsstats.rpccnt[NFSPROC_MKDIR], 441 ext_nfsstats.rpccnt[NFSPROC_RMDIR], 442 ext_nfsstats.rpccnt[NFSPROC_READDIR], 443 ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS], 444 ext_nfsstats.rpccnt[NFSPROC_ACCESS]); 445 if (printtitle) 446 printf( 447 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 448 , "Mknod", "Fsstat", "Fsinfo", "PathConf", 449 "Commit", "SetClId", "SetClIdCf", "Lock"); 450 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 451 ext_nfsstats.rpccnt[NFSPROC_MKNOD], 452 ext_nfsstats.rpccnt[NFSPROC_FSSTAT], 453 ext_nfsstats.rpccnt[NFSPROC_FSINFO], 454 ext_nfsstats.rpccnt[NFSPROC_PATHCONF], 455 ext_nfsstats.rpccnt[NFSPROC_COMMIT], 456 ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID], 457 ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM], 458 ext_nfsstats.rpccnt[NFSPROC_LOCK]); 459 if (printtitle) 460 printf("%9.9s %9.9s %9.9s %9.9s\n", 461 "LockT", "LockU", "Open", "OpenCfr"); 462 printf("%9d %9d %9d %9d\n", 463 ext_nfsstats.rpccnt[NFSPROC_LOCKT], 464 ext_nfsstats.rpccnt[NFSPROC_LOCKU], 465 ext_nfsstats.rpccnt[NFSPROC_OPEN], 466 ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM]); 467 if (printtitle) 468 printf( 469 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 470 , "OpenOwner", "Opens", "LockOwner", 471 "Locks", "Delegs", "LocalOwn", 472 "LocalOpen", "LocalLOwn"); 473 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 474 ext_nfsstats.clopenowners, 475 ext_nfsstats.clopens, 476 ext_nfsstats.cllockowners, 477 ext_nfsstats.cllocks, 478 ext_nfsstats.cldelegates, 479 ext_nfsstats.cllocalopenowners, 480 ext_nfsstats.cllocalopens, 481 ext_nfsstats.cllocallockowners); 482 if (printtitle) 483 printf("%9.9s\n", "LocalLock"); 484 printf("%9d\n", ext_nfsstats.cllocallocks); 485 if (printtitle) { 486 printf("Rpc Info:\n"); 487 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", 488 "TimedOut", "Invalid", "X Replies", "Retries", 489 "Requests"); 490 } 491 printf("%9d %9d %9d %9d %9d\n", 492 ext_nfsstats.rpctimeouts, 493 ext_nfsstats.rpcinvalid, 494 ext_nfsstats.rpcunexpected, 495 ext_nfsstats.rpcretries, 496 ext_nfsstats.rpcrequests); 497 if (printtitle) { 498 printf("Cache Info:\n"); 499 printf("%9.9s %9.9s %9.9s %9.9s", 500 "Attr Hits", "Misses", "Lkup Hits", "Misses"); 501 printf(" %9.9s %9.9s %9.9s %9.9s\n", 502 "BioR Hits", "Misses", "BioW Hits", "Misses"); 503 } 504 printf("%9d %9d %9d %9d", 505 ext_nfsstats.attrcache_hits, 506 ext_nfsstats.attrcache_misses, 507 ext_nfsstats.lookupcache_hits, 508 ext_nfsstats.lookupcache_misses); 509 printf(" %9d %9d %9d %9d\n", 510 ext_nfsstats.biocache_reads - ext_nfsstats.read_bios, 511 ext_nfsstats.read_bios, 512 ext_nfsstats.biocache_writes - ext_nfsstats.write_bios, 513 ext_nfsstats.write_bios); 514 if (printtitle) { 515 printf("%9.9s %9.9s %9.9s %9.9s", 516 "BioRLHits", "Misses", "BioD Hits", "Misses"); 517 printf(" %9.9s %9.9s\n", "DirE Hits", "Misses"); 518 } 519 printf("%9d %9d %9d %9d", 520 ext_nfsstats.biocache_readlinks - 521 ext_nfsstats.readlink_bios, 522 ext_nfsstats.readlink_bios, 523 ext_nfsstats.biocache_readdirs - 524 ext_nfsstats.readdir_bios, 525 ext_nfsstats.readdir_bios); 526 printf(" %9d %9d\n", 527 ext_nfsstats.direofcache_hits, 528 ext_nfsstats.direofcache_misses); 529 } 530 if (serverOnly != 0) { 531 if (printtitle) { 532 printf("\nServer Info:\n"); 533 printf( 534 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 535 , "Getattr", "Setattr", "Lookup", "Readlink", 536 "Read", "Write", "Create", "Remove"); 537 } 538 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 539 ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR], 540 ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR], 541 ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP], 542 ext_nfsstats.srvrpccnt[NFSV4OP_READLINK], 543 ext_nfsstats.srvrpccnt[NFSV4OP_READ], 544 ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 545 ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE], 546 ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]); 547 if (printtitle) 548 printf( 549 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 550 , "Rename", "Link", "Symlink", "Mkdir", "Rmdir", 551 "Readdir", "RdirPlus", "Access"); 552 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 553 ext_nfsstats.srvrpccnt[NFSV4OP_RENAME], 554 ext_nfsstats.srvrpccnt[NFSV4OP_LINK], 555 ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK], 556 ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR], 557 ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR], 558 ext_nfsstats.srvrpccnt[NFSV4OP_READDIR], 559 ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS], 560 ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]); 561 if (printtitle) 562 printf( 563 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 564 , "Mknod", "Fsstat", "Fsinfo", "PathConf", 565 "Commit", "LookupP", "SetClId", "SetClIdCf"); 566 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 567 ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD], 568 ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT], 569 ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO], 570 ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF], 571 ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT], 572 ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP], 573 ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID], 574 ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]); 575 if (printtitle) 576 printf( 577 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 578 , "Open", "OpenAttr", "OpenDwnGr", "OpenCfrm", 579 "DelePurge", "DeleRet", "GetFH", "Lock"); 580 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 581 ext_nfsstats.srvrpccnt[NFSV4OP_OPEN], 582 ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR], 583 ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE], 584 ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM], 585 ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE], 586 ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN], 587 ext_nfsstats.srvrpccnt[NFSV4OP_GETFH], 588 ext_nfsstats.srvrpccnt[NFSV4OP_LOCK]); 589 if (printtitle) 590 printf( 591 "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" 592 , "LockT", "LockU", "Close", "Verify", "NVerify", 593 "PutFH", "PutPubFH", "PutRootFH"); 594 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", 595 ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT], 596 ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU], 597 ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE], 598 ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY], 599 ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY], 600 ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH], 601 ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH], 602 ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH]); 603 if (printtitle) 604 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 605 "Renew", "RestoreFH", "SaveFH", "Secinfo", 606 "RelLckOwn", "V4Create"); 607 printf("%9d %9d %9d %9d %9d %9d\n", 608 ext_nfsstats.srvrpccnt[NFSV4OP_RENEW], 609 ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH], 610 ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH], 611 ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO], 612 ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN], 613 ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]); 614 if (printtitle) { 615 printf("Server:\n"); 616 printf("%9.9s %9.9s %9.9s\n", 617 "Retfailed", "Faults", "Clients"); 618 } 619 printf("%9d %9d %9d\n", 620 ext_nfsstats.srv_errs, ext_nfsstats.srvrpc_errs, 621 ext_nfsstats.srvclients); 622 if (printtitle) 623 printf("%9.9s %9.9s %9.9s %9.9s %9.9s \n", 624 "OpenOwner", "Opens", "LockOwner", 625 "Locks", "Delegs"); 626 printf("%9d %9d %9d %9d %9d \n", 627 ext_nfsstats.srvopenowners, 628 ext_nfsstats.srvopens, 629 ext_nfsstats.srvlockowners, 630 ext_nfsstats.srvlocks, 631 ext_nfsstats.srvdelegates); 632 if (printtitle) { 633 printf("Server Cache Stats:\n"); 634 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", 635 "Inprog", "Idem", "Non-idem", "Misses", 636 "CacheSize", "TCPPeak"); 637 } 638 printf("%9d %9d %9d %9d %9d %9d\n", 639 ext_nfsstats.srvcache_inproghits, 640 ext_nfsstats.srvcache_idemdonehits, 641 ext_nfsstats.srvcache_nonidemdonehits, 642 ext_nfsstats.srvcache_misses, 643 ext_nfsstats.srvcache_size, 644 ext_nfsstats.srvcache_tcppeak); 645 } 646 } 647 648 /* 649 * Print a running summary of nfs statistics for the experimental client and/or 650 * server. 651 * Repeat display every interval seconds, showing statistics 652 * collected over that interval. Assumes that interval is non-zero. 653 * First line printed at top of screen is always cumulative. 654 */ 655 static void 656 exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly) 657 { 658 struct ext_nfsstats nfsstats, lastst, *ext_nfsstatsp; 659 int hdrcnt = 1; 660 661 ext_nfsstatsp = &lastst; 662 if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0) 663 err(1, "Can't get stats"); 664 sleep(interval); 665 666 for (;;) { 667 ext_nfsstatsp = &nfsstats; 668 if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0) 669 err(1, "Can't get stats"); 670 671 if (--hdrcnt == 0) { 672 printhdr(clientOnly, serverOnly); 673 if (clientOnly && serverOnly) 674 hdrcnt = 10; 675 else 676 hdrcnt = 20; 677 } 678 if (clientOnly) { 679 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 680 ((clientOnly && serverOnly) ? "Client:" : ""), 681 DELTA(rpccnt[NFSPROC_GETATTR]), 682 DELTA(rpccnt[NFSPROC_LOOKUP]), 683 DELTA(rpccnt[NFSPROC_READLINK]), 684 DELTA(rpccnt[NFSPROC_READ]), 685 DELTA(rpccnt[NFSPROC_WRITE]), 686 DELTA(rpccnt[NFSPROC_RENAME]), 687 DELTA(rpccnt[NFSPROC_ACCESS]), 688 DELTA(rpccnt[NFSPROC_READDIR]) + 689 DELTA(rpccnt[NFSPROC_READDIRPLUS]) 690 ); 691 if (widemode) { 692 printf(" %s %s %s %s %s %s", 693 sperc1(DELTA(attrcache_hits), 694 DELTA(attrcache_misses)), 695 sperc1(DELTA(lookupcache_hits), 696 DELTA(lookupcache_misses)), 697 sperc2(DELTA(biocache_reads), 698 DELTA(read_bios)), 699 sperc2(DELTA(biocache_writes), 700 DELTA(write_bios)), 701 sperc1(DELTA(accesscache_hits), 702 DELTA(accesscache_misses)), 703 sperc2(DELTA(biocache_readdirs), 704 DELTA(readdir_bios)) 705 ); 706 } 707 printf("\n"); 708 } 709 if (serverOnly) { 710 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", 711 ((clientOnly && serverOnly) ? "Server:" : ""), 712 DELTA(srvrpccnt[NFSV4OP_GETATTR]), 713 DELTA(srvrpccnt[NFSV4OP_LOOKUP]), 714 DELTA(srvrpccnt[NFSV4OP_READLINK]), 715 DELTA(srvrpccnt[NFSV4OP_READ]), 716 DELTA(srvrpccnt[NFSV4OP_WRITE]), 717 DELTA(srvrpccnt[NFSV4OP_RENAME]), 718 DELTA(srvrpccnt[NFSV4OP_ACCESS]), 719 DELTA(srvrpccnt[NFSV4OP_READDIR]) + 720 DELTA(srvrpccnt[NFSV4OP_READDIRPLUS])); 721 printf("\n"); 722 } 723 lastst = nfsstats; 724 fflush(stdout); 725 sleep(interval); 726 } 727 /*NOTREACHED*/ 728 } 729