home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / nfsstat / nfsstat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-01  |  10.1 KB  |  383 lines

  1. /*
  2.  * Copyright (c) 1983, 1989 Regents of the University of California.
  3.  * 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. char copyright[] =
  39. "@(#) Copyright (c) 1983, 1989 Regents of the University of California.\n\
  40.  All rights reserved.\n";
  41. #endif /* not lint */
  42.  
  43. #ifndef lint
  44. static char sccsid[] = "@(#)nfsstat.c    5.9 (Berkeley) 7/1/91";
  45. #endif /* not lint */
  46.  
  47. #include <sys/param.h>
  48. #if BSD >= 199103
  49. #define NEWVM
  50. #endif
  51. #ifndef NEWVM
  52. #include <sys/vmmac.h>
  53. #include <machine/pte.h>
  54. #endif
  55. #include <sys/mount.h>
  56. #include <nfs/nfsv2.h>
  57. #include <nfs/nfs.h>
  58. #include <signal.h>
  59. #include <fcntl.h>
  60. #include <ctype.h>
  61. #include <errno.h>
  62. #include <nlist.h>
  63. #include <unistd.h>
  64. #include <stdio.h>
  65. #include <stdlib.h>
  66. #include <string.h>
  67. #include <paths.h>
  68.  
  69. struct nlist nl[] = {
  70. #define    N_NFSSTAT    0
  71.     { "_nfsstats" },
  72. #ifndef NEWVM
  73. #define    N_SYSMAP    1
  74.     { "_Sysmap" },
  75. #define    N_SYSSIZE    2
  76.     { "_Syssize" },
  77. #endif
  78.     "",
  79. };
  80.  
  81. #ifndef NEWVM
  82. struct pte *Sysmap;
  83. #endif
  84.  
  85. int kflag, kmem;
  86. char *kernel = _PATH_UNIX;
  87. char *kmemf = _PATH_KMEM;
  88.  
  89. off_t klseek();
  90. void intpr(), printhdr(), sidewaysintpr(), usage();
  91.  
  92. main(argc, argv)
  93.     int argc;
  94.     char **argv;
  95. {
  96.     extern int optind;
  97.     extern char *optarg;
  98.     u_int interval;
  99.     int ch;
  100.  
  101.     interval = 0;
  102.     while ((ch = getopt(argc, argv, "M:N:w:")) != EOF)
  103.         switch(ch) {
  104.         case 'M':
  105.             kmemf = optarg;
  106.             kflag = 1;
  107.             break;
  108.         case 'N':
  109.             kernel = optarg;
  110.             break;
  111.         case 'w':
  112.             interval = atoi(optarg);
  113.             break;
  114.         case '?':
  115.         default:
  116.             usage();
  117.         }
  118.     argc -= optind;
  119.     argv += optind;
  120.  
  121. #define    BACKWARD_COMPATIBILITY
  122. #ifdef    BACKWARD_COMPATIBILITY
  123.     if (*argv) {
  124.         kernel = *++argv;
  125.         if (*++argv) {
  126.             kmemf = *argv;
  127.             kflag = 1;
  128.         }
  129.     }
  130. #endif
  131.     if (nlist(kernel, nl) < 0 || nl[0].n_type == 0) {
  132.         (void)fprintf(stderr, "nfsstate: %s: no namelist\n", kernel);
  133.         exit(1);
  134.     }
  135.     kmem = open(kmemf, O_RDONLY);
  136.     if (kmem < 0) {
  137.         (void)fprintf(stderr,
  138.             "nfsstat: %s: %s\n", kmemf, strerror(errno));
  139.         exit(1);
  140.     }
  141.     if (kflag) {
  142. #ifdef NEWVM
  143.         (void)fprintf(stderr, "nfsstat: can't do core files yet\n");
  144.         exit(1);
  145. #else
  146.         off_t off;
  147.  
  148.         Sysmap = (struct pte *)
  149.            malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
  150.         if (!Sysmap) {
  151.             (void)fprintf(stderr, "nfsstat: %s\n", strerror(errno));
  152.             exit(1);
  153.         }
  154.         off = nl[N_SYSMAP].n_value & ~KERNBASE;
  155.         (void)lseek(kmem, off, L_SET);
  156.         (void)read(kmem, (char *)Sysmap,
  157.             (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
  158. #endif
  159.     }
  160.  
  161.     if (!nl[N_NFSSTAT].n_value) {
  162.         (void)fprintf(stderr, "nfsstat: nfsstats symbol not defined\n");
  163.         exit(1);
  164.     }
  165.     if (interval)
  166.         sidewaysintpr(interval, nl[N_NFSSTAT].n_value);
  167.     else
  168.         intpr(nl[N_NFSSTAT].n_value);
  169.     exit(0);
  170. }
  171.  
  172. /*
  173.  * Print a description of the network interfaces.
  174.  */
  175. void
  176. intpr(nfsstataddr)
  177.     off_t nfsstataddr;
  178. {
  179.     struct nfsstats nfsstats;
  180.  
  181.     klseek(kmem, nfsstataddr, 0L);
  182.     read(kmem, (char *)&nfsstats, sizeof(struct nfsstats));
  183.     printf("Client Info:\n");
  184.     printf("Rpc Counts:\n");
  185.     printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
  186.         "Getattr", "Setattr", "Lookup", "Readlink", "Read",
  187.         "Write", "Create", "Remove");
  188.     printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
  189.         nfsstats.rpccnt[1],
  190.         nfsstats.rpccnt[2],
  191.         nfsstats.rpccnt[4],
  192.         nfsstats.rpccnt[5],
  193.         nfsstats.rpccnt[6],
  194.         nfsstats.rpccnt[8],
  195.         nfsstats.rpccnt[9],
  196.         nfsstats.rpccnt[10]);
  197.     printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
  198.         "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
  199.         "Readdir", "Statfs");
  200.     printf("%9d %9d %9d %9d %9d %9d %9d\n",
  201.         nfsstats.rpccnt[11],
  202.         nfsstats.rpccnt[12],
  203.         nfsstats.rpccnt[13],
  204.         nfsstats.rpccnt[14],
  205.         nfsstats.rpccnt[15],
  206.         nfsstats.rpccnt[16],
  207.         nfsstats.rpccnt[17]);
  208.     printf("Rpc Info:\n");
  209.     printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
  210.         "TimedOut", "Invalid", "X Replies", "Retries", "Requests");
  211.     printf("%9d %9d %9d %9d %9d\n",
  212.         nfsstats.rpctimeouts,
  213.         nfsstats.rpcinvalid,
  214.         nfsstats.rpcunexpected,
  215.         nfsstats.rpcretries,
  216.         nfsstats.rpcrequests);
  217.     printf("Cache Info:\n");
  218.     printf("%9.9s %9.9s %9.9s %9.9s",
  219.         "Attr Hits", "Misses", "Lkup Hits", "Misses");
  220.     printf(" %9.9s %9.9s %9.9s %9.9s\n",
  221.         "BioR Hits", "Misses", "BioW Hits", "Misses");
  222.     printf("%9d %9d %9d %9d",
  223.         nfsstats.attrcache_hits, nfsstats.attrcache_misses,
  224.         nfsstats.lookupcache_hits, nfsstats.lookupcache_misses);
  225.     printf(" %9d %9d %9d %9d\n",
  226.         nfsstats.biocache_reads-nfsstats.read_bios,
  227.         nfsstats.read_bios,
  228.         nfsstats.biocache_writes-nfsstats.write_bios,
  229.         nfsstats.write_bios);
  230.     printf("%9.9s %9.9s %9.9s %9.9s",
  231.         "BioRLHits", "Misses", "BioD Hits", "Misses");
  232.     printf(" %9.9s %9.9s\n", "DirE Hits", "Misses");
  233.     printf("%9d %9d %9d %9d",
  234.         nfsstats.biocache_readlinks-nfsstats.readlink_bios,
  235.         nfsstats.readlink_bios,
  236.         nfsstats.biocache_readdirs-nfsstats.readdir_bios,
  237.         nfsstats.readdir_bios);
  238.     printf(" %9d %9d\n",
  239.         nfsstats.direofcache_hits, nfsstats.direofcache_misses);
  240.     printf("\nServer Info:\n");
  241.     printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
  242.         "Getattr", "Setattr", "Lookup", "Readlink", "Read",
  243.         "Write", "Create", "Remove");
  244.     printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
  245.         nfsstats.srvrpccnt[1],
  246.         nfsstats.srvrpccnt[2],
  247.         nfsstats.srvrpccnt[4],
  248.         nfsstats.srvrpccnt[5],
  249.         nfsstats.srvrpccnt[6],
  250.         nfsstats.srvrpccnt[8],
  251.         nfsstats.srvrpccnt[9],
  252.         nfsstats.srvrpccnt[10]);
  253.     printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
  254.         "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
  255.         "Readdir", "Statfs");
  256.     printf("%9d %9d %9d %9d %9d %9d %9d\n",
  257.         nfsstats.srvrpccnt[11],
  258.         nfsstats.srvrpccnt[12],
  259.         nfsstats.srvrpccnt[13],
  260.         nfsstats.srvrpccnt[14],
  261.         nfsstats.srvrpccnt[15],
  262.         nfsstats.srvrpccnt[16],
  263.         nfsstats.srvrpccnt[17]);
  264.     printf("Server Ret-Failed\n");
  265.     printf("%17d\n", nfsstats.srvrpc_errs);
  266.     printf("Server Faults\n");
  267.     printf("%13d\n", nfsstats.srv_errs);
  268.     printf("Server Cache Stats:\n");
  269.     printf("%9.9s %9.9s %9.9s %9.9s\n",
  270.         "Inprog", "Idem", "Non-idem", "Misses");
  271.     printf("%9d %9d %9d %9d\n",
  272.         nfsstats.srvcache_inproghits,
  273.         nfsstats.srvcache_idemdonehits,
  274.         nfsstats.srvcache_nonidemdonehits,
  275.         nfsstats.srvcache_misses);
  276. }
  277.  
  278. u_char    signalled;            /* set if alarm goes off "early" */
  279.  
  280. /*
  281.  * Print a running summary of nfs statistics.
  282.  * Repeat display every interval seconds, showing statistics
  283.  * collected over that interval.  Assumes that interval is non-zero.
  284.  * First line printed at top of screen is always cumulative.
  285.  */
  286. void
  287. sidewaysintpr(interval, off)
  288.     u_int interval;
  289.     off_t off;
  290. {
  291.     struct nfsstats nfsstats, lastst;
  292.     int hdrcnt, oldmask;
  293.     void catchalarm();
  294.  
  295.     klseek(kmem, off, 0L);
  296.  
  297.     (void)signal(SIGALRM, catchalarm);
  298.     signalled = 0;
  299.     (void)alarm(interval);
  300.     bzero((caddr_t)&lastst, sizeof(lastst));
  301.  
  302.     for (hdrcnt = 1;;) {
  303.         if (!--hdrcnt) {
  304.             printhdr();
  305.             hdrcnt = 20;
  306.         }
  307.         klseek(kmem, off, 0L);
  308.         read(kmem, (char *)&nfsstats, sizeof nfsstats);
  309.         printf("Client: %8d %8d %8d %8d %8d %8d %8d %8d\n",
  310.             nfsstats.rpccnt[1]-lastst.rpccnt[1],
  311.             nfsstats.rpccnt[4]-lastst.rpccnt[4],
  312.             nfsstats.rpccnt[5]-lastst.rpccnt[5],
  313.             nfsstats.rpccnt[6]-lastst.rpccnt[6],
  314.             nfsstats.rpccnt[8]-lastst.rpccnt[8],
  315.             nfsstats.rpccnt[11]-lastst.rpccnt[11],
  316.             nfsstats.rpccnt[12]-lastst.rpccnt[12],
  317.             nfsstats.rpccnt[16]-lastst.rpccnt[16]);
  318.         printf("Server: %8d %8d %8d %8d %8d %8d %8d %8d\n",
  319.             nfsstats.srvrpccnt[1]-lastst.srvrpccnt[1],
  320.             nfsstats.srvrpccnt[4]-lastst.srvrpccnt[4],
  321.             nfsstats.srvrpccnt[5]-lastst.srvrpccnt[5],
  322.             nfsstats.srvrpccnt[6]-lastst.srvrpccnt[6],
  323.             nfsstats.srvrpccnt[8]-lastst.srvrpccnt[8],
  324.             nfsstats.srvrpccnt[11]-lastst.srvrpccnt[11],
  325.             nfsstats.srvrpccnt[12]-lastst.srvrpccnt[12],
  326.             nfsstats.srvrpccnt[16]-lastst.srvrpccnt[16]);
  327.         lastst = nfsstats;
  328.         fflush(stdout);
  329.         oldmask = sigblock(sigmask(SIGALRM));
  330.         if (!signalled)
  331.             sigpause(0);
  332.         sigsetmask(oldmask);
  333.         signalled = 0;
  334.         (void)alarm(interval);
  335.     }
  336.     /*NOTREACHED*/
  337. }
  338.  
  339. void
  340. printhdr()
  341. {
  342.     printf("        %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s\n",
  343.         "Getattr", "Lookup", "Readlink", "Read", "Write", "Rename",
  344.         "Link", "Readdir");
  345.     fflush(stdout);
  346. }
  347.  
  348. /*
  349.  * Called if an interval expires before sidewaysintpr has completed a loop.
  350.  * Sets a flag to not wait for the alarm.
  351.  */
  352. void
  353. catchalarm()
  354. {
  355.     signalled = 1;
  356. }
  357.  
  358. /*
  359.  * Seek into the kernel for a value.
  360.  */
  361. off_t
  362. klseek(fd, base, off)
  363.     int fd, off;
  364.     off_t base;
  365. {
  366. #ifndef NEWVM
  367.     if (kflag) {
  368.         /* get kernel pte */
  369.         base &= ~KERNBASE;
  370.         base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
  371.     }
  372. #endif
  373.     return (lseek(fd, base, off));
  374. }
  375.  
  376. void
  377. usage()
  378. {
  379.     (void)fprintf(stderr,
  380.         "usage: nfsstat [-M core] [-N system] [-w interval]\n");
  381.     exit(1);
  382. }
  383.