Annotation of src/usr.bin/nfsstat/nfsstat.c, Revision 1.1
1.1 ! deraadt 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: * 3. All advertising materials mentioning features or use of this software
! 17: * must display the following acknowledgement:
! 18: * This product includes software developed by the University of
! 19: * California, Berkeley and its contributors.
! 20: * 4. Neither the name of the University nor the names of its contributors
! 21: * may be used to endorse or promote products derived from this software
! 22: * without specific prior written permission.
! 23: *
! 24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 34: * SUCH DAMAGE.
! 35: */
! 36:
! 37: #ifndef lint
! 38: static char copyright[] =
! 39: "@(#) Copyright (c) 1983, 1989, 1993\n\
! 40: The Regents of the University of California. All rights reserved.\n";
! 41: #endif /* not lint */
! 42:
! 43: #ifndef lint
! 44: /*static char sccsid[] = "from: @(#)nfsstat.c 8.1 (Berkeley) 6/6/93";*/
! 45: static char *rcsid = "$Id: nfsstat.c,v 1.5 1994/06/13 21:02:20 mycroft Exp $";
! 46: #endif /* not lint */
! 47:
! 48: #include <sys/param.h>
! 49: #if BSD >= 199103
! 50: #define NEWVM
! 51: #endif
! 52: #ifndef NEWVM
! 53: #include <sys/vmmac.h>
! 54: #include <sys/ucred.h>
! 55: #include <machine/pte.h>
! 56: #endif
! 57: #include <sys/mount.h>
! 58: #include <nfs/nfsv2.h>
! 59: #include <nfs/nfs.h>
! 60: #include <signal.h>
! 61: #include <fcntl.h>
! 62: #include <ctype.h>
! 63: #include <errno.h>
! 64: #include <kvm.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:
! 72: struct nlist nl[] = {
! 73: #define N_NFSSTAT 0
! 74: { "_nfsstats" },
! 75: "",
! 76: };
! 77: kvm_t *kd;
! 78:
! 79: void intpr(), printhdr(), sidewaysintpr(), usage();
! 80:
! 81: main(argc, argv)
! 82: int argc;
! 83: char **argv;
! 84: {
! 85: extern int optind;
! 86: extern char *optarg;
! 87: u_int interval;
! 88: int ch;
! 89: char *memf, *nlistf;
! 90: char errbuf[80];
! 91:
! 92: interval = 0;
! 93: memf = nlistf = NULL;
! 94: while ((ch = getopt(argc, argv, "M:N:w:")) != EOF)
! 95: switch(ch) {
! 96: case 'M':
! 97: memf = optarg;
! 98: break;
! 99: case 'N':
! 100: nlistf = optarg;
! 101: break;
! 102: case 'w':
! 103: interval = atoi(optarg);
! 104: break;
! 105: case '?':
! 106: default:
! 107: usage();
! 108: }
! 109: argc -= optind;
! 110: argv += optind;
! 111:
! 112: #define BACKWARD_COMPATIBILITY
! 113: #ifdef BACKWARD_COMPATIBILITY
! 114: if (*argv) {
! 115: interval = atoi(*argv);
! 116: if (*++argv) {
! 117: nlistf = *argv;
! 118: if (*++argv)
! 119: memf = *argv;
! 120: }
! 121: }
! 122: #endif
! 123: /*
! 124: * Discard setgid privileges if not the running kernel so that bad
! 125: * guys can't print interesting stuff from kernel memory.
! 126: */
! 127: if (nlistf != NULL || memf != NULL)
! 128: setgid(getgid());
! 129:
! 130: if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == 0) {
! 131: fprintf(stderr, "nfsstat: kvm_openfiles: %s\n", errbuf);
! 132: exit(1);
! 133: }
! 134: if (kvm_nlist(kd, nl) != 0) {
! 135: fprintf(stderr, "nfsstat: kvm_nlist: can't get names\n");
! 136: exit(1);
! 137: }
! 138:
! 139: if (interval)
! 140: sidewaysintpr(interval, nl[N_NFSSTAT].n_value);
! 141: else
! 142: intpr(nl[N_NFSSTAT].n_value);
! 143: exit(0);
! 144: }
! 145:
! 146: /*
! 147: * Print a description of the nfs stats.
! 148: */
! 149: void
! 150: intpr(nfsstataddr)
! 151: u_long nfsstataddr;
! 152: {
! 153: struct nfsstats nfsstats;
! 154:
! 155: if (kvm_read(kd, (u_long)nfsstataddr, (char *)&nfsstats, sizeof(struct nfsstats)) < 0) {
! 156: fprintf(stderr, "nfsstat: kvm_read failed\n");
! 157: exit(1);
! 158: }
! 159: printf("Client Info:\n");
! 160: printf("Rpc Counts:\n");
! 161: printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
! 162: "Getattr", "Setattr", "Lookup", "Readlink", "Read",
! 163: "Write", "Create", "Remove");
! 164: printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
! 165: nfsstats.rpccnt[NFSPROC_GETATTR],
! 166: nfsstats.rpccnt[NFSPROC_SETATTR],
! 167: nfsstats.rpccnt[NFSPROC_LOOKUP],
! 168: nfsstats.rpccnt[NFSPROC_READLINK],
! 169: nfsstats.rpccnt[NFSPROC_READ],
! 170: nfsstats.rpccnt[NFSPROC_WRITE],
! 171: nfsstats.rpccnt[NFSPROC_CREATE],
! 172: nfsstats.rpccnt[NFSPROC_REMOVE]);
! 173: printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
! 174: "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
! 175: "Readdir", "Statfs", "RdirLook");
! 176: printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
! 177: nfsstats.rpccnt[NFSPROC_RENAME],
! 178: nfsstats.rpccnt[NFSPROC_LINK],
! 179: nfsstats.rpccnt[NFSPROC_SYMLINK],
! 180: nfsstats.rpccnt[NFSPROC_MKDIR],
! 181: nfsstats.rpccnt[NFSPROC_RMDIR],
! 182: nfsstats.rpccnt[NFSPROC_READDIR],
! 183: nfsstats.rpccnt[NFSPROC_STATFS],
! 184: nfsstats.rpccnt[NQNFSPROC_READDIRLOOK]);
! 185: printf("%9.9s %9.9s %9.9s\n",
! 186: "GLease", "Vacate", "Evict");
! 187: printf("%9d %9d %9d\n",
! 188: nfsstats.rpccnt[NQNFSPROC_GETLEASE],
! 189: nfsstats.rpccnt[NQNFSPROC_VACATED],
! 190: nfsstats.rpccnt[NQNFSPROC_EVICTED]);
! 191: printf("Rpc Info:\n");
! 192: printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
! 193: "TimedOut", "Invalid", "X Replies", "Retries", "Requests");
! 194: printf("%9d %9d %9d %9d %9d\n",
! 195: nfsstats.rpctimeouts,
! 196: nfsstats.rpcinvalid,
! 197: nfsstats.rpcunexpected,
! 198: nfsstats.rpcretries,
! 199: nfsstats.rpcrequests);
! 200: printf("Cache Info:\n");
! 201: printf("%9.9s %9.9s %9.9s %9.9s",
! 202: "Attr Hits", "Misses", "Lkup Hits", "Misses");
! 203: printf(" %9.9s %9.9s %9.9s %9.9s\n",
! 204: "BioR Hits", "Misses", "BioW Hits", "Misses");
! 205: printf("%9d %9d %9d %9d",
! 206: nfsstats.attrcache_hits, nfsstats.attrcache_misses,
! 207: nfsstats.lookupcache_hits, nfsstats.lookupcache_misses);
! 208: printf(" %9d %9d %9d %9d\n",
! 209: nfsstats.biocache_reads-nfsstats.read_bios,
! 210: nfsstats.read_bios,
! 211: nfsstats.biocache_writes-nfsstats.write_bios,
! 212: nfsstats.write_bios);
! 213: printf("%9.9s %9.9s %9.9s %9.9s",
! 214: "BioRLHits", "Misses", "BioD Hits", "Misses");
! 215: printf(" %9.9s %9.9s\n", "DirE Hits", "Misses");
! 216: printf("%9d %9d %9d %9d",
! 217: nfsstats.biocache_readlinks-nfsstats.readlink_bios,
! 218: nfsstats.readlink_bios,
! 219: nfsstats.biocache_readdirs-nfsstats.readdir_bios,
! 220: nfsstats.readdir_bios);
! 221: printf(" %9d %9d\n",
! 222: nfsstats.direofcache_hits, nfsstats.direofcache_misses);
! 223: printf("\nServer Info:\n");
! 224: printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
! 225: "Getattr", "Setattr", "Lookup", "Readlink", "Read",
! 226: "Write", "Create", "Remove");
! 227: printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
! 228: nfsstats.srvrpccnt[NFSPROC_GETATTR],
! 229: nfsstats.srvrpccnt[NFSPROC_SETATTR],
! 230: nfsstats.srvrpccnt[NFSPROC_LOOKUP],
! 231: nfsstats.srvrpccnt[NFSPROC_READLINK],
! 232: nfsstats.srvrpccnt[NFSPROC_READ],
! 233: nfsstats.srvrpccnt[NFSPROC_WRITE],
! 234: nfsstats.srvrpccnt[NFSPROC_CREATE],
! 235: nfsstats.srvrpccnt[NFSPROC_REMOVE]);
! 236: printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
! 237: "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
! 238: "Readdir", "Statfs", "RdirLook");
! 239: printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
! 240: nfsstats.srvrpccnt[NFSPROC_RENAME],
! 241: nfsstats.srvrpccnt[NFSPROC_LINK],
! 242: nfsstats.srvrpccnt[NFSPROC_SYMLINK],
! 243: nfsstats.srvrpccnt[NFSPROC_MKDIR],
! 244: nfsstats.srvrpccnt[NFSPROC_RMDIR],
! 245: nfsstats.srvrpccnt[NFSPROC_READDIR],
! 246: nfsstats.srvrpccnt[NFSPROC_STATFS],
! 247: nfsstats.srvrpccnt[NQNFSPROC_READDIRLOOK]);
! 248: printf("%9.9s %9.9s %9.9s\n",
! 249: "GLease", "Vacate", "Evict");
! 250: printf("%9d %9d %9d\n",
! 251: nfsstats.srvrpccnt[NQNFSPROC_GETLEASE],
! 252: nfsstats.srvrpccnt[NQNFSPROC_VACATED],
! 253: nfsstats.srvrpccnt[NQNFSPROC_EVICTED]);
! 254: printf("Server Ret-Failed\n");
! 255: printf("%17d\n", nfsstats.srvrpc_errs);
! 256: printf("Server Faults\n");
! 257: printf("%13d\n", nfsstats.srv_errs);
! 258: printf("Server Cache Stats:\n");
! 259: printf("%9.9s %9.9s %9.9s %9.9s\n",
! 260: "Inprog", "Idem", "Non-idem", "Misses");
! 261: printf("%9d %9d %9d %9d\n",
! 262: nfsstats.srvcache_inproghits,
! 263: nfsstats.srvcache_idemdonehits,
! 264: nfsstats.srvcache_nonidemdonehits,
! 265: nfsstats.srvcache_misses);
! 266: printf("Server Lease Stats:\n");
! 267: printf("%9.9s %9.9s %9.9s\n",
! 268: "Leases", "PeakL", "GLeases");
! 269: printf("%9d %9d %9d\n",
! 270: nfsstats.srvnqnfs_leases,
! 271: nfsstats.srvnqnfs_maxleases,
! 272: nfsstats.srvnqnfs_getleases);
! 273: }
! 274:
! 275: u_char signalled; /* set if alarm goes off "early" */
! 276:
! 277: /*
! 278: * Print a running summary of nfs statistics.
! 279: * Repeat display every interval seconds, showing statistics
! 280: * collected over that interval. Assumes that interval is non-zero.
! 281: * First line printed at top of screen is always cumulative.
! 282: */
! 283: void
! 284: sidewaysintpr(interval, off)
! 285: u_int interval;
! 286: u_long off;
! 287: {
! 288: struct nfsstats nfsstats, lastst;
! 289: int hdrcnt, oldmask;
! 290: void catchalarm();
! 291:
! 292: (void)signal(SIGALRM, catchalarm);
! 293: signalled = 0;
! 294: (void)alarm(interval);
! 295: bzero((caddr_t)&lastst, sizeof(lastst));
! 296:
! 297: for (hdrcnt = 1;;) {
! 298: if (!--hdrcnt) {
! 299: printhdr();
! 300: hdrcnt = 20;
! 301: }
! 302: if (kvm_read(kd, off, (char *)&nfsstats, sizeof nfsstats) < 0) {
! 303: fprintf(stderr, "nfsstat: kvm_read failed\n");
! 304: exit(1);
! 305: }
! 306: printf("Client: %8d %8d %8d %8d %8d %8d %8d %8d\n",
! 307: nfsstats.rpccnt[1]-lastst.rpccnt[1],
! 308: nfsstats.rpccnt[4]-lastst.rpccnt[4],
! 309: nfsstats.rpccnt[5]-lastst.rpccnt[5],
! 310: nfsstats.rpccnt[6]-lastst.rpccnt[6],
! 311: nfsstats.rpccnt[8]-lastst.rpccnt[8],
! 312: nfsstats.rpccnt[11]-lastst.rpccnt[11],
! 313: nfsstats.rpccnt[12]-lastst.rpccnt[12],
! 314: nfsstats.rpccnt[16]-lastst.rpccnt[16]);
! 315: printf("Server: %8d %8d %8d %8d %8d %8d %8d %8d\n",
! 316: nfsstats.srvrpccnt[1]-lastst.srvrpccnt[1],
! 317: nfsstats.srvrpccnt[4]-lastst.srvrpccnt[4],
! 318: nfsstats.srvrpccnt[5]-lastst.srvrpccnt[5],
! 319: nfsstats.srvrpccnt[6]-lastst.srvrpccnt[6],
! 320: nfsstats.srvrpccnt[8]-lastst.srvrpccnt[8],
! 321: nfsstats.srvrpccnt[11]-lastst.srvrpccnt[11],
! 322: nfsstats.srvrpccnt[12]-lastst.srvrpccnt[12],
! 323: nfsstats.srvrpccnt[16]-lastst.srvrpccnt[16]);
! 324: lastst = nfsstats;
! 325: fflush(stdout);
! 326: oldmask = sigblock(sigmask(SIGALRM));
! 327: if (!signalled)
! 328: sigpause(0);
! 329: sigsetmask(oldmask);
! 330: signalled = 0;
! 331: (void)alarm(interval);
! 332: }
! 333: /*NOTREACHED*/
! 334: }
! 335:
! 336: void
! 337: printhdr()
! 338: {
! 339: printf(" %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s\n",
! 340: "Getattr", "Lookup", "Readlink", "Read", "Write", "Rename",
! 341: "Link", "Readdir");
! 342: fflush(stdout);
! 343: }
! 344:
! 345: /*
! 346: * Called if an interval expires before sidewaysintpr has completed a loop.
! 347: * Sets a flag to not wait for the alarm.
! 348: */
! 349: void
! 350: catchalarm()
! 351: {
! 352: signalled = 1;
! 353: }
! 354:
! 355: void
! 356: usage()
! 357: {
! 358: (void)fprintf(stderr,
! 359: "usage: nfsstat [-M core] [-N system] [-w interval]\n");
! 360: exit(1);
! 361: }