]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/nfsstat/nfsstat.c
Merge OpenSSL 1.0.2f.
[FreeBSD/FreeBSD.git] / usr.bin / nfsstat / nfsstat.c
1 /*
2  * Copyright (c) 1983, 1989, 1993
3  *      The Regents of the University of California.  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  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
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  * 4. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 #ifndef lint
34 static const char copyright[] =
35 "@(#) Copyright (c) 1983, 1989, 1993\n\
36         The Regents of the University of California.  All rights reserved.\n";
37 #endif /* not lint */
38
39 #ifndef lint
40 #if 0
41 static char sccsid[] = "@(#)nfsstat.c   8.2 (Berkeley) 3/31/95";
42 #endif
43 static const char rcsid[] =
44   "$FreeBSD$";
45 #endif /* not lint */
46
47 #include <sys/param.h>
48 #include <sys/module.h>
49 #include <sys/mount.h>
50 #include <sys/time.h>
51 #include <sys/sysctl.h>
52 #include <nfs/nfsproto.h>
53 #include <nfsclient/nfs.h>
54 #include <nfsserver/nfs.h>
55 #include <nfs/nfssvc.h>
56
57 #include <fs/nfs/nfsport.h>
58
59 #include <signal.h>
60 #include <fcntl.h>
61 #include <ctype.h>
62 #include <errno.h>
63 #include <limits.h>
64 #include <nlist.h>
65 #include <unistd.h>
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include <paths.h>
70 #include <err.h>
71
72 static int widemode = 0;
73 static int zflag = 0;
74 static int printtitle = 1;
75 static struct ext_nfsstats ext_nfsstats;
76 static int extra_output = 0;
77
78 static void intpr(int, int);
79 static void printhdr(int, int);
80 static void usage(void);
81 static char *sperc1(int, int);
82 static char *sperc2(int, int);
83 static void exp_intpr(int, int);
84 static void exp_sidewaysintpr(u_int, int, int);
85
86 #define DELTA(field)    (nfsstats.field - lastst.field)
87
88 int
89 main(int argc, char **argv)
90 {
91         u_int interval;
92         int clientOnly = -1;
93         int serverOnly = -1;
94         int ch;
95         char *memf, *nlistf;
96         int mntlen, i;
97         char buf[1024];
98         struct statfs *mntbuf;
99         struct nfscl_dumpmntopts dumpmntopts;
100
101         interval = 0;
102         memf = nlistf = NULL;
103         while ((ch = getopt(argc, argv, "cesWM:mN:w:z")) != -1)
104                 switch(ch) {
105                 case 'M':
106                         memf = optarg;
107                         break;
108                 case 'm':
109                         /* Display mount options for NFS mount points. */
110                         mntlen = getmntinfo(&mntbuf, MNT_NOWAIT);
111                         for (i = 0; i < mntlen; i++) {
112                                 if (strcmp(mntbuf->f_fstypename, "nfs") == 0) {
113                                         dumpmntopts.ndmnt_fname =
114                                             mntbuf->f_mntonname;
115                                         dumpmntopts.ndmnt_buf = buf;
116                                         dumpmntopts.ndmnt_blen = sizeof(buf);
117                                         if (nfssvc(NFSSVC_DUMPMNTOPTS,
118                                             &dumpmntopts) >= 0)
119                                                 printf("%s on %s\n%s\n",
120                                                     mntbuf->f_mntfromname,
121                                                     mntbuf->f_mntonname, buf);
122                                         else if (errno == EPERM)
123                                                 errx(1, "Only priviledged users"
124                                                     " can use the -m option");
125                                 }
126                                 mntbuf++;
127                         }
128                         exit(0);
129                 case 'N':
130                         nlistf = optarg;
131                         break;
132                 case 'W':
133                         widemode = 1;
134                         break;
135                 case 'w':
136                         interval = atoi(optarg);
137                         break;
138                 case 'c':
139                         clientOnly = 1;
140                         if (serverOnly < 0)
141                                 serverOnly = 0;
142                         break;
143                 case 's':
144                         serverOnly = 1;
145                         if (clientOnly < 0)
146                                 clientOnly = 0;
147                         break;
148                 case 'z':
149                         zflag = 1;
150                         break;
151                 case 'e':
152                         extra_output = 1;
153                         break;
154                 case '?':
155                 default:
156                         usage();
157                 }
158         argc -= optind;
159         argv += optind;
160
161 #define BACKWARD_COMPATIBILITY
162 #ifdef  BACKWARD_COMPATIBILITY
163         if (*argv) {
164                 interval = atoi(*argv);
165                 if (*++argv) {
166                         nlistf = *argv;
167                         if (*++argv)
168                                 memf = *argv;
169                 }
170         }
171 #endif
172         if (modfind("nfscommon") < 0)
173                 errx(1, "NFS client/server not loaded");
174
175         if (interval) {
176                 exp_sidewaysintpr(interval, clientOnly, serverOnly);
177         } else {
178                 if (extra_output != 0)
179                         exp_intpr(clientOnly, serverOnly);
180                 else
181                         intpr(clientOnly, serverOnly);
182         }
183         exit(0);
184 }
185
186 /*
187  * Print a description of the nfs stats.
188  */
189 static void
190 intpr(int clientOnly, int serverOnly)
191 {
192         int nfssvc_flag;
193
194         nfssvc_flag = NFSSVC_GETSTATS;
195         if (zflag != 0) {
196                 if (clientOnly != 0)
197                         nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
198                 if (serverOnly != 0)
199                         nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
200         }
201         if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
202                 err(1, "Can't get stats");
203         if (clientOnly) {
204                 printf("Client Info:\n");
205                 printf("Rpc Counts:\n");
206                 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
207                         "Getattr", "Setattr", "Lookup", "Readlink", "Read",
208                         "Write", "Create", "Remove");
209                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
210                         ext_nfsstats.rpccnt[NFSPROC_GETATTR],
211                         ext_nfsstats.rpccnt[NFSPROC_SETATTR],
212                         ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
213                         ext_nfsstats.rpccnt[NFSPROC_READLINK],
214                         ext_nfsstats.rpccnt[NFSPROC_READ],
215                         ext_nfsstats.rpccnt[NFSPROC_WRITE],
216                         ext_nfsstats.rpccnt[NFSPROC_CREATE],
217                         ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
218                 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
219                         "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
220                         "Readdir", "RdirPlus", "Access");
221                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
222                         ext_nfsstats.rpccnt[NFSPROC_RENAME],
223                         ext_nfsstats.rpccnt[NFSPROC_LINK],
224                         ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
225                         ext_nfsstats.rpccnt[NFSPROC_MKDIR],
226                         ext_nfsstats.rpccnt[NFSPROC_RMDIR],
227                         ext_nfsstats.rpccnt[NFSPROC_READDIR],
228                         ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
229                         ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
230                 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
231                         "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
232                 printf("%9d %9d %9d %9d %9d\n",
233                         ext_nfsstats.rpccnt[NFSPROC_MKNOD],
234                         ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
235                         ext_nfsstats.rpccnt[NFSPROC_FSINFO],
236                         ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
237                         ext_nfsstats.rpccnt[NFSPROC_COMMIT]);
238                 printf("Rpc Info:\n");
239                 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
240                         "TimedOut", "Invalid", "X Replies", "Retries", 
241                         "Requests");
242                 printf("%9d %9d %9d %9d %9d\n",
243                         ext_nfsstats.rpctimeouts,
244                         ext_nfsstats.rpcinvalid,
245                         ext_nfsstats.rpcunexpected,
246                         ext_nfsstats.rpcretries,
247                         ext_nfsstats.rpcrequests);
248                 printf("Cache Info:\n");
249                 printf("%9.9s %9.9s %9.9s %9.9s",
250                         "Attr Hits", "Misses", "Lkup Hits", "Misses");
251                 printf(" %9.9s %9.9s %9.9s %9.9s\n",
252                         "BioR Hits", "Misses", "BioW Hits", "Misses");
253                 printf("%9d %9d %9d %9d",
254                         ext_nfsstats.attrcache_hits,
255                         ext_nfsstats.attrcache_misses,
256                         ext_nfsstats.lookupcache_hits,
257                         ext_nfsstats.lookupcache_misses);
258                 printf(" %9d %9d %9d %9d\n",
259                         ext_nfsstats.biocache_reads -
260                         ext_nfsstats.read_bios,
261                         ext_nfsstats.read_bios,
262                         ext_nfsstats.biocache_writes -
263                         ext_nfsstats.write_bios,
264                         ext_nfsstats.write_bios);
265                 printf("%9.9s %9.9s %9.9s %9.9s",
266                         "BioRLHits", "Misses", "BioD Hits", "Misses");
267                 printf(" %9.9s %9.9s %9.9s %9.9s\n", "DirE Hits", "Misses", "Accs Hits", "Misses");
268                 printf("%9d %9d %9d %9d",
269                         ext_nfsstats.biocache_readlinks -
270                         ext_nfsstats.readlink_bios,
271                         ext_nfsstats.readlink_bios,
272                         ext_nfsstats.biocache_readdirs -
273                         ext_nfsstats.readdir_bios,
274                         ext_nfsstats.readdir_bios);
275                 printf(" %9d %9d %9d %9d\n",
276                         ext_nfsstats.direofcache_hits,
277                         ext_nfsstats.direofcache_misses,
278                         ext_nfsstats.accesscache_hits,
279                         ext_nfsstats.accesscache_misses);
280         }
281         if (serverOnly) {
282                 printf("\nServer Info:\n");
283                 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
284                         "Getattr", "Setattr", "Lookup", "Readlink", "Read",
285                         "Write", "Create", "Remove");
286                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
287                         ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
288                         ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
289                         ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
290                         ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
291                         ext_nfsstats.srvrpccnt[NFSV4OP_READ],
292                         ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
293                         ext_nfsstats.srvrpccnt[NFSV4OP_CREATE],
294                         ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
295                 printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
296                         "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
297                         "Readdir", "RdirPlus", "Access");
298                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
299                         ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
300                         ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
301                         ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
302                         ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
303                         ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
304                         ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
305                         ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
306                         ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
307                 printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
308                         "Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
309                 printf("%9d %9d %9d %9d %9d\n",
310                         ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
311                         ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
312                         ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
313                         ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
314                         ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT]);
315                 printf("Server Ret-Failed\n");
316                 printf("%17d\n", ext_nfsstats.srvrpc_errs);
317                 printf("Server Faults\n");
318                 printf("%13d\n", ext_nfsstats.srv_errs);
319                 printf("Server Cache Stats:\n");
320                 printf("%9.9s %9.9s %9.9s %9.9s\n",
321                         "Inprog", "Idem", "Non-idem", "Misses");
322                 printf("%9d %9d %9d %9d\n",
323                         ext_nfsstats.srvcache_inproghits,
324                         ext_nfsstats.srvcache_idemdonehits,
325                         ext_nfsstats.srvcache_nonidemdonehits,
326                         ext_nfsstats.srvcache_misses);
327                 printf("Server Write Gathering:\n");
328                 printf("%9.9s %9.9s %9.9s\n",
329                         "WriteOps", "WriteRPC", "Opsaved");
330                 /*
331                  * The new client doesn't do write gathering. It was
332                  * only useful for NFSv2.
333                  */
334                 printf("%9d %9d %9d\n",
335                         ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
336                         ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 0);
337         }
338 }
339
340 static void
341 printhdr(int clientOnly, int serverOnly)
342 {
343         printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
344             ((serverOnly && clientOnly) ? "        " : " "),
345             "GtAttr", "Lookup", "Rdlink", "Read", "Write", "Rename",
346             "Access", "Rddir");
347         if (widemode && clientOnly) {
348                 printf(" Attr Lkup BioR BioW Accs BioD");
349         }
350         printf("\n");
351         fflush(stdout);
352 }
353
354 static void
355 usage(void)
356 {
357         (void)fprintf(stderr,
358             "usage: nfsstat [-cemszW] [-M core] [-N system] [-w wait]\n");
359         exit(1);
360 }
361
362 static char SPBuf[64][8];
363 static int SPIndex;
364
365 static char * 
366 sperc1(int hits, int misses)
367 {
368         char *p = SPBuf[SPIndex];
369
370         if (hits + misses) {
371                 sprintf(p, "%3d%%", 
372                     (int)(char)((quad_t)hits * 100 / (hits + misses)));
373         } else {
374                 sprintf(p, "   -");
375         }
376         SPIndex = (SPIndex + 1) & 63;
377         return(p);
378 }
379
380 static char * 
381 sperc2(int ttl, int misses)
382 {
383         char *p = SPBuf[SPIndex];
384
385         if (ttl) {
386                 sprintf(p, "%3d%%",
387                     (int)(char)((quad_t)(ttl - misses) * 100 / ttl));
388         } else {
389                 sprintf(p, "   -");
390         }
391         SPIndex = (SPIndex + 1) & 63;
392         return(p);
393 }
394
395 /*
396  * Print a description of the nfs stats for the experimental client/server.
397  */
398 static void
399 exp_intpr(int clientOnly, int serverOnly)
400 {
401         int nfssvc_flag;
402
403         nfssvc_flag = NFSSVC_GETSTATS;
404         if (zflag != 0) {
405                 if (clientOnly != 0)
406                         nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
407                 if (serverOnly != 0)
408                         nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
409         }
410         if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
411                 err(1, "Can't get stats");
412         if (clientOnly != 0) {
413                 if (printtitle) {
414                         printf("Client Info:\n");
415                         printf("Rpc Counts:\n");
416                         printf(
417                             "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
418                             , "Getattr", "Setattr", "Lookup", "Readlink",
419                             "Read", "Write", "Create", "Remove");
420                 }
421                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
422                     ext_nfsstats.rpccnt[NFSPROC_GETATTR],
423                     ext_nfsstats.rpccnt[NFSPROC_SETATTR],
424                     ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
425                     ext_nfsstats.rpccnt[NFSPROC_READLINK],
426                     ext_nfsstats.rpccnt[NFSPROC_READ],
427                     ext_nfsstats.rpccnt[NFSPROC_WRITE],
428                     ext_nfsstats.rpccnt[NFSPROC_CREATE],
429                     ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
430                 if (printtitle)
431                         printf(
432                             "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
433                             , "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
434                             "Readdir", "RdirPlus", "Access");
435                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
436                     ext_nfsstats.rpccnt[NFSPROC_RENAME],
437                     ext_nfsstats.rpccnt[NFSPROC_LINK],
438                     ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
439                     ext_nfsstats.rpccnt[NFSPROC_MKDIR],
440                     ext_nfsstats.rpccnt[NFSPROC_RMDIR],
441                     ext_nfsstats.rpccnt[NFSPROC_READDIR],
442                     ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
443                     ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
444                 if (printtitle)
445                         printf(
446                             "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
447                             , "Mknod", "Fsstat", "Fsinfo", "PathConf",
448                             "Commit", "SetClId", "SetClIdCf", "Lock");
449                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
450                     ext_nfsstats.rpccnt[NFSPROC_MKNOD],
451                     ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
452                     ext_nfsstats.rpccnt[NFSPROC_FSINFO],
453                     ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
454                     ext_nfsstats.rpccnt[NFSPROC_COMMIT],
455                     ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID],
456                     ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM],
457                     ext_nfsstats.rpccnt[NFSPROC_LOCK]);
458                 if (printtitle)
459                         printf("%9.9s %9.9s %9.9s %9.9s\n",
460                             "LockT", "LockU", "Open", "OpenCfr");
461                 printf("%9d %9d %9d %9d\n",
462                     ext_nfsstats.rpccnt[NFSPROC_LOCKT],
463                     ext_nfsstats.rpccnt[NFSPROC_LOCKU],
464                     ext_nfsstats.rpccnt[NFSPROC_OPEN],
465                     ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM]);
466                 if (printtitle)
467                         printf(
468                             "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
469                             , "OpenOwner", "Opens", "LockOwner",
470                             "Locks", "Delegs", "LocalOwn",
471                             "LocalOpen", "LocalLOwn");
472                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
473                     ext_nfsstats.clopenowners,
474                     ext_nfsstats.clopens,
475                     ext_nfsstats.cllockowners,
476                     ext_nfsstats.cllocks,
477                     ext_nfsstats.cldelegates,
478                     ext_nfsstats.cllocalopenowners,
479                     ext_nfsstats.cllocalopens,
480                     ext_nfsstats.cllocallockowners);
481                 if (printtitle)
482                         printf("%9.9s\n", "LocalLock");
483                 printf("%9d\n", ext_nfsstats.cllocallocks);
484                 if (printtitle) {
485                         printf("Rpc Info:\n");
486                         printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
487                             "TimedOut", "Invalid", "X Replies", "Retries",
488                             "Requests");
489                 }
490                 printf("%9d %9d %9d %9d %9d\n",
491                     ext_nfsstats.rpctimeouts,
492                     ext_nfsstats.rpcinvalid,
493                     ext_nfsstats.rpcunexpected,
494                     ext_nfsstats.rpcretries,
495                     ext_nfsstats.rpcrequests);
496                 if (printtitle) {
497                         printf("Cache Info:\n");
498                         printf("%9.9s %9.9s %9.9s %9.9s",
499                             "Attr Hits", "Misses", "Lkup Hits", "Misses");
500                         printf(" %9.9s %9.9s %9.9s %9.9s\n",
501                             "BioR Hits", "Misses", "BioW Hits", "Misses");
502                 }
503                 printf("%9d %9d %9d %9d",
504                     ext_nfsstats.attrcache_hits,
505                     ext_nfsstats.attrcache_misses,
506                     ext_nfsstats.lookupcache_hits,
507                     ext_nfsstats.lookupcache_misses);
508                 printf(" %9d %9d %9d %9d\n",
509                     ext_nfsstats.biocache_reads - ext_nfsstats.read_bios,
510                     ext_nfsstats.read_bios,
511                     ext_nfsstats.biocache_writes - ext_nfsstats.write_bios,
512                     ext_nfsstats.write_bios);
513                 if (printtitle) {
514                         printf("%9.9s %9.9s %9.9s %9.9s",
515                             "BioRLHits", "Misses", "BioD Hits", "Misses");
516                         printf(" %9.9s %9.9s\n", "DirE Hits", "Misses");
517                 }
518                 printf("%9d %9d %9d %9d",
519                     ext_nfsstats.biocache_readlinks -
520                     ext_nfsstats.readlink_bios,
521                     ext_nfsstats.readlink_bios,
522                     ext_nfsstats.biocache_readdirs -
523                     ext_nfsstats.readdir_bios,
524                     ext_nfsstats.readdir_bios);
525                 printf(" %9d %9d\n",
526                     ext_nfsstats.direofcache_hits,
527                     ext_nfsstats.direofcache_misses);
528         }
529         if (serverOnly != 0) {
530                 if (printtitle) {
531                         printf("\nServer Info:\n");
532                         printf(
533                             "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
534                             , "Getattr", "Setattr", "Lookup", "Readlink",
535                             "Read", "Write", "Create", "Remove");
536                 }
537                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
538                     ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
539                     ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
540                     ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
541                     ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
542                     ext_nfsstats.srvrpccnt[NFSV4OP_READ],
543                     ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
544                     ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE],
545                     ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
546                 if (printtitle)
547                         printf(
548                             "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
549                             , "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
550                             "Readdir", "RdirPlus", "Access");
551                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
552                     ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
553                     ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
554                     ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
555                     ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
556                     ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
557                     ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
558                     ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
559                     ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
560                 if (printtitle)
561                         printf(
562                             "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
563                             , "Mknod", "Fsstat", "Fsinfo", "PathConf",
564                             "Commit", "LookupP", "SetClId", "SetClIdCf");
565                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
566                     ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
567                     ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
568                     ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
569                     ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
570                     ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT],
571                     ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP],
572                     ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID],
573                     ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]);
574                 if (printtitle)
575                         printf(
576                             "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
577                             , "Open", "OpenAttr", "OpenDwnGr", "OpenCfrm",
578                             "DelePurge", "DeleRet", "GetFH", "Lock");
579                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
580                     ext_nfsstats.srvrpccnt[NFSV4OP_OPEN],
581                     ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR],
582                     ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE],
583                     ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM],
584                     ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE],
585                     ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN],
586                     ext_nfsstats.srvrpccnt[NFSV4OP_GETFH],
587                     ext_nfsstats.srvrpccnt[NFSV4OP_LOCK]);
588                 if (printtitle)
589                         printf(
590                             "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
591                             , "LockT", "LockU", "Close", "Verify", "NVerify",
592                             "PutFH", "PutPubFH", "PutRootFH");
593                 printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
594                     ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT],
595                     ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU],
596                     ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE],
597                     ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY],
598                     ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY],
599                     ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH],
600                     ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH],
601                     ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH]);
602                 if (printtitle)
603                         printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
604                             "Renew", "RestoreFH", "SaveFH", "Secinfo",
605                             "RelLckOwn", "V4Create");
606                 printf("%9d %9d %9d %9d %9d %9d\n",
607                     ext_nfsstats.srvrpccnt[NFSV4OP_RENEW],
608                     ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH],
609                     ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH],
610                     ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO],
611                     ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN],
612                     ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]);
613                 if (printtitle) {
614                         printf("Server:\n");
615                         printf("%9.9s %9.9s %9.9s\n",
616                             "Retfailed", "Faults", "Clients");
617                 }
618                 printf("%9d %9d %9d\n",
619                     ext_nfsstats.srv_errs, ext_nfsstats.srvrpc_errs,
620                     ext_nfsstats.srvclients);
621                 if (printtitle)
622                         printf("%9.9s %9.9s %9.9s %9.9s %9.9s \n",
623                             "OpenOwner", "Opens", "LockOwner",
624                             "Locks", "Delegs");
625                 printf("%9d %9d %9d %9d %9d \n",
626                     ext_nfsstats.srvopenowners,
627                     ext_nfsstats.srvopens,
628                     ext_nfsstats.srvlockowners,
629                     ext_nfsstats.srvlocks,
630                     ext_nfsstats.srvdelegates);
631                 if (printtitle) {
632                         printf("Server Cache Stats:\n");
633                         printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
634                             "Inprog", "Idem", "Non-idem", "Misses", 
635                             "CacheSize", "TCPPeak");
636                 }
637                 printf("%9d %9d %9d %9d %9d %9d\n",
638                     ext_nfsstats.srvcache_inproghits,
639                     ext_nfsstats.srvcache_idemdonehits,
640                     ext_nfsstats.srvcache_nonidemdonehits,
641                     ext_nfsstats.srvcache_misses,
642                     ext_nfsstats.srvcache_size,
643                     ext_nfsstats.srvcache_tcppeak);
644         }
645 }
646
647 /*
648  * Print a running summary of nfs statistics for the experimental client and/or
649  * server.
650  * Repeat display every interval seconds, showing statistics
651  * collected over that interval.  Assumes that interval is non-zero.
652  * First line printed at top of screen is always cumulative.
653  */
654 static void
655 exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly)
656 {
657         struct ext_nfsstats nfsstats, lastst, *ext_nfsstatsp;
658         int hdrcnt = 1;
659
660         ext_nfsstatsp = &lastst;
661         if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0)
662                 err(1, "Can't get stats");
663         sleep(interval);
664
665         for (;;) {
666                 ext_nfsstatsp = &nfsstats;
667                 if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0)
668                         err(1, "Can't get stats");
669
670                 if (--hdrcnt == 0) {
671                         printhdr(clientOnly, serverOnly);
672                         if (clientOnly && serverOnly)
673                                 hdrcnt = 10;
674                         else
675                                 hdrcnt = 20;
676                 }
677                 if (clientOnly) {
678                     printf("%s %6d %6d %6d %6d %6d %6d %6d %6d",
679                         ((clientOnly && serverOnly) ? "Client:" : ""),
680                         DELTA(rpccnt[NFSPROC_GETATTR]),
681                         DELTA(rpccnt[NFSPROC_LOOKUP]),
682                         DELTA(rpccnt[NFSPROC_READLINK]),
683                         DELTA(rpccnt[NFSPROC_READ]),
684                         DELTA(rpccnt[NFSPROC_WRITE]),
685                         DELTA(rpccnt[NFSPROC_RENAME]),
686                         DELTA(rpccnt[NFSPROC_ACCESS]),
687                         DELTA(rpccnt[NFSPROC_READDIR]) +
688                         DELTA(rpccnt[NFSPROC_READDIRPLUS])
689                     );
690                     if (widemode) {
691                             printf(" %s %s %s %s %s %s",
692                                 sperc1(DELTA(attrcache_hits),
693                                     DELTA(attrcache_misses)),
694                                 sperc1(DELTA(lookupcache_hits), 
695                                     DELTA(lookupcache_misses)),
696                                 sperc2(DELTA(biocache_reads),
697                                     DELTA(read_bios)),
698                                 sperc2(DELTA(biocache_writes),
699                                     DELTA(write_bios)),
700                                 sperc1(DELTA(accesscache_hits),
701                                     DELTA(accesscache_misses)),
702                                 sperc2(DELTA(biocache_readdirs),
703                                     DELTA(readdir_bios))
704                             );
705                     }
706                     printf("\n");
707                 }
708                 if (serverOnly) {
709                     printf("%s %6d %6d %6d %6d %6d %6d %6d %6d",
710                         ((clientOnly && serverOnly) ? "Server:" : ""),
711                         DELTA(srvrpccnt[NFSV4OP_GETATTR]),
712                         DELTA(srvrpccnt[NFSV4OP_LOOKUP]),
713                         DELTA(srvrpccnt[NFSV4OP_READLINK]),
714                         DELTA(srvrpccnt[NFSV4OP_READ]),
715                         DELTA(srvrpccnt[NFSV4OP_WRITE]),
716                         DELTA(srvrpccnt[NFSV4OP_RENAME]),
717                         DELTA(srvrpccnt[NFSV4OP_ACCESS]),
718                         DELTA(srvrpccnt[NFSV4OP_READDIR]) +
719                         DELTA(srvrpccnt[NFSV4OP_READDIRPLUS]));
720                     printf("\n");
721                 }
722                 lastst = nfsstats;
723                 fflush(stdout);
724                 sleep(interval);
725         }
726         /*NOTREACHED*/
727 }