pathname changes & addition of nroff rule for manpages
[unix-history] / usr / src / usr.bin / nfsstat / nfsstat.c
CommitLineData
4cbecdde
KM
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 *
87198c0c 8 * %sccs.include.redist.c%
4cbecdde
KM
9 */
10
11#ifndef lint
12char 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
87198c0c 18static char sccsid[] = "@(#)nfsstat.c 5.5 (Berkeley) %G%";
4cbecdde
KM
19#endif /* not lint */
20
21#include <sys/param.h>
22#include <sys/vmmac.h>
23#include <sys/file.h>
24#include <machine/pte.h>
25#include <sys/namei.h>
26#include <sys/mount.h>
27#include <nfs/nfsv2.h>
28#include <nfs/nfs.h>
29#include <ctype.h>
30#include <errno.h>
31#include <nlist.h>
32#include <stdio.h>
33#include <paths.h>
34
35#define YES 1
36#define NO 0
37
38struct nlist nl[] = {
39#define N_NFSSTAT 0
40 { "_nfsstats" },
41#define N_SYSMAP 1
42 { "_Sysmap" },
43#define N_SYSSIZE 2
44 { "_Syssize" },
45 "",
46};
47
48struct pte *Sysmap;
49
50char *system = _PATH_UNIX;
51char *kmemf = _PATH_KMEM;
52int kmem;
53int kflag;
54int interval;
55
56extern char *malloc();
57extern off_t lseek();
58
59main(argc, argv)
60 int argc;
61 char *argv[];
62{
63 int ch;
64
65 interval = 0;
66 argc--;
67 argv++;
68 if (argc > 0) {
69 interval = atoi(argv[0]);
70 if (interval <= 0)
71 usage();
72 argv++, argc--;
73 if (argc > 0) {
74 system = *argv;
75 argv++, argc--;
76 if (argc > 0) {
77 kmemf = *argv;
78 kflag++;
79 }
80 }
81 }
82 if (nlist(system, nl) < 0 || nl[0].n_type == 0) {
83 fprintf(stderr, "%s: no namelist\n", system);
84 exit(1);
85 }
86 kmem = open(kmemf, O_RDONLY);
87 if (kmem < 0) {
88 perror(kmemf);
89 exit(1);
90 }
91 if (kflag) {
92 off_t off;
93
94 Sysmap = (struct pte *)
95 malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
96 if (!Sysmap) {
97 fputs("nfsstat: can't get memory for Sysmap.\n", stderr);
98 exit(1);
99 }
100 off = nl[N_SYSMAP].n_value & ~KERNBASE;
101 (void)lseek(kmem, off, L_SET);
102 (void)read(kmem, (char *)Sysmap,
103 (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
104 }
105 intpr(interval, nl[N_NFSSTAT].n_value);
106 exit(0);
107}
108
109/*
110 * Seek into the kernel for a value.
111 */
112off_t
113klseek(fd, base, off)
114 int fd, off;
115 off_t base;
116{
117 if (kflag) {
118 /* get kernel pte */
119 base &= ~KERNBASE;
120 base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
121 }
122 return (lseek(fd, base, off));
123}
124
125usage()
126{
127 fputs("Usage: nfsstat [interval [ system [ corefile ] ] ]\n", stderr);
128 exit(1);
129}
130
131/*
132 * Print a description of the network interfaces.
133 */
134intpr(interval, nfsstataddr)
135 int interval;
136 off_t nfsstataddr;
137{
138 struct nfsstats nfsstats;
139
140 if (nfsstataddr == 0) {
141 printf("nfsstat: symbol not defined\n");
142 return;
143 }
144 if (interval) {
145 sidewaysintpr((unsigned)interval, nfsstataddr);
146 return;
147 }
148 klseek(kmem, nfsstataddr, 0);
149 read(kmem, (char *)&nfsstats, sizeof(struct nfsstats));
150 printf("Client Info:\n");
ab8b6a82 151 printf("Rpc Counts:\n");
4cbecdde
KM
152 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
153 "Getattr", "Setattr", "Lookup", "Readlink", "Read",
154 "Write", "Create", "Remove");
155 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
156 nfsstats.rpccnt[1],
157 nfsstats.rpccnt[2],
158 nfsstats.rpccnt[4],
159 nfsstats.rpccnt[5],
160 nfsstats.rpccnt[6],
161 nfsstats.rpccnt[8],
162 nfsstats.rpccnt[9],
163 nfsstats.rpccnt[10]);
164 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
165 "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
166 "Readdir", "Statfs");
167 printf("%9d %9d %9d %9d %9d %9d %9d\n",
168 nfsstats.rpccnt[11],
169 nfsstats.rpccnt[12],
170 nfsstats.rpccnt[13],
171 nfsstats.rpccnt[14],
172 nfsstats.rpccnt[15],
173 nfsstats.rpccnt[16],
174 nfsstats.rpccnt[17]);
ab8b6a82
KM
175 printf("Rpc Info:\n");
176 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
177 "TimedOut", "Invalid", "X Replies", "Retries", "Requests");
178 printf("%9d %9d %9d %9d %9d\n",
179 nfsstats.rpctimeouts,
180 nfsstats.rpcinvalid,
181 nfsstats.rpcunexpected,
182 nfsstats.rpcretries,
183 nfsstats.rpcrequests);
4cbecdde 184 printf("Cache Info:\n");
1b3a818d 185 printf("%9.9s %9.9s %9.9s %9.9s",
4cbecdde 186 "Attr Hits", "Misses", "Lkup Hits", "Misses");
1b3a818d
KM
187 printf(" %9.9s %9.9s %9.9s %9.9s\n",
188 "BioR Hits", "Misses", "BioW Hits", "Misses");
189 printf("%9d %9d %9d %9d",
4cbecdde
KM
190 nfsstats.attrcache_hits, nfsstats.attrcache_misses,
191 nfsstats.lookupcache_hits, nfsstats.lookupcache_misses);
1b3a818d
KM
192 printf(" %9d %9d %9d %9d\n",
193 nfsstats.biocache_reads-nfsstats.read_bios,
194 nfsstats.read_bios,
195 nfsstats.biocache_writes-nfsstats.write_bios,
196 nfsstats.write_bios);
ab8b6a82
KM
197 printf("%9.9s %9.9s %9.9s %9.9s",
198 "BioRLHits", "Misses", "BioD Hits", "Misses");
199 printf(" %9.9s %9.9s\n", "DirE Hits", "Misses");
200 printf("%9d %9d %9d %9d",
201 nfsstats.biocache_readlinks-nfsstats.readlink_bios,
202 nfsstats.readlink_bios,
203 nfsstats.biocache_readdirs-nfsstats.readdir_bios,
204 nfsstats.readdir_bios);
205 printf(" %9d %9d\n",
e6c65482 206 nfsstats.direofcache_hits, nfsstats.direofcache_misses);
ab8b6a82 207 printf("\nServer Info:\n");
4cbecdde
KM
208 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
209 "Getattr", "Setattr", "Lookup", "Readlink", "Read",
210 "Write", "Create", "Remove");
211 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
212 nfsstats.srvrpccnt[1],
213 nfsstats.srvrpccnt[2],
214 nfsstats.srvrpccnt[4],
215 nfsstats.srvrpccnt[5],
216 nfsstats.srvrpccnt[6],
217 nfsstats.srvrpccnt[8],
218 nfsstats.srvrpccnt[9],
219 nfsstats.srvrpccnt[10]);
220 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
221 "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
222 "Readdir", "Statfs");
223 printf("%9d %9d %9d %9d %9d %9d %9d\n",
224 nfsstats.srvrpccnt[11],
225 nfsstats.srvrpccnt[12],
226 nfsstats.srvrpccnt[13],
227 nfsstats.srvrpccnt[14],
228 nfsstats.srvrpccnt[15],
229 nfsstats.srvrpccnt[16],
230 nfsstats.srvrpccnt[17]);
1b3a818d 231 printf("Server Ret-Failed\n");
4cbecdde
KM
232 printf("%17d\n", nfsstats.srvrpc_errs);
233 printf("Server Faults\n");
234 printf("%13d\n", nfsstats.srv_errs);
1b3a818d
KM
235 printf("Server Cache Stats:\n");
236 printf("%9.9s %9.9s %9.9s %9.9s\n",
237 "Inprog", "Idem", "Non-idem", "Misses");
238 printf("%9d %9d %9d %9d\n",
239 nfsstats.srvcache_inproghits,
240 nfsstats.srvcache_idemdonehits,
241 nfsstats.srvcache_nonidemdonehits,
242 nfsstats.srvcache_misses);
4cbecdde
KM
243}
244
245u_char signalled; /* set if alarm goes off "early" */
246
247/*
248 * Print a running summary of nfs statistics.
249 * Repeat display every interval seconds, showing statistics
250 * collected over that interval. Assumes that interval is non-zero.
251 * First line printed at top of screen is always cumulative.
252 */
253sidewaysintpr(interval, off)
254 unsigned interval;
255 off_t off;
256{
257 struct nfsstats nfsstats, lastst;
258 register int line;
259 int oldmask;
260 int catchalarm();
261
262 klseek(kmem, off, 0);
263
264 (void)signal(SIGALRM, catchalarm);
265 signalled = NO;
266 (void)alarm(interval);
267 bzero((caddr_t)&lastst, sizeof(lastst));
268banner:
269 printf(" %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s\n",
270 "Getattr", "Lookup", "Readlink", "Read",
271 "Write", "Rename", "Link", "Readdir");
272 fflush(stdout);
273 line = 0;
274loop:
275 klseek(kmem, off, 0);
276 read(kmem, (char *)&nfsstats, sizeof nfsstats);
277 printf("Client: %8d %8d %8d %8d %8d %8d %8d %8d\n",
278 nfsstats.rpccnt[1]-lastst.rpccnt[1],
279 nfsstats.rpccnt[4]-lastst.rpccnt[4],
280 nfsstats.rpccnt[5]-lastst.rpccnt[5],
281 nfsstats.rpccnt[6]-lastst.rpccnt[6],
282 nfsstats.rpccnt[8]-lastst.rpccnt[8],
283 nfsstats.rpccnt[11]-lastst.rpccnt[11],
284 nfsstats.rpccnt[12]-lastst.rpccnt[12],
285 nfsstats.rpccnt[16]-lastst.rpccnt[16]);
286 printf("Server: %8d %8d %8d %8d %8d %8d %8d %8d\n",
287 nfsstats.srvrpccnt[1]-lastst.srvrpccnt[1],
288 nfsstats.srvrpccnt[4]-lastst.srvrpccnt[4],
289 nfsstats.srvrpccnt[5]-lastst.srvrpccnt[5],
290 nfsstats.srvrpccnt[6]-lastst.srvrpccnt[6],
291 nfsstats.srvrpccnt[8]-lastst.srvrpccnt[8],
292 nfsstats.srvrpccnt[11]-lastst.srvrpccnt[11],
293 nfsstats.srvrpccnt[12]-lastst.srvrpccnt[12],
294 nfsstats.srvrpccnt[16]-lastst.srvrpccnt[16]);
295 lastst = nfsstats;
296 fflush(stdout);
297 line++;
298 oldmask = sigblock(sigmask(SIGALRM));
299 if (! signalled) {
300 sigpause(0);
301 }
302 sigsetmask(oldmask);
303 signalled = NO;
304 (void)alarm(interval);
305 if (line == 21)
306 goto banner;
307 goto loop;
308 /*NOTREACHED*/
309}
310
311/*
312 * Called if an interval expires before sidewaysintpr has completed a loop.
313 * Sets a flag to not wait for the alarm.
314 */
315catchalarm()
316{
317 signalled = YES;
318}