* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement: ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * 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
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)nfsstat.c 5.5 (Berkeley) 6/1/90";
+static char sccsid[] = "@(#)nfsstat.c 5.9 (Berkeley) 7/1/91";
#endif /* not lint */
#include <sys/param.h>
+#if BSD >= 199103
+#define NEWVM
+#endif
+#ifndef NEWVM
#include <sys/vmmac.h>
-#include <sys/file.h>
#include <machine/pte.h>
-#include <sys/namei.h>
+#endif
#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 <unistd.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <paths.h>
-#define YES 1
-#define NO 0
-
struct nlist nl[] = {
#define N_NFSSTAT 0
{ "_nfsstats" },
+#ifndef NEWVM
#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;
- char *argv[];
+ char **argv;
{
+ extern int optind;
+ extern char *optarg;
+ u_int interval;
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();
- 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) {
- perror(kmemf);
+ (void)fprintf(stderr,
+ "nfsstat: %s: %s\n", kmemf, strerror(errno));
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) {
- 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,
- (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.
*/
-intpr(interval, nfsstataddr)
- int interval;
+void
+intpr(nfsstataddr)
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");
* collected over that interval. Assumes that interval is non-zero.
* First line printed at top of screen is always cumulative.
*/
+void
sidewaysintpr(interval, off)
- unsigned interval;
+ u_int interval;
off_t off;
{
struct nfsstats nfsstats, lastst;
- register int line;
- int oldmask;
- int catchalarm();
+ int hdrcnt, oldmask;
+ void catchalarm();
- klseek(kmem, off, 0);
+ klseek(kmem, off, 0L);
(void)signal(SIGALRM, catchalarm);
- signalled = NO;
+ signalled = 0;
(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*/
}
+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.
*/
+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);
}