Print this page
6198 Let's EOL cachefs
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c
+++ new/usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /* LINTLIBRARY */
23 23 /* PROTOLIB1 */
24 24
25 25 /*
26 26 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
27 27 * Use is subject to license terms.
28 + * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
28 29 */
29 30
30 31 /*
31 32 * nfsstat: Network File System statistics
32 33 *
33 34 */
34 35
35 36 #include <stdio.h>
36 37 #include <stdlib.h>
37 38 #include <unistd.h>
38 39 #include <stdarg.h>
39 40 #include <string.h>
40 41 #include <errno.h>
41 42 #include <fcntl.h>
42 43 #include <kvm.h>
43 44 #include <kstat.h>
44 45 #include <sys/param.h>
45 46 #include <sys/types.h>
46 47 #include <sys/t_lock.h>
47 48 #include <sys/tiuser.h>
48 49 #include <sys/statvfs.h>
49 50 #include <sys/mntent.h>
50 51 #include <sys/mnttab.h>
51 52 #include <sys/sysmacros.h>
52 53 #include <sys/mkdev.h>
53 54 #include <rpc/types.h>
54 55 #include <rpc/xdr.h>
55 56 #include <rpc/auth.h>
56 57 #include <rpc/clnt.h>
57 58 #include <nfs/nfs.h>
58 59 #include <nfs/nfs_clnt.h>
59 60 #include <nfs/nfs_sec.h>
60 61 #include <inttypes.h>
61 62 #include <signal.h>
62 63 #include <time.h>
63 64 #include <sys/time.h>
64 65 #include <strings.h>
65 66 #include <ctype.h>
66 67 #include <locale.h>
67 68
68 69 #include "statcommon.h"
69 70
70 71 static kstat_ctl_t *kc = NULL; /* libkstat cookie */
71 72 static kstat_t *rpc_clts_client_kstat, *rpc_clts_server_kstat;
72 73 static kstat_t *rpc_cots_client_kstat, *rpc_cots_server_kstat;
73 74 static kstat_t *rpc_rdma_client_kstat, *rpc_rdma_server_kstat;
74 75 static kstat_t *nfs_client_kstat, *nfs_server_v2_kstat, *nfs_server_v3_kstat;
75 76 static kstat_t *nfs4_client_kstat, *nfs_server_v4_kstat;
76 77 static kstat_t *rfsproccnt_v2_kstat, *rfsproccnt_v3_kstat, *rfsproccnt_v4_kstat;
77 78 static kstat_t *rfsreqcnt_v2_kstat, *rfsreqcnt_v3_kstat, *rfsreqcnt_v4_kstat;
78 79 static kstat_t *aclproccnt_v2_kstat, *aclproccnt_v3_kstat;
79 80 static kstat_t *aclreqcnt_v2_kstat, *aclreqcnt_v3_kstat;
80 81 static kstat_t *ksum_kstat;
81 82
82 83 static void handle_sig(int);
83 84 static int getstats_rpc(void);
84 85 static int getstats_nfs(void);
85 86 static int getstats_rfsproc(int);
86 87 static int getstats_rfsreq(int);
87 88 static int getstats_aclproc(void);
88 89 static int getstats_aclreq(void);
89 90 static void putstats(void);
90 91 static void setup(void);
91 92 static void cr_print(int);
92 93 static void sr_print(int);
93 94 static void cn_print(int, int);
94 95 static void sn_print(int, int);
95 96 static void ca_print(int, int);
96 97 static void sa_print(int, int);
97 98 static void req_print(kstat_t *, kstat_t *, int, int, int);
98 99 static void req_print_v4(kstat_t *, kstat_t *, int, int);
99 100 static void stat_print(const char *, kstat_t *, kstat_t *, int, int);
100 101 static void nfsstat_kstat_sum(kstat_t *, kstat_t *, kstat_t *);
101 102 static void stats_timer(int);
102 103 static void safe_zalloc(void **, uint_t, int);
103 104 static int safe_strtoi(char const *, char *);
104 105
105 106
106 107 static void nfsstat_kstat_copy(kstat_t *, kstat_t *, int);
107 108 static kid_t safe_kstat_read(kstat_ctl_t *, kstat_t *, void *);
108 109 static kid_t safe_kstat_write(kstat_ctl_t *, kstat_t *, void *);
109 110
110 111 static void usage(void);
111 112 static void mi_print(void);
112 113 static int ignore(char *);
113 114 static int interval; /* interval between stats */
114 115 static int count; /* number of iterations the stat is printed */
115 116 #define MAX_COLUMNS 80
116 117 #define MAX_PATHS 50 /* max paths that can be taken by -m */
117 118
118 119 /*
119 120 * MI4_MIRRORMOUNT is canonically defined in nfs4_clnt.h, but we cannot
120 121 * include that file here. Same with MI4_REFERRAL.
121 122 */
122 123 #define MI4_MIRRORMOUNT 0x4000
123 124 #define MI4_REFERRAL 0x8000
124 125 #define NFS_V4 4
125 126
126 127 static int req_width(kstat_t *, int);
127 128 static int stat_width(kstat_t *, int);
128 129 static char *path [MAX_PATHS] = {NULL}; /* array to store the multiple paths */
129 130
130 131 /*
131 132 * Struct holds the previous kstat values so
132 133 * we can compute deltas when using the -i flag
133 134 */
134 135 typedef struct old_kstat
135 136 {
136 137 kstat_t kst;
137 138 int tot;
138 139 } old_kstat_t;
139 140
140 141 static old_kstat_t old_rpc_clts_client_kstat, old_rpc_clts_server_kstat;
141 142 static old_kstat_t old_rpc_cots_client_kstat, old_rpc_cots_server_kstat;
142 143 static old_kstat_t old_rpc_rdma_client_kstat, old_rpc_rdma_server_kstat;
143 144 static old_kstat_t old_nfs_client_kstat, old_nfs_server_v2_kstat;
144 145 static old_kstat_t old_nfs_server_v3_kstat, old_ksum_kstat;
145 146 static old_kstat_t old_nfs4_client_kstat, old_nfs_server_v4_kstat;
146 147 static old_kstat_t old_rfsproccnt_v2_kstat, old_rfsproccnt_v3_kstat;
147 148 static old_kstat_t old_rfsproccnt_v4_kstat, old_rfsreqcnt_v2_kstat;
148 149 static old_kstat_t old_rfsreqcnt_v3_kstat, old_rfsreqcnt_v4_kstat;
149 150 static old_kstat_t old_aclproccnt_v2_kstat, old_aclproccnt_v3_kstat;
150 151 static old_kstat_t old_aclreqcnt_v2_kstat, old_aclreqcnt_v3_kstat;
151 152
152 153 static uint_t timestamp_fmt = NODATE;
153 154
154 155 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
155 156 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */
156 157 #endif
157 158
158 159 int
159 160 main(int argc, char *argv[])
160 161 {
161 162 int c, go_forever, j;
162 163 int cflag = 0; /* client stats */
163 164 int sflag = 0; /* server stats */
164 165 int nflag = 0; /* nfs stats */
165 166 int rflag = 0; /* rpc stats */
166 167 int mflag = 0; /* mount table stats */
167 168 int aflag = 0; /* print acl statistics */
168 169 int vflag = 0; /* version specified, 0 specifies all */
169 170 int zflag = 0; /* zero stats after printing */
170 171 char *split_line = "*******************************************"
171 172 "*************************************";
172 173
173 174 interval = 0;
174 175 count = 0;
175 176 go_forever = 0;
176 177
177 178 (void) setlocale(LC_ALL, "");
178 179 (void) textdomain(TEXT_DOMAIN);
179 180
180 181 while ((c = getopt(argc, argv, "cnrsmzav:T:")) != EOF) {
181 182 switch (c) {
182 183 case 'c':
183 184 cflag++;
184 185 break;
185 186 case 'n':
186 187 nflag++;
187 188 break;
188 189 case 'r':
189 190 rflag++;
190 191 break;
191 192 case 's':
192 193 sflag++;
193 194 break;
194 195 case 'm':
195 196 mflag++;
196 197 break;
197 198 case 'z':
198 199 if (geteuid())
199 200 fail(0, "Must be root for z flag\n");
200 201 zflag++;
201 202 break;
202 203 case 'a':
203 204 aflag++;
204 205 break;
205 206 case 'v':
206 207 vflag = atoi(optarg);
207 208 if ((vflag < 2) || (vflag > 4))
208 209 fail(0, "Invalid version number\n");
209 210 break;
210 211 case 'T':
211 212 if (optarg) {
212 213 if (*optarg == 'u')
213 214 timestamp_fmt = UDATE;
214 215 else if (*optarg == 'd')
215 216 timestamp_fmt = DDATE;
216 217 else
217 218 usage();
218 219 } else {
219 220 usage();
220 221 }
221 222 break;
222 223 case '?':
223 224 default:
224 225 usage();
225 226 }
226 227 }
227 228
228 229 if (((argc - optind) > 0) && !mflag) {
229 230
230 231 interval = safe_strtoi(argv[optind], "invalid interval");
231 232 if (interval < 1)
232 233 fail(0, "invalid interval\n");
233 234 optind++;
234 235
235 236 if ((argc - optind) > 0) {
236 237 count = safe_strtoi(argv[optind], "invalid count");
237 238 if ((count <= 0) || (count == NULL))
238 239 fail(0, "invalid count\n");
239 240 }
240 241 optind++;
241 242
242 243 if ((argc - optind) > 0)
243 244 usage();
244 245
245 246 /*
246 247 * no count number was set, so we will loop infinitely
247 248 * at interval specified
248 249 */
249 250 if (!count)
250 251 go_forever = 1;
251 252 stats_timer(interval);
252 253 } else if (mflag) {
253 254
254 255 if (cflag || rflag || sflag || zflag || nflag || aflag || vflag)
255 256 fail(0,
256 257 "The -m flag may not be used with any other flags");
257 258
258 259 for (j = 0; (argc - optind > 0) && (j < (MAX_PATHS - 1)); j++) {
259 260 path[j] = argv[optind];
260 261 if (*path[j] != '/')
261 262 fail(0, "Please fully qualify your pathname "
262 263 "with a leading '/'");
263 264 optind++;
264 265 }
265 266 path[j] = NULL;
266 267 if (argc - optind > 0)
267 268 fprintf(stderr, "Only the first 50 paths "
268 269 "will be searched for\n");
269 270 }
270 271
271 272 setup();
272 273
273 274 do {
274 275 if (mflag) {
275 276 mi_print();
276 277 } else {
277 278 if (timestamp_fmt != NODATE)
278 279 print_timestamp(timestamp_fmt);
279 280
280 281 if (sflag &&
281 282 (rpc_clts_server_kstat == NULL ||
282 283 nfs_server_v4_kstat == NULL)) {
283 284 fprintf(stderr,
284 285 "nfsstat: kernel is not configured with "
285 286 "the server nfs and rpc code.\n");
286 287 }
287 288
288 289 /* if s and nothing else, all 3 prints are called */
289 290 if (sflag || (!sflag && !cflag)) {
290 291 if (rflag || (!rflag && !nflag && !aflag))
291 292 sr_print(zflag);
292 293 if (nflag || (!rflag && !nflag && !aflag))
293 294 sn_print(zflag, vflag);
294 295 if (aflag || (!rflag && !nflag && !aflag))
295 296 sa_print(zflag, vflag);
296 297 }
297 298 if (cflag &&
298 299 (rpc_clts_client_kstat == NULL ||
299 300 nfs_client_kstat == NULL)) {
300 301 fprintf(stderr,
301 302 "nfsstat: kernel is not configured with"
302 303 " the client nfs and rpc code.\n");
303 304 }
304 305 if (cflag || (!sflag && !cflag)) {
305 306 if (rflag || (!rflag && !nflag && !aflag))
306 307 cr_print(zflag);
307 308 if (nflag || (!rflag && !nflag && !aflag))
308 309 cn_print(zflag, vflag);
309 310 if (aflag || (!rflag && !nflag && !aflag))
310 311 ca_print(zflag, vflag);
311 312 }
312 313 }
313 314
314 315 if (zflag)
315 316 putstats();
316 317 if (interval)
317 318 printf("%s\n", split_line);
318 319
319 320 if (interval > 0)
320 321 (void) pause();
321 322 } while ((--count > 0) || go_forever);
322 323
323 324 kstat_close(kc);
324 325 free(ksum_kstat);
325 326 return (0);
326 327 }
327 328
328 329
329 330 static int
330 331 getstats_rpc(void)
331 332 {
332 333 int field_width = 0;
333 334
334 335 if (rpc_clts_client_kstat != NULL) {
335 336 safe_kstat_read(kc, rpc_clts_client_kstat, NULL);
336 337 field_width = stat_width(rpc_clts_client_kstat, field_width);
337 338 }
338 339
339 340 if (rpc_cots_client_kstat != NULL) {
340 341 safe_kstat_read(kc, rpc_cots_client_kstat, NULL);
341 342 field_width = stat_width(rpc_cots_client_kstat, field_width);
342 343 }
343 344
344 345 if (rpc_rdma_client_kstat != NULL) {
345 346 safe_kstat_read(kc, rpc_rdma_client_kstat, NULL);
346 347 field_width = stat_width(rpc_rdma_client_kstat, field_width);
347 348 }
348 349
349 350 if (rpc_clts_server_kstat != NULL) {
350 351 safe_kstat_read(kc, rpc_clts_server_kstat, NULL);
351 352 field_width = stat_width(rpc_clts_server_kstat, field_width);
352 353 }
353 354 if (rpc_cots_server_kstat != NULL) {
354 355 safe_kstat_read(kc, rpc_cots_server_kstat, NULL);
355 356 field_width = stat_width(rpc_cots_server_kstat, field_width);
356 357 }
357 358 if (rpc_rdma_server_kstat != NULL) {
358 359 safe_kstat_read(kc, rpc_rdma_server_kstat, NULL);
359 360 field_width = stat_width(rpc_rdma_server_kstat, field_width);
360 361 }
361 362 return (field_width);
362 363 }
363 364
364 365 static int
365 366 getstats_nfs(void)
366 367 {
367 368 int field_width = 0;
368 369
369 370 if (nfs_client_kstat != NULL) {
370 371 safe_kstat_read(kc, nfs_client_kstat, NULL);
371 372 field_width = stat_width(nfs_client_kstat, field_width);
372 373 }
373 374 if (nfs4_client_kstat != NULL) {
374 375 safe_kstat_read(kc, nfs4_client_kstat, NULL);
375 376 field_width = stat_width(nfs4_client_kstat, field_width);
376 377 }
377 378 if (nfs_server_v2_kstat != NULL) {
378 379 safe_kstat_read(kc, nfs_server_v2_kstat, NULL);
379 380 field_width = stat_width(nfs_server_v2_kstat, field_width);
380 381 }
381 382 if (nfs_server_v3_kstat != NULL) {
382 383 safe_kstat_read(kc, nfs_server_v3_kstat, NULL);
383 384 field_width = stat_width(nfs_server_v3_kstat, field_width);
384 385 }
385 386 if (nfs_server_v4_kstat != NULL) {
386 387 safe_kstat_read(kc, nfs_server_v4_kstat, NULL);
387 388 field_width = stat_width(nfs_server_v4_kstat, field_width);
388 389 }
389 390 return (field_width);
390 391 }
391 392
392 393 static int
393 394 getstats_rfsproc(int ver)
394 395 {
395 396 int field_width = 0;
396 397
397 398 if ((ver == 2) && (rfsproccnt_v2_kstat != NULL)) {
398 399 safe_kstat_read(kc, rfsproccnt_v2_kstat, NULL);
399 400 field_width = req_width(rfsproccnt_v2_kstat, field_width);
400 401 }
401 402 if ((ver == 3) && (rfsproccnt_v3_kstat != NULL)) {
402 403 safe_kstat_read(kc, rfsproccnt_v3_kstat, NULL);
403 404 field_width = req_width(rfsproccnt_v3_kstat, field_width);
404 405 }
405 406 if ((ver == 4) && (rfsproccnt_v4_kstat != NULL)) {
406 407 safe_kstat_read(kc, rfsproccnt_v4_kstat, NULL);
407 408 field_width = req_width(rfsproccnt_v4_kstat, field_width);
408 409 }
409 410 return (field_width);
410 411 }
411 412
412 413 static int
413 414 getstats_rfsreq(int ver)
414 415 {
415 416 int field_width = 0;
416 417 if ((ver == 2) && (rfsreqcnt_v2_kstat != NULL)) {
417 418 safe_kstat_read(kc, rfsreqcnt_v2_kstat, NULL);
418 419 field_width = req_width(rfsreqcnt_v2_kstat, field_width);
419 420 }
420 421 if ((ver == 3) && (rfsreqcnt_v3_kstat != NULL)) {
421 422 safe_kstat_read(kc, rfsreqcnt_v3_kstat, NULL);
422 423 field_width = req_width(rfsreqcnt_v3_kstat, field_width);
423 424 }
424 425 if ((ver == 4) && (rfsreqcnt_v4_kstat != NULL)) {
425 426 safe_kstat_read(kc, rfsreqcnt_v4_kstat, NULL);
426 427 field_width = req_width(rfsreqcnt_v4_kstat, field_width);
427 428 }
428 429 return (field_width);
429 430 }
430 431
431 432 static int
432 433 getstats_aclproc(void)
433 434 {
434 435 int field_width = 0;
435 436 if (aclproccnt_v2_kstat != NULL) {
436 437 safe_kstat_read(kc, aclproccnt_v2_kstat, NULL);
437 438 field_width = req_width(aclproccnt_v2_kstat, field_width);
438 439 }
439 440 if (aclproccnt_v3_kstat != NULL) {
440 441 safe_kstat_read(kc, aclproccnt_v3_kstat, NULL);
441 442 field_width = req_width(aclproccnt_v3_kstat, field_width);
442 443 }
443 444 return (field_width);
444 445 }
445 446
446 447 static int
447 448 getstats_aclreq(void)
448 449 {
449 450 int field_width = 0;
450 451 if (aclreqcnt_v2_kstat != NULL) {
451 452 safe_kstat_read(kc, aclreqcnt_v2_kstat, NULL);
452 453 field_width = req_width(aclreqcnt_v2_kstat, field_width);
453 454 }
454 455 if (aclreqcnt_v3_kstat != NULL) {
455 456 safe_kstat_read(kc, aclreqcnt_v3_kstat, NULL);
456 457 field_width = req_width(aclreqcnt_v3_kstat, field_width);
457 458 }
458 459 return (field_width);
459 460 }
460 461
461 462 static void
462 463 putstats(void)
463 464 {
464 465 if (rpc_clts_client_kstat != NULL)
465 466 safe_kstat_write(kc, rpc_clts_client_kstat, NULL);
466 467 if (rpc_cots_client_kstat != NULL)
467 468 safe_kstat_write(kc, rpc_cots_client_kstat, NULL);
468 469 if (rpc_rdma_client_kstat != NULL)
469 470 safe_kstat_write(kc, rpc_rdma_client_kstat, NULL);
470 471 if (nfs_client_kstat != NULL)
471 472 safe_kstat_write(kc, nfs_client_kstat, NULL);
472 473 if (nfs4_client_kstat != NULL)
473 474 safe_kstat_write(kc, nfs4_client_kstat, NULL);
474 475 if (rpc_clts_server_kstat != NULL)
475 476 safe_kstat_write(kc, rpc_clts_server_kstat, NULL);
476 477 if (rpc_cots_server_kstat != NULL)
477 478 safe_kstat_write(kc, rpc_cots_server_kstat, NULL);
478 479 if (rpc_rdma_server_kstat != NULL)
479 480 safe_kstat_write(kc, rpc_rdma_server_kstat, NULL);
480 481 if (nfs_server_v2_kstat != NULL)
481 482 safe_kstat_write(kc, nfs_server_v2_kstat, NULL);
482 483 if (nfs_server_v3_kstat != NULL)
483 484 safe_kstat_write(kc, nfs_server_v3_kstat, NULL);
484 485 if (nfs_server_v4_kstat != NULL)
485 486 safe_kstat_write(kc, nfs_server_v4_kstat, NULL);
486 487 if (rfsproccnt_v2_kstat != NULL)
487 488 safe_kstat_write(kc, rfsproccnt_v2_kstat, NULL);
488 489 if (rfsproccnt_v3_kstat != NULL)
489 490 safe_kstat_write(kc, rfsproccnt_v3_kstat, NULL);
490 491 if (rfsproccnt_v4_kstat != NULL)
491 492 safe_kstat_write(kc, rfsproccnt_v4_kstat, NULL);
492 493 if (rfsreqcnt_v2_kstat != NULL)
493 494 safe_kstat_write(kc, rfsreqcnt_v2_kstat, NULL);
494 495 if (rfsreqcnt_v3_kstat != NULL)
495 496 safe_kstat_write(kc, rfsreqcnt_v3_kstat, NULL);
496 497 if (rfsreqcnt_v4_kstat != NULL)
497 498 safe_kstat_write(kc, rfsreqcnt_v4_kstat, NULL);
498 499 if (aclproccnt_v2_kstat != NULL)
499 500 safe_kstat_write(kc, aclproccnt_v2_kstat, NULL);
500 501 if (aclproccnt_v3_kstat != NULL)
501 502 safe_kstat_write(kc, aclproccnt_v3_kstat, NULL);
502 503 if (aclreqcnt_v2_kstat != NULL)
503 504 safe_kstat_write(kc, aclreqcnt_v2_kstat, NULL);
504 505 if (aclreqcnt_v3_kstat != NULL)
505 506 safe_kstat_write(kc, aclreqcnt_v3_kstat, NULL);
506 507 }
507 508
508 509 static void
509 510 setup(void)
510 511 {
511 512 if ((kc = kstat_open()) == NULL)
512 513 fail(1, "kstat_open(): can't open /dev/kstat");
513 514
514 515 /* alloc space for our temporary kstat */
515 516 safe_zalloc((void **)&ksum_kstat, sizeof (kstat_t), 0);
516 517 rpc_clts_client_kstat = kstat_lookup(kc, "unix", 0, "rpc_clts_client");
517 518 rpc_clts_server_kstat = kstat_lookup(kc, "unix", 0, "rpc_clts_server");
518 519 rpc_cots_client_kstat = kstat_lookup(kc, "unix", 0, "rpc_cots_client");
519 520 rpc_cots_server_kstat = kstat_lookup(kc, "unix", 0, "rpc_cots_server");
520 521 rpc_rdma_client_kstat = kstat_lookup(kc, "unix", 0, "rpc_rdma_client");
521 522 rpc_rdma_server_kstat = kstat_lookup(kc, "unix", 0, "rpc_rdma_server");
522 523 nfs_client_kstat = kstat_lookup(kc, "nfs", 0, "nfs_client");
523 524 nfs4_client_kstat = kstat_lookup(kc, "nfs", 0, "nfs4_client");
524 525 nfs_server_v2_kstat = kstat_lookup(kc, "nfs", 2, "nfs_server");
525 526 nfs_server_v3_kstat = kstat_lookup(kc, "nfs", 3, "nfs_server");
526 527 nfs_server_v4_kstat = kstat_lookup(kc, "nfs", 4, "nfs_server");
527 528 rfsproccnt_v2_kstat = kstat_lookup(kc, "nfs", 0, "rfsproccnt_v2");
528 529 rfsproccnt_v3_kstat = kstat_lookup(kc, "nfs", 0, "rfsproccnt_v3");
529 530 rfsproccnt_v4_kstat = kstat_lookup(kc, "nfs", 0, "rfsproccnt_v4");
530 531 rfsreqcnt_v2_kstat = kstat_lookup(kc, "nfs", 0, "rfsreqcnt_v2");
531 532 rfsreqcnt_v3_kstat = kstat_lookup(kc, "nfs", 0, "rfsreqcnt_v3");
532 533 rfsreqcnt_v4_kstat = kstat_lookup(kc, "nfs", 0, "rfsreqcnt_v4");
533 534 aclproccnt_v2_kstat = kstat_lookup(kc, "nfs_acl", 0, "aclproccnt_v2");
534 535 aclproccnt_v3_kstat = kstat_lookup(kc, "nfs_acl", 0, "aclproccnt_v3");
535 536 aclreqcnt_v2_kstat = kstat_lookup(kc, "nfs_acl", 0, "aclreqcnt_v2");
536 537 aclreqcnt_v3_kstat = kstat_lookup(kc, "nfs_acl", 0, "aclreqcnt_v3");
537 538 if (rpc_clts_client_kstat == NULL && rpc_cots_server_kstat == NULL &&
538 539 rfsproccnt_v2_kstat == NULL && rfsreqcnt_v3_kstat == NULL)
539 540 fail(0, "Multiple kstat lookups failed."
540 541 "Your kernel module may not be loaded\n");
541 542 }
542 543
543 544 static int
544 545 req_width(kstat_t *req, int field_width)
545 546 {
546 547 int i, nreq, per, len;
547 548 char fixlen[128];
548 549 kstat_named_t *knp;
549 550 uint64_t tot;
550 551
551 552 tot = 0;
552 553 knp = KSTAT_NAMED_PTR(req);
553 554 for (i = 0; i < req->ks_ndata; i++)
554 555 tot += knp[i].value.ui64;
555 556
556 557 knp = kstat_data_lookup(req, "null");
557 558 nreq = req->ks_ndata - (knp - KSTAT_NAMED_PTR(req));
558 559
559 560 for (i = 0; i < nreq; i++) {
560 561 len = strlen(knp[i].name) + 1;
561 562 if (field_width < len)
562 563 field_width = len;
563 564 if (tot)
564 565 per = (int)(knp[i].value.ui64 * 100 / tot);
565 566 else
566 567 per = 0;
567 568 (void) sprintf(fixlen, "%" PRIu64 " %d%%",
568 569 knp[i].value.ui64, per);
569 570 len = strlen(fixlen) + 1;
570 571 if (field_width < len)
571 572 field_width = len;
572 573 }
573 574 return (field_width);
574 575 }
575 576
576 577 static int
577 578 stat_width(kstat_t *req, int field_width)
578 579 {
579 580 int i, nreq, len;
580 581 char fixlen[128];
581 582 kstat_named_t *knp;
582 583
583 584 knp = KSTAT_NAMED_PTR(req);
584 585 nreq = req->ks_ndata;
585 586
586 587 for (i = 0; i < nreq; i++) {
587 588 len = strlen(knp[i].name) + 1;
588 589 if (field_width < len)
589 590 field_width = len;
590 591 (void) sprintf(fixlen, "%" PRIu64, knp[i].value.ui64);
591 592 len = strlen(fixlen) + 1;
592 593 if (field_width < len)
593 594 field_width = len;
594 595 }
595 596 return (field_width);
596 597 }
597 598
598 599 static void
599 600 cr_print(int zflag)
600 601 {
601 602 int field_width;
602 603
603 604 field_width = getstats_rpc();
604 605 if (field_width == 0)
605 606 return;
606 607
607 608 stat_print("\nClient rpc:\nConnection oriented:",
608 609 rpc_cots_client_kstat,
609 610 &old_rpc_cots_client_kstat.kst, field_width, zflag);
610 611 stat_print("Connectionless:", rpc_clts_client_kstat,
611 612 &old_rpc_clts_client_kstat.kst, field_width, zflag);
612 613 stat_print("RDMA based:", rpc_rdma_client_kstat,
613 614 &old_rpc_rdma_client_kstat.kst, field_width, zflag);
614 615 }
615 616
616 617 static void
617 618 sr_print(int zflag)
618 619 {
619 620 int field_width;
620 621
621 622 field_width = getstats_rpc();
622 623 if (field_width == 0)
623 624 return;
624 625
625 626 stat_print("\nServer rpc:\nConnection oriented:", rpc_cots_server_kstat,
626 627 &old_rpc_cots_server_kstat.kst, field_width, zflag);
627 628 stat_print("Connectionless:", rpc_clts_server_kstat,
628 629 &old_rpc_clts_server_kstat.kst, field_width, zflag);
629 630 stat_print("RDMA based:", rpc_rdma_server_kstat,
630 631 &old_rpc_rdma_server_kstat.kst, field_width, zflag);
631 632 }
632 633
633 634 static void
634 635 cn_print(int zflag, int vflag)
635 636 {
636 637 int field_width;
637 638
638 639 field_width = getstats_nfs();
639 640 if (field_width == 0)
640 641 return;
641 642
642 643 if (vflag == 0) {
643 644 nfsstat_kstat_sum(nfs_client_kstat, nfs4_client_kstat,
644 645 ksum_kstat);
645 646 stat_print("\nClient nfs:", ksum_kstat, &old_ksum_kstat.kst,
646 647 field_width, zflag);
647 648 }
648 649
649 650 if (vflag == 2 || vflag == 3) {
650 651 stat_print("\nClient nfs:", nfs_client_kstat,
651 652 &old_nfs_client_kstat.kst, field_width, zflag);
652 653 }
653 654
654 655 if (vflag == 4) {
655 656 stat_print("\nClient nfs:", nfs4_client_kstat,
656 657 &old_nfs4_client_kstat.kst, field_width, zflag);
657 658 }
658 659
659 660 if (vflag == 2 || vflag == 0) {
660 661 field_width = getstats_rfsreq(2);
661 662 req_print(rfsreqcnt_v2_kstat, &old_rfsreqcnt_v2_kstat.kst,
662 663 2, field_width, zflag);
663 664 }
664 665
665 666 if (vflag == 3 || vflag == 0) {
666 667 field_width = getstats_rfsreq(3);
667 668 req_print(rfsreqcnt_v3_kstat, &old_rfsreqcnt_v3_kstat.kst, 3,
668 669 field_width, zflag);
669 670 }
670 671
671 672 if (vflag == 4 || vflag == 0) {
672 673 field_width = getstats_rfsreq(4);
673 674 req_print_v4(rfsreqcnt_v4_kstat, &old_rfsreqcnt_v4_kstat.kst,
674 675 field_width, zflag);
675 676 }
676 677 }
677 678
678 679 static void
679 680 sn_print(int zflag, int vflag)
680 681 {
681 682 int field_width;
682 683
683 684 field_width = getstats_nfs();
684 685 if (field_width == 0)
685 686 return;
686 687
687 688 if (vflag == 2 || vflag == 0) {
688 689 stat_print("\nServer NFSv2:", nfs_server_v2_kstat,
689 690 &old_nfs_server_v2_kstat.kst, field_width, zflag);
690 691 }
691 692
692 693 if (vflag == 3 || vflag == 0) {
693 694 stat_print("\nServer NFSv3:", nfs_server_v3_kstat,
694 695 &old_nfs_server_v3_kstat.kst, field_width, zflag);
695 696 }
696 697
697 698 if (vflag == 4 || vflag == 0) {
698 699 stat_print("\nServer NFSv4:", nfs_server_v4_kstat,
699 700 &old_nfs_server_v4_kstat.kst, field_width, zflag);
700 701 }
701 702
702 703 if (vflag == 2 || vflag == 0) {
703 704 field_width = getstats_rfsproc(2);
704 705 req_print(rfsproccnt_v2_kstat, &old_rfsproccnt_v2_kstat.kst,
705 706 2, field_width, zflag);
706 707 }
707 708
708 709 if (vflag == 3 || vflag == 0) {
709 710 field_width = getstats_rfsproc(3);
710 711 req_print(rfsproccnt_v3_kstat, &old_rfsproccnt_v3_kstat.kst,
711 712 3, field_width, zflag);
712 713 }
713 714
714 715 if (vflag == 4 || vflag == 0) {
715 716 field_width = getstats_rfsproc(4);
716 717 req_print_v4(rfsproccnt_v4_kstat, &old_rfsproccnt_v4_kstat.kst,
717 718 field_width, zflag);
718 719 }
719 720 }
720 721
721 722 static void
722 723 ca_print(int zflag, int vflag)
723 724 {
724 725 int field_width;
725 726
726 727 field_width = getstats_aclreq();
727 728 if (field_width == 0)
728 729 return;
729 730
730 731 printf("\nClient nfs_acl:\n");
731 732
732 733 if (vflag == 2 || vflag == 0) {
733 734 req_print(aclreqcnt_v2_kstat, &old_aclreqcnt_v2_kstat.kst, 2,
734 735 field_width, zflag);
735 736 }
736 737
737 738 if (vflag == 3 || vflag == 0) {
738 739 req_print(aclreqcnt_v3_kstat, &old_aclreqcnt_v3_kstat.kst,
739 740 3, field_width, zflag);
740 741 }
741 742 }
742 743
743 744 static void
744 745 sa_print(int zflag, int vflag)
745 746 {
746 747 int field_width;
747 748
748 749 field_width = getstats_aclproc();
749 750 if (field_width == 0)
750 751 return;
751 752
752 753 printf("\nServer nfs_acl:\n");
753 754
754 755 if (vflag == 2 || vflag == 0) {
755 756 req_print(aclproccnt_v2_kstat, &old_aclproccnt_v2_kstat.kst,
756 757 2, field_width, zflag);
757 758 }
758 759
759 760 if (vflag == 3 || vflag == 0) {
760 761 req_print(aclproccnt_v3_kstat, &old_aclproccnt_v3_kstat.kst,
761 762 3, field_width, zflag);
762 763 }
763 764 }
764 765
765 766 #define MIN(a, b) ((a) < (b) ? (a) : (b))
766 767
767 768 static void
768 769 req_print(kstat_t *req, kstat_t *req_old, int ver, int field_width,
769 770 int zflag)
770 771 {
771 772 int i, j, nreq, per, ncolumns;
772 773 uint64_t tot, old_tot;
773 774 char fixlen[128];
774 775 kstat_named_t *knp;
775 776 kstat_named_t *kptr;
776 777 kstat_named_t *knp_old;
777 778
778 779 if (req == NULL)
779 780 return;
780 781
781 782 if (field_width == 0)
782 783 return;
783 784
784 785 ncolumns = (MAX_COLUMNS -1)/field_width;
785 786 knp = kstat_data_lookup(req, "null");
786 787 knp_old = KSTAT_NAMED_PTR(req_old);
787 788
788 789 kptr = KSTAT_NAMED_PTR(req);
789 790 nreq = req->ks_ndata - (knp - KSTAT_NAMED_PTR(req));
790 791
791 792 tot = 0;
792 793 old_tot = 0;
793 794
794 795 if (knp_old == NULL) {
795 796 old_tot = 0;
796 797 }
797 798
798 799 for (i = 0; i < req->ks_ndata; i++)
799 800 tot += kptr[i].value.ui64;
800 801
801 802 if (interval && knp_old != NULL) {
802 803 for (i = 0; i < req_old->ks_ndata; i++)
803 804 old_tot += knp_old[i].value.ui64;
804 805 tot -= old_tot;
805 806 }
806 807
807 808 printf("Version %d: (%" PRIu64 " calls)\n", ver, tot);
808 809
809 810 for (i = 0; i < nreq; i += ncolumns) {
810 811 for (j = i; j < MIN(i + ncolumns, nreq); j++) {
811 812 printf("%-*s", field_width, knp[j].name);
812 813 }
813 814 printf("\n");
814 815 for (j = i; j < MIN(i + ncolumns, nreq); j++) {
815 816 if (tot && interval && knp_old != NULL)
816 817 per = (int)((knp[j].value.ui64 -
817 818 knp_old[j].value.ui64) * 100 / tot);
818 819 else if (tot)
819 820 per = (int)(knp[j].value.ui64 * 100 / tot);
820 821 else
821 822 per = 0;
822 823 (void) sprintf(fixlen, "%" PRIu64 " %d%% ",
823 824 ((interval && knp_old != NULL) ?
824 825 (knp[j].value.ui64 - knp_old[j].value.ui64)
825 826 : knp[j].value.ui64), per);
826 827 printf("%-*s", field_width, fixlen);
827 828 }
828 829 printf("\n");
829 830 }
830 831 if (zflag) {
831 832 for (i = 0; i < req->ks_ndata; i++)
832 833 knp[i].value.ui64 = 0;
833 834 }
834 835 if (knp_old != NULL)
835 836 nfsstat_kstat_copy(req, req_old, 1);
836 837 else
837 838 nfsstat_kstat_copy(req, req_old, 0);
838 839 }
839 840
840 841 /*
841 842 * Separate version of the req_print() to deal with V4 and its use of
842 843 * procedures and operations. It looks odd to have the counts for
843 844 * both of those lumped into the same set of statistics so this
844 845 * function (copy of req_print() does the separation and titles).
845 846 */
846 847
847 848 #define COUNT 2
848 849
849 850 static void
850 851 req_print_v4(kstat_t *req, kstat_t *req_old, int field_width, int zflag)
851 852 {
852 853 int i, j, nreq, per, ncolumns;
853 854 uint64_t tot, tot_ops, old_tot, old_tot_ops;
854 855 char fixlen[128];
855 856 kstat_named_t *kptr;
856 857 kstat_named_t *knp;
857 858 kstat_named_t *kptr_old;
858 859
859 860 if (req == NULL)
860 861 return;
861 862
862 863 if (field_width == 0)
863 864 return;
864 865
865 866 ncolumns = (MAX_COLUMNS)/field_width;
866 867 kptr = KSTAT_NAMED_PTR(req);
867 868 kptr_old = KSTAT_NAMED_PTR(req_old);
868 869
869 870 if (kptr_old == NULL) {
870 871 old_tot_ops = 0;
871 872 old_tot = 0;
872 873 } else {
873 874 old_tot = kptr_old[0].value.ui64 + kptr_old[1].value.ui64;
874 875 for (i = 2, old_tot_ops = 0; i < req_old->ks_ndata; i++)
875 876 old_tot_ops += kptr_old[i].value.ui64;
876 877 }
877 878
878 879 /* Count the number of operations sent */
879 880 for (i = 2, tot_ops = 0; i < req->ks_ndata; i++)
880 881 tot_ops += kptr[i].value.ui64;
881 882 /* For v4 NULL/COMPOUND are the only procedures */
882 883 tot = kptr[0].value.ui64 + kptr[1].value.ui64;
883 884
884 885 if (interval) {
885 886 tot -= old_tot;
886 887 tot_ops -= old_tot_ops;
887 888 }
888 889
889 890 printf("Version 4: (%" PRIu64 " calls)\n", tot);
890 891
891 892 knp = kstat_data_lookup(req, "null");
892 893 nreq = req->ks_ndata - (knp - KSTAT_NAMED_PTR(req));
893 894
894 895 for (i = 0; i < COUNT; i += ncolumns) {
895 896 for (j = i; j < MIN(i + ncolumns, 2); j++) {
896 897 printf("%-*s", field_width, knp[j].name);
897 898 }
898 899 printf("\n");
899 900 for (j = i; j < MIN(i + ncolumns, 2); j++) {
900 901 if (tot && interval && kptr_old != NULL)
901 902 per = (int)((knp[j].value.ui64 -
902 903 kptr_old[j].value.ui64) * 100 / tot);
903 904 else if (tot)
904 905 per = (int)(knp[j].value.ui64 * 100 / tot);
905 906 else
906 907 per = 0;
907 908 (void) sprintf(fixlen, "%" PRIu64 " %d%% ",
908 909 ((interval && kptr_old != NULL) ?
909 910 (knp[j].value.ui64 - kptr_old[j].value.ui64)
910 911 : knp[j].value.ui64), per);
911 912 printf("%-*s", field_width, fixlen);
912 913 }
913 914 printf("\n");
914 915 }
915 916
916 917 printf("Version 4: (%" PRIu64 " operations)\n", tot_ops);
917 918 for (i = 2; i < nreq; i += ncolumns) {
918 919 for (j = i; j < MIN(i + ncolumns, nreq); j++) {
919 920 printf("%-*s", field_width, knp[j].name);
920 921 }
921 922 printf("\n");
922 923 for (j = i; j < MIN(i + ncolumns, nreq); j++) {
923 924 if (tot_ops && interval && kptr_old != NULL)
924 925 per = (int)((knp[j].value.ui64 -
925 926 kptr_old[j].value.ui64) * 100 / tot_ops);
926 927 else if (tot_ops)
927 928 per = (int)(knp[j].value.ui64 * 100 / tot_ops);
928 929 else
929 930 per = 0;
930 931 (void) sprintf(fixlen, "%" PRIu64 " %d%% ",
931 932 ((interval && kptr_old != NULL) ?
932 933 (knp[j].value.ui64 - kptr_old[j].value.ui64)
933 934 : knp[j].value.ui64), per);
934 935 printf("%-*s", field_width, fixlen);
935 936 }
936 937 printf("\n");
937 938 }
938 939 if (zflag) {
939 940 for (i = 0; i < req->ks_ndata; i++)
940 941 kptr[i].value.ui64 = 0;
941 942 }
942 943 if (kptr_old != NULL)
943 944 nfsstat_kstat_copy(req, req_old, 1);
944 945 else
945 946 nfsstat_kstat_copy(req, req_old, 0);
946 947 }
947 948
948 949 static void
949 950 stat_print(const char *title_string, kstat_t *req, kstat_t *req_old,
950 951 int field_width, int zflag)
951 952 {
952 953 int i, j, nreq, ncolumns;
953 954 char fixlen[128];
954 955 kstat_named_t *knp;
955 956 kstat_named_t *knp_old;
956 957
957 958 if (req == NULL)
958 959 return;
959 960
960 961 if (field_width == 0)
961 962 return;
962 963
963 964 printf("%s\n", title_string);
964 965 ncolumns = (MAX_COLUMNS -1)/field_width;
965 966
966 967 /* MEANS knp = (kstat_named_t *)req->ks_data */
967 968 knp = KSTAT_NAMED_PTR(req);
968 969 nreq = req->ks_ndata;
969 970 knp_old = KSTAT_NAMED_PTR(req_old);
970 971
971 972 for (i = 0; i < nreq; i += ncolumns) {
972 973 /* prints out the titles of the columns */
973 974 for (j = i; j < MIN(i + ncolumns, nreq); j++) {
974 975 printf("%-*s", field_width, knp[j].name);
975 976 }
976 977 printf("\n");
977 978 /* prints out the stat numbers */
978 979 for (j = i; j < MIN(i + ncolumns, nreq); j++) {
979 980 (void) sprintf(fixlen, "%" PRIu64 " ",
980 981 (interval && knp_old != NULL) ?
981 982 (knp[j].value.ui64 - knp_old[j].value.ui64)
982 983 : knp[j].value.ui64);
983 984 printf("%-*s", field_width, fixlen);
984 985 }
985 986 printf("\n");
986 987
987 988 }
988 989 if (zflag) {
989 990 for (i = 0; i < req->ks_ndata; i++)
990 991 knp[i].value.ui64 = 0;
991 992 }
992 993
993 994 if (knp_old != NULL)
994 995 nfsstat_kstat_copy(req, req_old, 1);
995 996 else
996 997 nfsstat_kstat_copy(req, req_old, 0);
997 998 }
998 999
999 1000 static void
1000 1001 nfsstat_kstat_sum(kstat_t *kstat1, kstat_t *kstat2, kstat_t *sum)
1001 1002 {
1002 1003 int i;
1003 1004 kstat_named_t *knp1, *knp2, *knpsum;
1004 1005 if (kstat1 == NULL || kstat2 == NULL)
1005 1006 return;
1006 1007
1007 1008 knp1 = KSTAT_NAMED_PTR(kstat1);
1008 1009 knp2 = KSTAT_NAMED_PTR(kstat2);
1009 1010 if (sum->ks_data == NULL)
1010 1011 nfsstat_kstat_copy(kstat1, sum, 0);
1011 1012 knpsum = KSTAT_NAMED_PTR(sum);
1012 1013
1013 1014 for (i = 0; i < (kstat1->ks_ndata); i++)
1014 1015 knpsum[i].value.ui64 = knp1[i].value.ui64 + knp2[i].value.ui64;
1015 1016 }
1016 1017
1017 1018 /*
1018 1019 * my_dir and my_path could be pointers
1019 1020 */
1020 1021 struct myrec {
1021 1022 ulong_t my_fsid;
1022 1023 char my_dir[MAXPATHLEN];
1023 1024 char *my_path;
1024 1025 char *ig_path;
1025 1026 struct myrec *next;
1026 1027 };
1027 1028
1028 1029 /*
1029 1030 * Print the mount table info
1030 1031 */
1031 1032 static void
1032 1033 mi_print(void)
1033 1034 {
1034 1035 FILE *mt;
1035 1036 struct extmnttab m;
1036 1037 struct myrec *list, *mrp, *pmrp;
1037 1038 char *flavor;
1038 1039 int ignored = 0;
1039 1040 seconfig_t nfs_sec;
1040 1041 kstat_t *ksp;
1041 1042 struct mntinfo_kstat mik;
1042 1043 int transport_flag = 0;
1043 1044 int path_count;
1044 1045 int found;
1045 1046 char *timer_name[] = {
1046 1047 "Lookups",
1047 1048 "Reads",
1048 1049 "Writes",
1049 1050 "All"
1050 1051 };
1051 1052
1052 1053 mt = fopen(MNTTAB, "r");
1053 1054 if (mt == NULL) {
1054 1055 perror(MNTTAB);
1055 1056 exit(0);
1056 1057 }
1057 1058
1058 1059 list = NULL;
1059 1060 resetmnttab(mt);
1060 1061
1061 1062 while (getextmntent(mt, &m, sizeof (struct extmnttab)) == 0) {
1062 1063 /* ignore non "nfs" and save the "ignore" entries */
1063 1064 if (strcmp(m.mnt_fstype, MNTTYPE_NFS) != 0)
1064 1065 continue;
1065 1066 /*
1066 1067 * Check to see here if user gave a path(s) to
1067 1068 * only show the mount point they wanted
1068 1069 * Iterate through the list of paths the user gave and see
1069 1070 * if any of them match our current nfs mount
1070 1071 */
1071 1072 if (path[0] != NULL) {
1072 1073 found = 0;
1073 1074 for (path_count = 0; path[path_count] != NULL;
1074 1075 path_count++) {
1075 1076 if (strcmp(path[path_count], m.mnt_mountp)
1076 1077 == 0) {
1077 1078 found = 1;
1078 1079 break;
1079 1080 }
1080 1081 }
1081 1082 if (!found)
1082 1083 continue;
1083 1084 }
1084 1085
1085 1086 if ((mrp = malloc(sizeof (struct myrec))) == 0) {
1086 1087 fprintf(stderr, "nfsstat: not enough memory\n");
1087 1088 exit(1);
1088 1089 }
1089 1090 mrp->my_fsid = makedev(m.mnt_major, m.mnt_minor);
1090 1091 if (ignore(m.mnt_mntopts)) {
1091 1092 /*
1092 1093 * ignored entries cannot be ignored for this
1093 1094 * option. We have to display the info for this
1094 1095 * nfs mount. The ignore is an indication
1095 1096 * that the actual mount point is different and
1096 1097 * something is in between the nfs mount.
1097 1098 * So save the mount point now
1098 1099 */
1099 1100 if ((mrp->ig_path = malloc(
1100 1101 strlen(m.mnt_mountp) + 1)) == 0) {
1101 1102 fprintf(stderr, "nfsstat: not enough memory\n");
1102 1103 exit(1);
1103 1104 }
1104 1105 (void) strcpy(mrp->ig_path, m.mnt_mountp);
1105 1106 ignored++;
1106 1107 } else {
1107 1108 mrp->ig_path = 0;
↓ open down ↓ |
1070 lines elided |
↑ open up ↑ |
1108 1109 (void) strcpy(mrp->my_dir, m.mnt_mountp);
1109 1110 }
1110 1111 if ((mrp->my_path = strdup(m.mnt_special)) == NULL) {
1111 1112 fprintf(stderr, "nfsstat: not enough memory\n");
1112 1113 exit(1);
1113 1114 }
1114 1115 mrp->next = list;
1115 1116 list = mrp;
1116 1117 }
1117 1118
1118 - /*
1119 - * If something got ignored, go to the beginning of the mnttab
1120 - * and look for the cachefs entries since they are the one
1121 - * causing this. The mount point saved for the ignored entries
1122 - * is matched against the special to get the actual mount point.
1123 - * We are interested in the acutal mount point so that the output
1124 - * look nice too.
1125 - */
1126 - if (ignored) {
1127 - rewind(mt);
1128 - resetmnttab(mt);
1129 - while (getextmntent(mt, &m, sizeof (struct extmnttab)) == 0) {
1119 + (void) fclose(mt);
1130 1120
1131 - /* ignore non "cachefs" */
1132 - if (strcmp(m.mnt_fstype, MNTTYPE_CACHEFS) != 0)
1133 - continue;
1134 -
1135 - for (mrp = list; mrp; mrp = mrp->next) {
1136 - if (mrp->ig_path == 0)
1137 - continue;
1138 - if (strcmp(mrp->ig_path, m.mnt_special) == 0) {
1139 - mrp->ig_path = 0;
1140 - (void) strcpy(mrp->my_dir,
1141 - m.mnt_mountp);
1142 - }
1143 - }
1144 - }
1121 + if (ignored) {
1145 1122 /*
1146 1123 * Now ignored entries which do not have
1147 1124 * the my_dir initialized are really ignored; This never
1148 1125 * happens unless the mnttab is corrupted.
1149 1126 */
1150 1127 for (pmrp = 0, mrp = list; mrp; mrp = mrp->next) {
1151 1128 if (mrp->ig_path == 0)
1152 1129 pmrp = mrp;
1153 1130 else if (pmrp)
1154 1131 pmrp->next = mrp->next;
1155 1132 else
1156 1133 list = mrp->next;
1157 1134 }
1158 1135 }
1159 1136
1160 - (void) fclose(mt);
1161 -
1162 -
1163 1137 for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
1164 1138 int i;
1165 1139
1166 1140 if (ksp->ks_type != KSTAT_TYPE_RAW)
1167 1141 continue;
1168 1142 if (strcmp(ksp->ks_module, "nfs") != 0)
1169 1143 continue;
1170 1144 if (strcmp(ksp->ks_name, "mntinfo") != 0)
1171 1145 continue;
1172 1146
1173 1147 for (mrp = list; mrp; mrp = mrp->next) {
1174 1148 if ((mrp->my_fsid & MAXMIN) == ksp->ks_instance)
1175 1149 break;
1176 1150 }
1177 1151 if (mrp == 0)
1178 1152 continue;
1179 1153
1180 1154 if (safe_kstat_read(kc, ksp, &mik) == -1)
1181 1155 continue;
1182 1156
1183 1157 printf("%s from %s\n", mrp->my_dir, mrp->my_path);
1184 1158
1185 1159 /*
1186 1160 * for printing rdma transport and provider string.
1187 1161 * This way we avoid modifying the kernel mntinfo_kstat
1188 1162 * struct for protofmly.
1189 1163 */
1190 1164 if (strcmp(mik.mik_proto, "ibtf") == 0) {
1191 1165 printf(" Flags: vers=%u,proto=rdma",
1192 1166 mik.mik_vers);
1193 1167 transport_flag = 1;
1194 1168 } else {
1195 1169 printf(" Flags: vers=%u,proto=%s",
1196 1170 mik.mik_vers, mik.mik_proto);
1197 1171 transport_flag = 0;
1198 1172 }
1199 1173
1200 1174 /*
1201 1175 * get the secmode name from /etc/nfssec.conf.
1202 1176 */
1203 1177 if (!nfs_getseconfig_bynumber(mik.mik_secmod, &nfs_sec)) {
1204 1178 flavor = nfs_sec.sc_name;
1205 1179 } else
1206 1180 flavor = NULL;
1207 1181
1208 1182 if (flavor != NULL)
1209 1183 printf(",sec=%s", flavor);
1210 1184 else
1211 1185 printf(",sec#=%d", mik.mik_secmod);
1212 1186
1213 1187 printf(",%s", (mik.mik_flags & MI_HARD) ? "hard" : "soft");
1214 1188 if (mik.mik_flags & MI_PRINTED)
1215 1189 printf(",printed");
1216 1190 printf(",%s", (mik.mik_flags & MI_INT) ? "intr" : "nointr");
1217 1191 if (mik.mik_flags & MI_DOWN)
1218 1192 printf(",down");
1219 1193 if (mik.mik_flags & MI_NOAC)
1220 1194 printf(",noac");
1221 1195 if (mik.mik_flags & MI_NOCTO)
1222 1196 printf(",nocto");
1223 1197 if (mik.mik_flags & MI_DYNAMIC)
1224 1198 printf(",dynamic");
1225 1199 if (mik.mik_flags & MI_LLOCK)
1226 1200 printf(",llock");
1227 1201 if (mik.mik_flags & MI_GRPID)
1228 1202 printf(",grpid");
1229 1203 if (mik.mik_flags & MI_RPCTIMESYNC)
1230 1204 printf(",rpctimesync");
1231 1205 if (mik.mik_flags & MI_LINK)
1232 1206 printf(",link");
1233 1207 if (mik.mik_flags & MI_SYMLINK)
1234 1208 printf(",symlink");
1235 1209 if (mik.mik_vers < NFS_V4 && mik.mik_flags & MI_READDIRONLY)
1236 1210 printf(",readdironly");
1237 1211 if (mik.mik_flags & MI_ACL)
1238 1212 printf(",acl");
1239 1213 if (mik.mik_flags & MI_DIRECTIO)
1240 1214 printf(",forcedirectio");
1241 1215
1242 1216 if (mik.mik_vers >= NFS_V4) {
1243 1217 if (mik.mik_flags & MI4_MIRRORMOUNT)
1244 1218 printf(",mirrormount");
1245 1219 if (mik.mik_flags & MI4_REFERRAL)
1246 1220 printf(",referral");
1247 1221 }
1248 1222
1249 1223 printf(",rsize=%d,wsize=%d,retrans=%d,timeo=%d",
1250 1224 mik.mik_curread, mik.mik_curwrite, mik.mik_retrans,
1251 1225 mik.mik_timeo);
1252 1226 printf("\n");
1253 1227 printf(" Attr cache: acregmin=%d,acregmax=%d"
1254 1228 ",acdirmin=%d,acdirmax=%d\n", mik.mik_acregmin,
1255 1229 mik.mik_acregmax, mik.mik_acdirmin, mik.mik_acdirmax);
1256 1230
1257 1231 if (transport_flag) {
1258 1232 printf(" Transport: proto=rdma, plugin=%s\n",
1259 1233 mik.mik_proto);
1260 1234 }
1261 1235
1262 1236 #define srtt_to_ms(x) x, (x * 2 + x / 2)
1263 1237 #define dev_to_ms(x) x, (x * 5)
1264 1238
1265 1239 for (i = 0; i < NFS_CALLTYPES + 1; i++) {
1266 1240 int j;
1267 1241
1268 1242 j = (i == NFS_CALLTYPES ? i - 1 : i);
1269 1243 if (mik.mik_timers[j].srtt ||
1270 1244 mik.mik_timers[j].rtxcur) {
1271 1245 printf(" %s: srtt=%d (%dms), "
1272 1246 "dev=%d (%dms), cur=%u (%ums)\n",
1273 1247 timer_name[i],
1274 1248 srtt_to_ms(mik.mik_timers[i].srtt),
1275 1249 dev_to_ms(mik.mik_timers[i].deviate),
1276 1250 mik.mik_timers[i].rtxcur,
1277 1251 mik.mik_timers[i].rtxcur * 20);
1278 1252 }
1279 1253 }
1280 1254
1281 1255 if (strchr(mrp->my_path, ','))
1282 1256 printf(
1283 1257 " Failover: noresponse=%d,failover=%d,"
1284 1258 "remap=%d,currserver=%s\n",
1285 1259 mik.mik_noresponse, mik.mik_failover,
1286 1260 mik.mik_remap, mik.mik_curserver);
1287 1261 printf("\n");
1288 1262 }
1289 1263 }
1290 1264
1291 1265 static char *mntopts[] = { MNTOPT_IGNORE, MNTOPT_DEV, NULL };
1292 1266 #define IGNORE 0
1293 1267 #define DEV 1
1294 1268
1295 1269 /*
1296 1270 * Return 1 if "ignore" appears in the options string
1297 1271 */
1298 1272 static int
1299 1273 ignore(char *opts)
1300 1274 {
1301 1275 char *value;
1302 1276 char *s;
1303 1277
1304 1278 if (opts == NULL)
1305 1279 return (0);
1306 1280 s = strdup(opts);
1307 1281 if (s == NULL)
1308 1282 return (0);
1309 1283 opts = s;
1310 1284
1311 1285 while (*opts != '\0') {
1312 1286 if (getsubopt(&opts, mntopts, &value) == IGNORE) {
1313 1287 free(s);
1314 1288 return (1);
1315 1289 }
1316 1290 }
1317 1291
1318 1292 free(s);
1319 1293 return (0);
1320 1294 }
1321 1295
1322 1296 void
1323 1297 usage(void)
1324 1298 {
1325 1299 fprintf(stderr, "Usage: nfsstat [-cnrsza [-v version] "
1326 1300 "[-T d|u] [interval [count]]\n");
1327 1301 fprintf(stderr, "Usage: nfsstat -m [pathname..]\n");
1328 1302 exit(1);
1329 1303 }
1330 1304
1331 1305 void
1332 1306 fail(int do_perror, char *message, ...)
1333 1307 {
1334 1308 va_list args;
1335 1309
1336 1310 va_start(args, message);
1337 1311 fprintf(stderr, "nfsstat: ");
1338 1312 vfprintf(stderr, message, args);
1339 1313 va_end(args);
1340 1314 if (do_perror)
1341 1315 fprintf(stderr, ": %s", strerror(errno));
1342 1316 fprintf(stderr, "\n");
1343 1317 exit(1);
1344 1318 }
1345 1319
1346 1320 kid_t
1347 1321 safe_kstat_read(kstat_ctl_t *kc, kstat_t *ksp, void *data)
1348 1322 {
1349 1323 kid_t kstat_chain_id = kstat_read(kc, ksp, data);
1350 1324
1351 1325 if (kstat_chain_id == -1)
1352 1326 fail(1, "kstat_read(%x, '%s') failed", kc, ksp->ks_name);
1353 1327 return (kstat_chain_id);
1354 1328 }
1355 1329
1356 1330 kid_t
1357 1331 safe_kstat_write(kstat_ctl_t *kc, kstat_t *ksp, void *data)
1358 1332 {
1359 1333 kid_t kstat_chain_id = 0;
1360 1334
1361 1335 if (ksp->ks_data != NULL) {
1362 1336 kstat_chain_id = kstat_write(kc, ksp, data);
1363 1337
1364 1338 if (kstat_chain_id == -1)
1365 1339 fail(1, "kstat_write(%x, '%s') failed", kc,
1366 1340 ksp->ks_name);
1367 1341 }
1368 1342 return (kstat_chain_id);
1369 1343 }
1370 1344
1371 1345 void
1372 1346 stats_timer(int interval)
1373 1347 {
1374 1348 timer_t t_id;
1375 1349 itimerspec_t time_struct;
1376 1350 struct sigevent sig_struct;
1377 1351 struct sigaction act;
1378 1352
1379 1353 bzero(&sig_struct, sizeof (struct sigevent));
1380 1354 bzero(&act, sizeof (struct sigaction));
1381 1355
1382 1356 /* Create timer */
1383 1357 sig_struct.sigev_notify = SIGEV_SIGNAL;
1384 1358 sig_struct.sigev_signo = SIGUSR1;
1385 1359 sig_struct.sigev_value.sival_int = 0;
1386 1360
1387 1361 if (timer_create(CLOCK_REALTIME, &sig_struct, &t_id) != 0) {
1388 1362 fail(1, "Timer creation failed");
1389 1363 }
1390 1364
1391 1365 act.sa_handler = handle_sig;
1392 1366
1393 1367 if (sigaction(SIGUSR1, &act, NULL) != 0) {
1394 1368 fail(1, "Could not set up signal handler");
1395 1369 }
1396 1370
1397 1371 time_struct.it_value.tv_sec = interval;
1398 1372 time_struct.it_value.tv_nsec = 0;
1399 1373 time_struct.it_interval.tv_sec = interval;
1400 1374 time_struct.it_interval.tv_nsec = 0;
1401 1375
1402 1376 /* Arm timer */
1403 1377 if ((timer_settime(t_id, 0, &time_struct, NULL)) != 0) {
1404 1378 fail(1, "Setting timer failed");
1405 1379 }
1406 1380 }
1407 1381
1408 1382 void
1409 1383 handle_sig(int x)
1410 1384 {
1411 1385 }
1412 1386
1413 1387 static void
1414 1388 nfsstat_kstat_copy(kstat_t *src, kstat_t *dst, int fr)
1415 1389 {
1416 1390
1417 1391 if (fr)
1418 1392 free(dst->ks_data);
1419 1393
1420 1394 *dst = *src;
1421 1395
1422 1396 if (src->ks_data != NULL) {
1423 1397 safe_zalloc(&dst->ks_data, src->ks_data_size, 0);
1424 1398 (void) memcpy(dst->ks_data, src->ks_data, src->ks_data_size);
1425 1399 } else {
1426 1400 dst->ks_data = NULL;
1427 1401 dst->ks_data_size = 0;
1428 1402 }
1429 1403 }
1430 1404
1431 1405 /*
1432 1406 * "Safe" allocators - if we return we're guaranteed to have the desired space
1433 1407 * allocated and zero-filled. We exit via fail if we can't get the space.
1434 1408 */
1435 1409 void
1436 1410 safe_zalloc(void **ptr, uint_t size, int free_first)
1437 1411 {
1438 1412 if (ptr == NULL)
1439 1413 fail(1, "invalid pointer");
1440 1414 if (free_first && *ptr != NULL)
1441 1415 free(*ptr);
1442 1416 if ((*ptr = (void *)malloc(size)) == NULL)
1443 1417 fail(1, "malloc failed");
1444 1418 (void) memset(*ptr, 0, size);
1445 1419 }
1446 1420
1447 1421 static int
1448 1422 safe_strtoi(char const *val, char *errmsg)
1449 1423 {
1450 1424 char *end;
1451 1425 long tmp;
1452 1426 errno = 0;
1453 1427 tmp = strtol(val, &end, 10);
1454 1428 if (*end != '\0' || errno)
1455 1429 fail(0, "%s %s", errmsg, val);
1456 1430 return ((int)tmp);
1457 1431 }
↓ open down ↓ |
285 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX