xref: /original-bsd/usr.bin/nfsstat/nfsstat.c (revision 217010d6)
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  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 char copyright[] =
13 "@(#) Copyright (c) 1983, 1989 Regents of the University of California.\n\
14  All rights reserved.\n";
15 #endif /* not lint */
16 
17 #ifndef lint
18 static char sccsid[] = "@(#)nfsstat.c	5.10 (Berkeley) 07/01/91";
19 #endif /* not lint */
20 
21 #include <sys/param.h>
22 #if BSD >= 199103
23 #define NEWVM
24 #endif
25 #ifndef NEWVM
26 #include <sys/vmmac.h>
27 #include <machine/pte.h>
28 #endif
29 #include <sys/mount.h>
30 #include <nfs/nfsv2.h>
31 #include <nfs/nfs.h>
32 #include <signal.h>
33 #include <fcntl.h>
34 #include <ctype.h>
35 #include <errno.h>
36 #include <nlist.h>
37 #include <unistd.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <paths.h>
42 
43 struct nlist nl[] = {
44 #define	N_NFSSTAT	0
45 	{ "_nfsstats" },
46 	"",
47 };
48 
49 char *kernel = NULL;
50 char *kmemf = NULL;
51 
52 void intpr(), printhdr(), sidewaysintpr(), usage();
53 
54 main(argc, argv)
55 	int argc;
56 	char **argv;
57 {
58 	extern int optind;
59 	extern char *optarg;
60 	u_int interval;
61 	int ch;
62 
63 	interval = 0;
64 	while ((ch = getopt(argc, argv, "M:N:w:")) != EOF)
65 		switch(ch) {
66 		case 'M':
67 			kmemf = optarg;
68 			break;
69 		case 'N':
70 			kernel = optarg;
71 			break;
72 		case 'w':
73 			interval = atoi(optarg);
74 			break;
75 		case '?':
76 		default:
77 			usage();
78 		}
79 	argc -= optind;
80 	argv += optind;
81 
82 #define	BACKWARD_COMPATIBILITY
83 #ifdef	BACKWARD_COMPATIBILITY
84 	if (*argv) {
85 		interval = atoi(*argv);
86 		if (*++argv) {
87 			kernel = *argv;
88 			if (*++argv)
89 				kmemf = *argv;
90 		}
91 	}
92 #endif
93 	if (kvm_openfiles(kernel, kmemf, NULL) == -1) {
94 		fprintf(stderr, "nfsstate: kvm_openfiles: %s", kvm_geterr());
95 		exit(1);
96 	}
97 	if (kvm_nlist(nl) != 0) {
98 		fprintf(stderr, "nfsstate: kvm_nlist: can't get names");
99 		exit(1);
100 	}
101 
102 	if (interval)
103 		sidewaysintpr(interval, nl[N_NFSSTAT].n_value);
104 	else
105 		intpr(nl[N_NFSSTAT].n_value);
106 	exit(0);
107 }
108 
109 /*
110  * Print a description of the network interfaces.
111  */
112 void
113 intpr(nfsstataddr)
114 	off_t nfsstataddr;
115 {
116 	struct nfsstats nfsstats;
117 
118 	kvm_read((void *)nfsstataddr, (char *)&nfsstats, sizeof(struct nfsstats));
119 	printf("Client Info:\n");
120 	printf("Rpc Counts:\n");
121 	printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
122 		"Getattr", "Setattr", "Lookup", "Readlink", "Read",
123 		"Write", "Create", "Remove");
124 	printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
125 		nfsstats.rpccnt[1],
126 		nfsstats.rpccnt[2],
127 		nfsstats.rpccnt[4],
128 		nfsstats.rpccnt[5],
129 		nfsstats.rpccnt[6],
130 		nfsstats.rpccnt[8],
131 		nfsstats.rpccnt[9],
132 		nfsstats.rpccnt[10]);
133 	printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
134 		"Rename", "Link", "Symlink", "Mkdir", "Rmdir",
135 		"Readdir", "Statfs");
136 	printf("%9d %9d %9d %9d %9d %9d %9d\n",
137 		nfsstats.rpccnt[11],
138 		nfsstats.rpccnt[12],
139 		nfsstats.rpccnt[13],
140 		nfsstats.rpccnt[14],
141 		nfsstats.rpccnt[15],
142 		nfsstats.rpccnt[16],
143 		nfsstats.rpccnt[17]);
144 	printf("Rpc Info:\n");
145 	printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
146 		"TimedOut", "Invalid", "X Replies", "Retries", "Requests");
147 	printf("%9d %9d %9d %9d %9d\n",
148 		nfsstats.rpctimeouts,
149 		nfsstats.rpcinvalid,
150 		nfsstats.rpcunexpected,
151 		nfsstats.rpcretries,
152 		nfsstats.rpcrequests);
153 	printf("Cache Info:\n");
154 	printf("%9.9s %9.9s %9.9s %9.9s",
155 		"Attr Hits", "Misses", "Lkup Hits", "Misses");
156 	printf(" %9.9s %9.9s %9.9s %9.9s\n",
157 		"BioR Hits", "Misses", "BioW Hits", "Misses");
158 	printf("%9d %9d %9d %9d",
159 		nfsstats.attrcache_hits, nfsstats.attrcache_misses,
160 		nfsstats.lookupcache_hits, nfsstats.lookupcache_misses);
161 	printf(" %9d %9d %9d %9d\n",
162 		nfsstats.biocache_reads-nfsstats.read_bios,
163 		nfsstats.read_bios,
164 		nfsstats.biocache_writes-nfsstats.write_bios,
165 		nfsstats.write_bios);
166 	printf("%9.9s %9.9s %9.9s %9.9s",
167 		"BioRLHits", "Misses", "BioD Hits", "Misses");
168 	printf(" %9.9s %9.9s\n", "DirE Hits", "Misses");
169 	printf("%9d %9d %9d %9d",
170 		nfsstats.biocache_readlinks-nfsstats.readlink_bios,
171 		nfsstats.readlink_bios,
172 		nfsstats.biocache_readdirs-nfsstats.readdir_bios,
173 		nfsstats.readdir_bios);
174 	printf(" %9d %9d\n",
175 		nfsstats.direofcache_hits, nfsstats.direofcache_misses);
176 	printf("\nServer Info:\n");
177 	printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
178 		"Getattr", "Setattr", "Lookup", "Readlink", "Read",
179 		"Write", "Create", "Remove");
180 	printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
181 		nfsstats.srvrpccnt[1],
182 		nfsstats.srvrpccnt[2],
183 		nfsstats.srvrpccnt[4],
184 		nfsstats.srvrpccnt[5],
185 		nfsstats.srvrpccnt[6],
186 		nfsstats.srvrpccnt[8],
187 		nfsstats.srvrpccnt[9],
188 		nfsstats.srvrpccnt[10]);
189 	printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
190 		"Rename", "Link", "Symlink", "Mkdir", "Rmdir",
191 		"Readdir", "Statfs");
192 	printf("%9d %9d %9d %9d %9d %9d %9d\n",
193 		nfsstats.srvrpccnt[11],
194 		nfsstats.srvrpccnt[12],
195 		nfsstats.srvrpccnt[13],
196 		nfsstats.srvrpccnt[14],
197 		nfsstats.srvrpccnt[15],
198 		nfsstats.srvrpccnt[16],
199 		nfsstats.srvrpccnt[17]);
200 	printf("Server Ret-Failed\n");
201 	printf("%17d\n", nfsstats.srvrpc_errs);
202 	printf("Server Faults\n");
203 	printf("%13d\n", nfsstats.srv_errs);
204 	printf("Server Cache Stats:\n");
205 	printf("%9.9s %9.9s %9.9s %9.9s\n",
206 		"Inprog", "Idem", "Non-idem", "Misses");
207 	printf("%9d %9d %9d %9d\n",
208 		nfsstats.srvcache_inproghits,
209 		nfsstats.srvcache_idemdonehits,
210 		nfsstats.srvcache_nonidemdonehits,
211 		nfsstats.srvcache_misses);
212 }
213 
214 u_char	signalled;			/* set if alarm goes off "early" */
215 
216 /*
217  * Print a running summary of nfs statistics.
218  * Repeat display every interval seconds, showing statistics
219  * collected over that interval.  Assumes that interval is non-zero.
220  * First line printed at top of screen is always cumulative.
221  */
222 void
223 sidewaysintpr(interval, off)
224 	u_int interval;
225 	off_t off;
226 {
227 	struct nfsstats nfsstats, lastst;
228 	int hdrcnt, oldmask;
229 	void catchalarm();
230 
231 	(void)signal(SIGALRM, catchalarm);
232 	signalled = 0;
233 	(void)alarm(interval);
234 	bzero((caddr_t)&lastst, sizeof(lastst));
235 
236 	for (hdrcnt = 1;;) {
237 		if (!--hdrcnt) {
238 			printhdr();
239 			hdrcnt = 20;
240 		}
241 		kvm_read((void *)off, (char *)&nfsstats, sizeof nfsstats);
242 		printf("Client: %8d %8d %8d %8d %8d %8d %8d %8d\n",
243 		    nfsstats.rpccnt[1]-lastst.rpccnt[1],
244 		    nfsstats.rpccnt[4]-lastst.rpccnt[4],
245 		    nfsstats.rpccnt[5]-lastst.rpccnt[5],
246 		    nfsstats.rpccnt[6]-lastst.rpccnt[6],
247 		    nfsstats.rpccnt[8]-lastst.rpccnt[8],
248 		    nfsstats.rpccnt[11]-lastst.rpccnt[11],
249 		    nfsstats.rpccnt[12]-lastst.rpccnt[12],
250 		    nfsstats.rpccnt[16]-lastst.rpccnt[16]);
251 		printf("Server: %8d %8d %8d %8d %8d %8d %8d %8d\n",
252 		    nfsstats.srvrpccnt[1]-lastst.srvrpccnt[1],
253 		    nfsstats.srvrpccnt[4]-lastst.srvrpccnt[4],
254 		    nfsstats.srvrpccnt[5]-lastst.srvrpccnt[5],
255 		    nfsstats.srvrpccnt[6]-lastst.srvrpccnt[6],
256 		    nfsstats.srvrpccnt[8]-lastst.srvrpccnt[8],
257 		    nfsstats.srvrpccnt[11]-lastst.srvrpccnt[11],
258 		    nfsstats.srvrpccnt[12]-lastst.srvrpccnt[12],
259 		    nfsstats.srvrpccnt[16]-lastst.srvrpccnt[16]);
260 		lastst = nfsstats;
261 		fflush(stdout);
262 		oldmask = sigblock(sigmask(SIGALRM));
263 		if (!signalled)
264 			sigpause(0);
265 		sigsetmask(oldmask);
266 		signalled = 0;
267 		(void)alarm(interval);
268 	}
269 	/*NOTREACHED*/
270 }
271 
272 void
273 printhdr()
274 {
275 	printf("        %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s\n",
276 	    "Getattr", "Lookup", "Readlink", "Read", "Write", "Rename",
277 	    "Link", "Readdir");
278 	fflush(stdout);
279 }
280 
281 /*
282  * Called if an interval expires before sidewaysintpr has completed a loop.
283  * Sets a flag to not wait for the alarm.
284  */
285 void
286 catchalarm()
287 {
288 	signalled = 1;
289 }
290 
291 void
292 usage()
293 {
294 	(void)fprintf(stderr,
295 	    "usage: nfsstat [-M core] [-N system] [-w interval]\n");
296 	exit(1);
297 }
298