BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.bin / nfsstat / nfsstat.c
index 9c47be4..cdaafcd 100644 (file)
@@ -5,7 +5,33 @@
  * This code is derived from software contributed to Berkeley by
  * Rick Macklem at The University of Guelph.
  *
  * This code is derived from software contributed to Berkeley by
  * Rick Macklem at The University of Guelph.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
@@ -15,137 +41,144 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)nfsstat.c  5.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)nfsstat.c  5.9 (Berkeley) 7/1/91";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
+#if BSD >= 199103
+#define NEWVM
+#endif
+#ifndef NEWVM
 #include <sys/vmmac.h>
 #include <sys/vmmac.h>
-#include <sys/file.h>
 #include <machine/pte.h>
 #include <machine/pte.h>
-#include <sys/namei.h>
+#endif
 #include <sys/mount.h>
 #include <nfs/nfsv2.h>
 #include <nfs/nfs.h>
 #include <sys/mount.h>
 #include <nfs/nfsv2.h>
 #include <nfs/nfs.h>
+#include <signal.h>
+#include <fcntl.h>
 #include <ctype.h>
 #include <errno.h>
 #include <nlist.h>
 #include <ctype.h>
 #include <errno.h>
 #include <nlist.h>
+#include <unistd.h>
 #include <stdio.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <paths.h>
 
 #include <paths.h>
 
-#define        YES     1
-#define        NO      0
-
 struct nlist nl[] = {
 #define        N_NFSSTAT       0
        { "_nfsstats" },
 struct nlist nl[] = {
 #define        N_NFSSTAT       0
        { "_nfsstats" },
+#ifndef NEWVM
 #define        N_SYSMAP        1
        { "_Sysmap" },
 #define        N_SYSSIZE       2
        { "_Syssize" },
 #define        N_SYSMAP        1
        { "_Sysmap" },
 #define        N_SYSSIZE       2
        { "_Syssize" },
+#endif
        "",
 };
 
        "",
 };
 
-struct pte *Sysmap;
+#ifndef NEWVM
+struct pte *Sysmap;
+#endif
 
 
-char   *system = _PATH_UNIX;
-char   *kmemf = _PATH_KMEM;
-int    kmem;
-int    kflag;
-int    interval;
+int kflag, kmem;
+char *kernel = _PATH_UNIX;
+char *kmemf = _PATH_KMEM;
 
 
-extern char *malloc();
-extern off_t lseek();
+off_t klseek();
+void intpr(), printhdr(), sidewaysintpr(), usage();
 
 main(argc, argv)
        int argc;
 
 main(argc, argv)
        int argc;
