2 * Copyright (c) 1983, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
38 static char copyright[] =
39 "@(#) Copyright (c) 1983, 1989, 1993\n\
40 The Regents of the University of California. All rights reserved.\n";
45 static char sccsid[] = "@(#)nfsstat.c 8.2 (Berkeley) 3/31/95";
47 static const char rcsid[] =
51 #include <sys/param.h>
52 #include <sys/mount.h>
54 #include <sys/sysctl.h>
55 #include <nfs/rpcv2.h>
56 #include <nfs/nfsproto.h>
57 #include <nfsclient/nfs.h>
58 #include <nfsserver/nfs.h>
82 static int deadkernel = 0;
83 static int widemode = 0;
86 void printhdr(int, int);
87 void sidewaysintpr(u_int, int, int);
89 char *sperc1(int, int);
90 char *sperc2(int, int);
92 #define DELTA(field) (nfsstats.field - lastst.field)
103 char errbuf[_POSIX2_LINE_MAX];
106 memf = nlistf = NULL;
107 while ((ch = getopt(argc, argv, "csWM:N:w:")) != -1)
119 interval = atoi(optarg);
138 #define BACKWARD_COMPATIBILITY
139 #ifdef BACKWARD_COMPATIBILITY
141 interval = atoi(*argv);
149 if (nlistf != NULL || memf != NULL) {
152 if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY,
154 errx(1, "kvm_openfiles: %s", errbuf);
156 if (kvm_nlist(kd, nl) != 0) {
157 errx(1, "kvm_nlist: can't get names");
162 sidewaysintpr(interval, clientOnly, serverOnly);
164 intpr(clientOnly, serverOnly);
169 * Read the nfs stats using sysctl(3) for live kernels, or kvm_read
173 readstats(stp, srvstp)
174 struct nfsstats **stp;
175 struct nfsrvstats **srvstp;
180 if (kvm_read(kd, (u_long)nl[N_NFSSTAT].n_value, *stp,
181 sizeof(struct nfsstats)) < 0) {
184 if (kvm_read(kd, (u_long)nl[N_NFSRVSTAT].n_value, *srvstp,
185 sizeof(struct nfsrvstats)) < 0) {
189 buflen = sizeof(struct nfsstats);
190 if (sysctlbyname("vfs.nfs.nfsstats", *stp, &buflen,
191 (void *)0, (size_t)0) < 0) {
194 buflen = sizeof(struct nfsrvstats);
195 if (sysctlbyname("vfs.nfsrv.nfsrvstats", *srvstp, &buflen,
196 (void *)0, (size_t)0) < 0) {
203 * Print a description of the nfs stats.
206 intpr(int clientOnly, int serverOnly)
208 struct nfsstats nfsstats, *nfsstatsp;
209 struct nfsrvstats nfsrvstats, *nfsrvstatsp;
211 nfsstatsp = &nfsstats;
212 nfsrvstatsp = &nfsrvstats;
214 readstats(&nfsstatsp, &nfsrvstatsp);
216 if (clientOnly && !nfsstatsp) {
217 printf("Client not present!\n");
221 printf("Client Info:\n");
222 printf("Rpc Counts:\n");
223 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
224 "Getattr", "Setattr", "Lookup", "Readlink", "Read",
225 "Write", "Create", "Remove");
226 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
227 nfsstats.rpccnt[NFSPROC_GETATTR],
228 nfsstats.rpccnt[NFSPROC_SETATTR],
229 nfsstats.rpccnt[NFSPROC_LOOKUP],
230 nfsstats.rpccnt[NFSPROC_READLINK],
231 nfsstats.rpccnt[NFSPROC_READ],
232 nfsstats.rpccnt[NFSPROC_WRITE],
233 nfsstats.rpccnt[NFSPROC_CREATE],
234 nfsstats.rpccnt[NFSPROC_REMOVE]);
235 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
236 "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
237 "Readdir", "RdirPlus", "Access");
238 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
239 nfsstats.rpccnt[NFSPROC_RENAME],
240 nfsstats.rpccnt[NFSPROC_LINK],
241 nfsstats.rpccnt[NFSPROC_SYMLINK],
242 nfsstats.rpccnt[NFSPROC_MKDIR],
243 nfsstats.rpccnt[NFSPROC_RMDIR],
244 nfsstats.rpccnt[NFSPROC_READDIR],
245 nfsstats.rpccnt[NFSPROC_READDIRPLUS],
246 nfsstats.rpccnt[NFSPROC_ACCESS]);
247 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
248 "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
249 printf("%9d %9d %9d %9d %9d\n",
250 nfsstats.rpccnt[NFSPROC_MKNOD],
251 nfsstats.rpccnt[NFSPROC_FSSTAT],
252 nfsstats.rpccnt[NFSPROC_FSINFO],
253 nfsstats.rpccnt[NFSPROC_PATHCONF],
254 nfsstats.rpccnt[NFSPROC_COMMIT]);
255 printf("Rpc Info:\n");
256 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
257 "TimedOut", "Invalid", "X Replies", "Retries",
259 printf("%9d %9d %9d %9d %9d\n",
260 nfsstats.rpctimeouts,
262 nfsstats.rpcunexpected,
264 nfsstats.rpcrequests);
265 printf("Cache Info:\n");
266 printf("%9.9s %9.9s %9.9s %9.9s",
267 "Attr Hits", "Misses", "Lkup Hits", "Misses");
268 printf(" %9.9s %9.9s %9.9s %9.9s\n",
269 "BioR Hits", "Misses", "BioW Hits", "Misses");
270 printf("%9d %9d %9d %9d",
271 nfsstats.attrcache_hits, nfsstats.attrcache_misses,
272 nfsstats.lookupcache_hits, nfsstats.lookupcache_misses);
273 printf(" %9d %9d %9d %9d\n",
274 nfsstats.biocache_reads-nfsstats.read_bios,
276 nfsstats.biocache_writes-nfsstats.write_bios,
277 nfsstats.write_bios);
278 printf("%9.9s %9.9s %9.9s %9.9s",
279 "BioRLHits", "Misses", "BioD Hits", "Misses");
280 printf(" %9.9s %9.9s\n", "DirE Hits", "Misses");
281 printf("%9d %9d %9d %9d",
282 nfsstats.biocache_readlinks-nfsstats.readlink_bios,
283 nfsstats.readlink_bios,
284 nfsstats.biocache_readdirs-nfsstats.readdir_bios,
285 nfsstats.readdir_bios);
287 nfsstats.direofcache_hits, nfsstats.direofcache_misses);
289 if (serverOnly && !nfsrvstatsp) {
290 printf("Server not present!\n");
294 printf("\nServer Info:\n");
295 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
296 "Getattr", "Setattr", "Lookup", "Readlink", "Read",
297 "Write", "Create", "Remove");
298 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
299 nfsrvstats.srvrpccnt[NFSPROC_GETATTR],
300 nfsrvstats.srvrpccnt[NFSPROC_SETATTR],
301 nfsrvstats.srvrpccnt[NFSPROC_LOOKUP],
302 nfsrvstats.srvrpccnt[NFSPROC_READLINK],
303 nfsrvstats.srvrpccnt[NFSPROC_READ],
304 nfsrvstats.srvrpccnt[NFSPROC_WRITE],
305 nfsrvstats.srvrpccnt[NFSPROC_CREATE],
306 nfsrvstats.srvrpccnt[NFSPROC_REMOVE]);
307 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
308 "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
309 "Readdir", "RdirPlus", "Access");
310 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
311 nfsrvstats.srvrpccnt[NFSPROC_RENAME],
312 nfsrvstats.srvrpccnt[NFSPROC_LINK],
313 nfsrvstats.srvrpccnt[NFSPROC_SYMLINK],
314 nfsrvstats.srvrpccnt[NFSPROC_MKDIR],
315 nfsrvstats.srvrpccnt[NFSPROC_RMDIR],
316 nfsrvstats.srvrpccnt[NFSPROC_READDIR],
317 nfsrvstats.srvrpccnt[NFSPROC_READDIRPLUS],
318 nfsrvstats.srvrpccnt[NFSPROC_ACCESS]);
319 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
320 "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
321 printf("%9d %9d %9d %9d %9d\n",
322 nfsrvstats.srvrpccnt[NFSPROC_MKNOD],
323 nfsrvstats.srvrpccnt[NFSPROC_FSSTAT],
324 nfsrvstats.srvrpccnt[NFSPROC_FSINFO],
325 nfsrvstats.srvrpccnt[NFSPROC_PATHCONF],
326 nfsrvstats.srvrpccnt[NFSPROC_COMMIT]);
327 printf("Server Ret-Failed\n");
328 printf("%17d\n", nfsrvstats.srvrpc_errs);
329 printf("Server Faults\n");
330 printf("%13d\n", nfsrvstats.srv_errs);
331 printf("Server Cache Stats:\n");
332 printf("%9.9s %9.9s %9.9s %9.9s\n",
333 "Inprog", "Idem", "Non-idem", "Misses");
334 printf("%9d %9d %9d %9d\n",
335 nfsrvstats.srvcache_inproghits,
336 nfsrvstats.srvcache_idemdonehits,
337 nfsrvstats.srvcache_nonidemdonehits,
338 nfsrvstats.srvcache_misses);
339 printf("Server Write Gathering:\n");
340 printf("%9.9s %9.9s %9.9s\n",
341 "WriteOps", "WriteRPC", "Opsaved");
342 printf("%9d %9d %9d\n",
343 nfsrvstats.srvvop_writes,
344 nfsrvstats.srvrpccnt[NFSPROC_WRITE],
345 nfsrvstats.srvrpccnt[NFSPROC_WRITE] -
346 nfsrvstats.srvvop_writes);
350 u_char signalled; /* set if alarm goes off "early" */
353 * Print a running summary of nfs statistics.
354 * Repeat display every interval seconds, showing statistics
355 * collected over that interval. Assumes that interval is non-zero.
356 * First line printed at top of screen is always cumulative.
359 sidewaysintpr(u_int interval, int clientOnly, int serverOnly)
361 struct nfsstats nfsstats, lastst, *nfsstatsp;
362 struct nfsrvstats nfsrvstats, lastsrvst, *nfsrvstatsp;
366 nfsrvstatsp = &lastsrvst;
367 readstats(&nfsstatsp, &nfsrvstatsp);
368 if (clientOnly && !nfsstatsp) {
369 printf("Client not present!\n");
372 if (serverOnly && !nfsrvstatsp) {
373 printf("Server not present!\n");
379 nfsstatsp = &nfsstats;
380 nfsrvstatsp = &nfsrvstats;
381 readstats(&nfsstatsp, &nfsrvstatsp);
384 printhdr(clientOnly, serverOnly);
385 if (clientOnly && serverOnly)
391 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d",
392 ((clientOnly && serverOnly) ? "Client:" : ""),
393 DELTA(attrcache_hits) + DELTA(attrcache_misses),
394 DELTA(lookupcache_hits) + DELTA(lookupcache_misses),
395 DELTA(biocache_readlinks),
396 DELTA(biocache_reads),
397 DELTA(biocache_writes),
398 nfsstats.rpccnt[NFSPROC_RENAME]-lastst.rpccnt[NFSPROC_RENAME],
399 DELTA(accesscache_hits) + DELTA(accesscache_misses),
400 DELTA(biocache_readdirs)
403 printf(" %s %s %s %s %s %s",
404 sperc1(DELTA(attrcache_hits),
405 DELTA(attrcache_misses)),
406 sperc1(DELTA(lookupcache_hits),
407 DELTA(lookupcache_misses)),
408 sperc2(DELTA(biocache_reads),
410 sperc2(DELTA(biocache_writes),
412 sperc1(DELTA(accesscache_hits),
413 DELTA(accesscache_misses)),
414 sperc2(DELTA(biocache_readdirs),
422 printf("%s %6d %6d %6d %6d %6d %6d %6d %6d",
423 ((clientOnly && serverOnly) ? "Server:" : ""),
424 nfsrvstats.srvrpccnt[NFSPROC_GETATTR]-lastsrvst.srvrpccnt[NFSPROC_GETATTR],
425 nfsrvstats.srvrpccnt[NFSPROC_LOOKUP]-lastsrvst.srvrpccnt[NFSPROC_LOOKUP],
426 nfsrvstats.srvrpccnt[NFSPROC_READLINK]-lastsrvst.srvrpccnt[NFSPROC_READLINK],
427 nfsrvstats.srvrpccnt[NFSPROC_READ]-lastsrvst.srvrpccnt[NFSPROC_READ],
428 nfsrvstats.srvrpccnt[NFSPROC_WRITE]-lastsrvst.srvrpccnt[NFSPROC_WRITE],
429 nfsrvstats.srvrpccnt[NFSPROC_RENAME]-lastsrvst.srvrpccnt[NFSPROC_RENAME],
430 nfsrvstats.srvrpccnt[NFSPROC_ACCESS]-lastsrvst.srvrpccnt[NFSPROC_ACCESS],
431 (nfsrvstats.srvrpccnt[NFSPROC_READDIR]-lastsrvst.srvrpccnt[NFSPROC_READDIR])
432 +(nfsrvstats.srvrpccnt[NFSPROC_READDIRPLUS]-lastsrvst.srvrpccnt[NFSPROC_READDIRPLUS]));
434 lastsrvst = nfsrvstats;
443 printhdr(int clientOnly, int serverOnly)
445 printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
446 ((serverOnly && clientOnly) ? " " : " "),
447 "GtAttr", "Lookup", "Rdlink", "Read", "Write", "Rename",
449 if (widemode && clientOnly) {
450 printf(" Attr Lkup BioR BioW Accs BioD");
459 (void)fprintf(stderr,
460 "usage: nfsstat [-csW] [-M core] [-N system] [-w interval]\n");
464 static char SPBuf[64][8];
468 sperc1(int hits, int misses)
470 char *p = SPBuf[SPIndex];
474 (int)(char)((quad_t)hits * 100 / (hits + misses)));
478 SPIndex = (SPIndex + 1) & 63;
483 sperc2(int ttl, int misses)
485 char *p = SPBuf[SPIndex];
489 (int)(char)((quad_t)(ttl - misses) * 100 / ttl));
493 SPIndex = (SPIndex + 1) & 63;