-       char *argv[];
+       char **argv;
 {
 {
+       extern int optind;
+       extern char *optarg;
+       u_int interval;
        int ch;
 
        interval = 0;
        int ch;
 
        interval = 0;
-       argc--;
-       argv++;
-       if (argc > 0) {
-               interval = atoi(argv[0]);
-               if (interval <= 0)
+       while ((ch = getopt(argc, argv, "M:N:w:")) != EOF)
+               switch(ch) {
+               case 'M':
+                       kmemf = optarg;
+                       kflag = 1;
+                       break;
+               case 'N':
+                       kernel = optarg;
+                       break;
+               case 'w':
+                       interval = atoi(optarg);
+                       break;
+               case '?':
+               default:
                        usage();
                        usage();
-               argv++, argc--;
-               if (argc > 0) {
-                       system = *argv;
-                       argv++, argc--;
-                       if (argc > 0) {
-                               kmemf = *argv;
-                               kflag++;
-                       }
+               }
+       argc -= optind;
+       argv += optind;
+
+#define        BACKWARD_COMPATIBILITY
+#ifdef BACKWARD_COMPATIBILITY
+       if (*argv) {
+               kernel = *++argv;
+               if (*++argv) {
+                       kmemf = *argv;
+                       kflag = 1;
                }
        }
                }
        }
-       if (nlist(system, nl) < 0 || nl[0].n_type == 0) {
-               fprintf(stderr, "%s: no namelist\n", system);
+#endif
+       if (nlist(kernel, nl) < 0 || nl[0].n_type == 0) {
+               (void)fprintf(stderr, "nfsstate: %s: no namelist\n", kernel);
                exit(1);
        }
        kmem = open(kmemf, O_RDONLY);
        if (kmem < 0) {
                exit(1);
        }
        kmem = open(kmemf, O_RDONLY);
        if (kmem < 0) {
-               perror(kmemf);
+               (void)fprintf(stderr,
+                   "nfsstat: %s: %s\n", kmemf, strerror(errno));
                exit(1);
        }
        if (kflag) {
                exit(1);
        }
        if (kflag) {
+#ifdef NEWVM
+               (void)fprintf(stderr, "nfsstat: can't do core files yet\n");
+               exit(1);
+#else
                off_t off;
 
                Sysmap = (struct pte *)
                   malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
                if (!Sysmap) {
                off_t off;
 
                Sysmap = (struct pte *)
                   malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
                if (!Sysmap) {
-                       fputs("nfsstat: can't get memory for Sysmap.\n", stderr);
+                       (void)fprintf(stderr, "nfsstat: %s\n", strerror(errno));
                        exit(1);
                }
                off = nl[N_SYSMAP].n_value & ~KERNBASE;
                (void)lseek(kmem, off, L_SET);
                (void)read(kmem, (char *)Sysmap,
                        exit(1);
                }
                off = nl[N_SYSMAP].n_value & ~KERNBASE;
                (void)lseek(kmem, off, L_SET);
                (void)read(kmem, (char *)Sysmap,
-                       (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
+                   (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
+#endif
        }
        }
-       intpr(interval, nl[N_NFSSTAT].n_value);
-       exit(0);
-}
 
 
-/*
- * Seek into the kernel for a value.
- */
-off_t
-klseek(fd, base, off)
-       int fd, off;
-       off_t base;
-{
-       if (kflag) {
-               /* get kernel pte */
-               base &= ~KERNBASE;
-               base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
+       if (!nl[N_NFSSTAT].n_value) {
+               (void)fprintf(stderr, "nfsstat: nfsstats symbol not defined\n");
+               exit(1);
        }
        }
-       return (lseek(fd, base, off));
-}
-
-usage()
-{
-       fputs("Usage: nfsstat [interval [ system [ corefile ] ] ]\n", stderr);
-       exit(1);
+       if (interval)
+               sidewaysintpr(interval, nl[N_NFSSTAT].n_value);
+       else
+               intpr(nl[N_NFSSTAT].n_value);
+       exit(0);
 }
 
 /*
  * Print a description of the network interfaces.
  */
 }
 
 /*
  * Print a description of the network interfaces.
  */
-intpr(interval, nfsstataddr)
-       int interval;
+void
+intpr(nfsstataddr)
        off_t nfsstataddr;
 {
        struct nfsstats nfsstats;
 
        off_t nfsstataddr;
 {
        struct nfsstats nfsstats;
 
-       if (nfsstataddr == 0) {
-               printf("nfsstat: symbol not defined\n");
-               return;
-       }
-       if (interval) {
-               sidewaysintpr((unsigned)interval, nfsstataddr);
-               return;
-       }
-       klseek(kmem, nfsstataddr, 0);
+       klseek(kmem, nfsstataddr, 0L);
        read(kmem, (char *)&nfsstats, sizeof(struct nfsstats));
        printf("Client Info:\n");
        printf("Rpc Counts:\n");
        read(kmem, (char *)&nfsstats, sizeof(struct nfsstats));
        printf("Client Info:\n");
        printf("Rpc Counts:\n");
@@ -250,64 +283,68 @@ u_char    signalled;                      /* set if alarm goes off "early" */
  * collected over that interval.  Assumes that interval is non-zero.
  * First line printed at top of screen is always cumulative.
  */
  * collected over that interval.  Assumes that interval is non-zero.
  * First line printed at top of screen is always cumulative.
  */
+void
 sidewaysintpr(interval, off)
 sidewaysintpr(interval, off)
-       unsigned interval;
+       u_int interval;
        off_t off;
 {
        struct nfsstats nfsstats, lastst;
        off_t off;
 {
        struct nfsstats nfsstats, lastst;
-       register int line;
-       int oldmask;
+       int hdrcnt, oldmask;
        void catchalarm();
 
        void catchalarm();
 
-       klseek(kmem, off, 0);
+       klseek(kmem, off, 0L);
 
        (void)signal(SIGALRM, catchalarm);
 
        (void)signal(SIGALRM, catchalarm);
-       signalled = NO;
+       signalled = 0;
        (void)alarm(interval);
        bzero((caddr_t)&lastst, sizeof(lastst));
        (void)alarm(interval);
        bzero((caddr_t)&lastst, sizeof(lastst));
-banner:
-       printf("        %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s\n",
-               "Getattr", "Lookup", "Readlink", "Read",
-               "Write", "Rename", "Link", "Readdir");
-       fflush(stdout);
-       line = 0;
-loop:
-       klseek(kmem, off, 0);
-       read(kmem, (char *)&nfsstats, sizeof nfsstats);
-       printf("Client: %8d %8d %8d %8d %8d %8d %8d %8d\n",
-               nfsstats.rpccnt[1]-lastst.rpccnt[1],
-               nfsstats.rpccnt[4]-lastst.rpccnt[4],
-               nfsstats.rpccnt[5]-lastst.rpccnt[5],
-               nfsstats.rpccnt[6]-lastst.rpccnt[6],
-               nfsstats.rpccnt[8]-lastst.rpccnt[8],
-               nfsstats.rpccnt[11]-lastst.rpccnt[11],
-               nfsstats.rpccnt[12]-lastst.rpccnt[12],
-               nfsstats.rpccnt[16]-lastst.rpccnt[16]);
-       printf("Server: %8d %8d %8d %8d %8d %8d %8d %8d\n",
-               nfsstats.srvrpccnt[1]-lastst.srvrpccnt[1],
-               nfsstats.srvrpccnt[4]-lastst.srvrpccnt[4],
-               nfsstats.srvrpccnt[5]-lastst.srvrpccnt[5],
-               nfsstats.srvrpccnt[6]-lastst.srvrpccnt[6],
-               nfsstats.srvrpccnt[8]-lastst.srvrpccnt[8],
-               nfsstats.srvrpccnt[11]-lastst.srvrpccnt[11],
-               nfsstats.srvrpccnt[12]-lastst.srvrpccnt[12],
-               nfsstats.srvrpccnt[16]-lastst.srvrpccnt[16]);
-       lastst = nfsstats;
-       fflush(stdout);
-       line++;
-       oldmask = sigblock(sigmask(SIGALRM));
-       if (! signalled) {
-               sigpause(0);
+
+       for (hdrcnt = 1;;) {
+               if (!--hdrcnt) {
+                       printhdr();
+                       hdrcnt = 20;
+               }
+               klseek(kmem, off, 0L);
+               read(kmem, (char *)&nfsstats, sizeof nfsstats);
+               printf("Client: %8d %8d %8d %8d %8d %8d %8d %8d\n",
+                   nfsstats.rpccnt[1]-lastst.rpccnt[1],
+                   nfsstats.rpccnt[4]-lastst.rpccnt[4],
+                   nfsstats.rpccnt[5]-lastst.rpccnt[5],
+                   nfsstats.rpccnt[6]-lastst.rpccnt[6],
+                   nfsstats.rpccnt[8]-lastst.rpccnt[8],
+                   nfsstats.rpccnt[11]-lastst.rpccnt[11],
+                   nfsstats.rpccnt[12]-lastst.rpccnt[12],
+                   nfsstats.rpccnt[16]-lastst.rpccnt[16]);
+               printf("Server: %8d %8d %8d %8d %8d %8d %8d %8d\n",
+                   nfsstats.srvrpccnt[1]-lastst.srvrpccnt[1],
+                   nfsstats.srvrpccnt[4]-lastst.srvrpccnt[4],
+                   nfsstats.srvrpccnt[5]-lastst.srvrpccnt[5],
+                   nfsstats.srvrpccnt[6]-lastst.srvrpccnt[6],
+                   nfsstats.srvrpccnt[8]-lastst.srvrpccnt[8],
+                   nfsstats.srvrpccnt[11]-lastst.srvrpccnt[11],
+                   nfsstats.srvrpccnt[12]-lastst.srvrpccnt[12],
+                   nfsstats.srvrpccnt[16]-lastst.srvrpccnt[16]);
+               lastst = nfsstats;
+               fflush(stdout);
+               oldmask = sigblock(sigmask(SIGALRM));
+               if (!signalled)
+                       sigpause(0);
+               sigsetmask(oldmask);
+               signalled = 0;
+               (void)alarm(interval);
        }
        }
-       sigsetmask(oldmask);
-       signalled = NO;
-       (void)alarm(interval);
-       if (line == 21)
-               goto banner;
-       goto loop;
        /*NOTREACHED*/
 }
 
        /*NOTREACHED*/
 }
 
+void
+printhdr()
+{
+       printf("        %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s\n",
+           "Getattr", "Lookup", "Readlink", "Read", "Write", "Rename",
+           "Link", "Readdir");
+       fflush(stdout);
+}
+
 /*
  * Called if an interval expires before sidewaysintpr has completed a loop.
  * Sets a flag to not wait for the alarm.
 /*
  * Called if an interval expires before sidewaysintpr has completed a loop.
  * Sets a flag to not wait for the alarm.
@@ -315,5 +352,31 @@ loop:
 void
 catchalarm()
 {
 void
 catchalarm()
 {
-       signalled = YES;
+       signalled = 1;
+}
+
+/*
+ * Seek into the kernel for a value.
+ */
+off_t
+klseek(fd, base, off)
+       int fd, off;
+       off_t base;
+{
+#ifndef NEWVM
+       if (kflag) {
+               /* get kernel pte */
+               base &= ~KERNBASE;
+               base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
+       }
+#endif
+       return (lseek(fd, base, off));
+}
+
+void
+usage()
+{
+       (void)fprintf(stderr,
+           "usage: nfsstat [-M core] [-N system] [-w interval]\n");
+       exit(1);
 }
 }