Print this page
10113 fmd_adm_xprt_f should return void
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/fm/fmstat/common/fmstat.c
+++ new/usr/src/cmd/fm/fmstat/common/fmstat.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
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 +/*
28 + * Copyright (c) 2018, Joyent, Inc.
29 + */
30 +
27 31 #include <fm/fmd_adm.h>
28 32
29 33 #include <strings.h>
30 34 #include <limits.h>
31 35 #include <stdlib.h>
32 36 #include <stdarg.h>
33 37 #include <stdio.h>
34 38 #include <errno.h>
35 39 #include <poll.h>
36 40 #include <locale.h>
37 41
38 42 #include "statcommon.h"
39 43
40 44 #define FMSTAT_EXIT_SUCCESS 0
41 45 #define FMSTAT_EXIT_ERROR 1
42 46 #define FMSTAT_EXIT_USAGE 2
43 47
44 48 static const struct stats {
45 49 fmd_stat_t module;
46 50 fmd_stat_t authority;
47 51 fmd_stat_t state;
48 52 fmd_stat_t loadtime;
49 53 fmd_stat_t snaptime;
50 54 fmd_stat_t received;
51 55 fmd_stat_t discarded;
52 56 fmd_stat_t retried;
53 57 fmd_stat_t replayed;
54 58 fmd_stat_t lost;
55 59 fmd_stat_t dispatched;
56 60 fmd_stat_t dequeued;
57 61 fmd_stat_t prdequeued;
58 62 fmd_stat_t accepted;
59 63 fmd_stat_t memtotal;
60 64 fmd_stat_t buftotal;
61 65 fmd_stat_t caseopen;
62 66 fmd_stat_t casesolved;
63 67 fmd_stat_t wcnt;
64 68 fmd_stat_t wtime;
65 69 fmd_stat_t wlentime;
66 70 fmd_stat_t wlastupdate;
67 71 fmd_stat_t dtime;
68 72 fmd_stat_t dlastupdate;
69 73 } stats_template = {
70 74 { "module", FMD_TYPE_STRING },
71 75 { "authority", FMD_TYPE_STRING },
72 76 { "state", FMD_TYPE_STRING },
73 77 { "loadtime", FMD_TYPE_TIME },
74 78 { "snaptime", FMD_TYPE_TIME },
75 79 { "received", FMD_TYPE_UINT64 },
76 80 { "discarded", FMD_TYPE_UINT64 },
77 81 { "retried", FMD_TYPE_UINT64 },
78 82 { "replayed", FMD_TYPE_UINT64 },
79 83 { "lost", FMD_TYPE_UINT64 },
80 84 { "dispatched", FMD_TYPE_UINT64 },
81 85 { "dequeued", FMD_TYPE_UINT64 },
82 86 { "prdequeued", FMD_TYPE_UINT64 },
83 87 { "accepted", FMD_TYPE_UINT64 },
84 88 { "memtotal", FMD_TYPE_SIZE },
85 89 { "buftotal", FMD_TYPE_SIZE },
86 90 { "caseopen", FMD_TYPE_UINT64 },
87 91 { "casesolved", FMD_TYPE_UINT64 },
88 92 { "wcnt", FMD_TYPE_UINT32 },
89 93 { "wtime", FMD_TYPE_TIME },
90 94 { "wlentime", FMD_TYPE_TIME },
91 95 { "wlastupdate", FMD_TYPE_TIME },
92 96 { "dtime", FMD_TYPE_TIME },
93 97 { "dlastupdate", FMD_TYPE_TIME },
94 98 };
95 99
96 100 static const char *g_pname;
97 101 static fmd_adm_t *g_adm;
98 102
99 103 static struct modstats {
100 104 char *m_name;
101 105 struct modstats *m_next;
102 106 struct stats m_stbuf[2];
103 107 int m_stidx;
104 108 int m_id;
105 109 struct stats *m_old;
106 110 struct stats *m_new;
107 111 double m_wait;
108 112 double m_svc;
109 113 double m_pct_b;
110 114 double m_pct_w;
111 115 } *g_mods;
112 116
113 117 static uint_t timestamp_fmt = NODATE;
114 118
115 119 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
116 120 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */
117 121 #endif
118 122
119 123 static void
120 124 vwarn(const char *format, va_list ap)
121 125 {
122 126 int err = errno;
123 127
124 128 (void) fprintf(stderr, "%s: ", g_pname);
125 129
126 130 if (format != NULL)
127 131 (void) vfprintf(stderr, format, ap);
128 132
129 133 errno = err; /* restore errno for fmd_adm_errmsg() */
130 134
131 135 if (format == NULL)
132 136 (void) fprintf(stderr, "%s\n", fmd_adm_errmsg(g_adm));
133 137 else if (strchr(format, '\n') == NULL)
134 138 (void) fprintf(stderr, ": %s\n", fmd_adm_errmsg(g_adm));
135 139 }
136 140
137 141 /*PRINTFLIKE1*/
138 142 void
139 143 warn(const char *format, ...)
140 144 {
141 145 va_list ap;
142 146
143 147 va_start(ap, format);
144 148 vwarn(format, ap);
145 149 va_end(ap);
146 150 }
147 151
148 152 /*PRINTFLIKE1*/
149 153 void
150 154 die(const char *format, ...)
151 155 {
152 156 va_list ap;
153 157
154 158 va_start(ap, format);
155 159 vwarn(format, ap);
156 160 va_end(ap);
157 161
158 162 fmd_adm_close(g_adm);
159 163 exit(FMSTAT_EXIT_ERROR);
160 164 }
161 165
162 166 static char *
163 167 time2str(char *buf, size_t len, uint64_t time)
164 168 {
165 169 static const struct unit {
166 170 const char *u_name;
167 171 hrtime_t u_mul;
168 172 } units[] = {
169 173 { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) },
170 174 { "h", NANOSEC * (hrtime_t)(60 * 60) },
171 175 { "m", NANOSEC * (hrtime_t)60 },
172 176 { "s", NANOSEC / SEC },
173 177 { "ms", NANOSEC / MILLISEC },
174 178 { "us", NANOSEC / MICROSEC },
175 179 { "ns", NANOSEC / NANOSEC },
176 180 };
177 181
178 182 const struct unit *up;
179 183
180 184 for (up = units; time % up->u_mul != 0; up++)
181 185 continue; /* find largest unit of which 'time' is a multiple */
182 186
183 187 (void) snprintf(buf, len, "%llu%s", time / up->u_mul, up->u_name);
184 188 return (buf);
185 189 }
186 190
187 191 static char *
188 192 size2str(char *buf, size_t len, uint64_t size)
189 193 {
190 194 static const char units[] = "bKMGTPE";
191 195 const uint64_t scale = 1024;
192 196 const char *up = units;
193 197 uint64_t osize = 0;
194 198
195 199 /*
196 200 * Convert the input size to a round number of the appropriately
197 201 * scaled units (saved in 'size') and a remainder (saved in 'osize').
198 202 */
199 203 while (size >= scale && up < (units + sizeof (units) - 2)) {
200 204 up++;
201 205 osize = size;
202 206 size = (size + (scale / 2)) / scale;
203 207 }
204 208
205 209 /*
206 210 * Format the result using at most one decimal place and the unit
207 211 * depending upon the amount of remainder (same as df -h algorithm).
208 212 */
209 213 if (osize != 0 && (osize / scale) < 10)
210 214 (void) snprintf(buf, len, "%.1f%c", (float)osize / scale, *up);
211 215 else if (size != 0)
212 216 (void) snprintf(buf, len, "%llu%c", size, *up);
213 217 else
214 218 (void) snprintf(buf, len, "0");
215 219
216 220 return (buf);
217 221 }
218 222
219 223 static uint64_t
220 224 u64delta(uint64_t old, uint64_t new)
221 225 {
222 226 return (new >= old ? (new - old) : ((UINT64_MAX - old) + new + 1));
223 227 }
224 228
225 229 static struct modstats *
226 230 modstat_create(const char *name, id_t id)
227 231 {
228 232 struct modstats *mp = malloc(sizeof (struct modstats));
229 233
230 234 if (mp == NULL)
231 235 return (NULL);
232 236
233 237 bzero(mp, sizeof (struct modstats));
234 238
235 239 if (name != NULL && (mp->m_name = strdup(name)) == NULL) {
236 240 free(mp);
237 241 return (NULL);
238 242 }
239 243
240 244 mp->m_id = id;
241 245 mp->m_next = g_mods;
242 246 g_mods = mp;
243 247 return (mp);
244 248 }
245 249
246 250 /*
247 251 * Given a statistics buffer containing event queue statistics, compute the
248 252 * common queue statistics for the given module and store the results in 'mp'.
249 253 * We set m_new and m_old for the caller, and store the compute values of
250 254 * m_svc, m_wait, m_pct_w, and m_pct_b there as well. The caller must not free
251 255 * 'ams' until after using the results as m_new may contain pointers to it.
252 256 */
253 257 static void
254 258 modstat_compute(struct modstats *mp, fmd_adm_stats_t *ams)
255 259 {
256 260 static fmd_stat_t *t_beg = (fmd_stat_t *)(&stats_template + 0);
257 261 static fmd_stat_t *t_end = (fmd_stat_t *)(&stats_template + 1);
258 262
259 263 struct stats *old, *new;
260 264 fmd_stat_t *tsp, *nsp, *sp;
261 265 double elapsed, avg_w, avg_d;
262 266 uint64_t delta;
263 267
264 268 old = mp->m_old = &mp->m_stbuf[mp->m_stidx];
265 269 mp->m_stidx = 1 - mp->m_stidx;
266 270 new = mp->m_new = &mp->m_stbuf[mp->m_stidx];
267 271
268 272 /*
269 273 * The statistics can come in any order; we compare each one to the
270 274 * template of statistics of interest, find the matching ones, and copy
271 275 * their values into the appropriate slot of the 'new' stats.
272 276 */
273 277 for (nsp = ams->ams_buf; nsp < ams->ams_buf + ams->ams_len; nsp++) {
274 278 for (tsp = t_beg; tsp < t_end; tsp++) {
275 279 const char *p = strrchr(nsp->fmds_name, '.');
276 280
277 281 /*
278 282 * The fmd queue stats can either be named fmd.<name>
279 283 * or fmd.xprt.%u.<name> depending on whether we're
280 284 * looking at the module queue or the transport queue.
281 285 * So we match using the patterns fmd.* and *.<name>
282 286 * and store only the value of <name> in stats_template.
283 287 */
284 288 if (p == NULL || strcmp(p + 1, tsp->fmds_name) != 0 ||
285 289 strncmp(nsp->fmds_name, "fmd.", 4) != 0)
286 290 continue; /* continue until we match the stat */
287 291
288 292 if (tsp->fmds_type != nsp->fmds_type) {
289 293 warn("%s has unexpected type (%u != %u)\n",
290 294 nsp->fmds_name, tsp->fmds_type,
291 295 nsp->fmds_type);
292 296 } else {
293 297 sp = (fmd_stat_t *)new + (tsp - t_beg);
294 298 sp->fmds_value = nsp->fmds_value;
295 299 }
296 300 }
297 301 }
298 302
299 303 /*
300 304 * Compute the elapsed time by taking the delta between 'snaptime', or
301 305 * or between snaptime and loadtime if there is no previous snapshot.
302 306 * If delta is zero, set it to 1sec so we don't divide by zero later.
303 307 */
304 308 delta = u64delta(old->snaptime.fmds_value.ui64 ?
305 309 old->snaptime.fmds_value.ui64 : old->loadtime.fmds_value.ui64,
306 310 new->snaptime.fmds_value.ui64);
307 311
308 312 elapsed = delta ? (double)delta : (double)NANOSEC;
309 313
310 314 /*
311 315 * Compute average wait queue len by taking the delta in the wait queue
312 316 * len * time products (wlentime stat) and dividing by the elapsed time.
313 317 */
314 318 delta = u64delta(old->wlentime.fmds_value.ui64,
315 319 new->wlentime.fmds_value.ui64);
316 320
317 321 if (delta != 0)
318 322 mp->m_wait = (double)delta / elapsed;
319 323 else
320 324 mp->m_wait = 0.0;
321 325
322 326 /*
323 327 * Compute average wait time by taking the delta in the wait queue time
324 328 * (wtime) and dividing by the delta in the number of dispatches.
325 329 */
326 330 delta = u64delta(old->dispatched.fmds_value.ui64,
327 331 new->dispatched.fmds_value.ui64);
328 332
329 333 if (delta != 0) {
330 334 avg_w = (double)u64delta(old->wtime.fmds_value.ui64,
331 335 new->wtime.fmds_value.ui64) / (double)delta;
332 336 } else
333 337 avg_w = 0.0;
334 338
335 339 /*
336 340 * Compute average dispatch time by taking the delta in the dispatch
337 341 * time (dtime) and dividing by the delta in the number of dequeues.
338 342 */
339 343 delta = u64delta(old->dequeued.fmds_value.ui64,
340 344 new->dequeued.fmds_value.ui64);
341 345
342 346 if (delta != 0) {
343 347 avg_d = (double)u64delta(old->dtime.fmds_value.ui64,
344 348 new->dtime.fmds_value.ui64) / (double)delta;
345 349 } else
346 350 avg_d = 0.0;
347 351
348 352 /*
349 353 * Finally compute the average overall service time by adding together
350 354 * the average wait and dispatch times and converting to milliseconds.
351 355 */
352 356 mp->m_svc = ((avg_w + avg_d) * (double)MILLISEC) / (double)NANOSEC;
353 357
354 358 /*
355 359 * Compute the %wait and %busy times by taking the delta in wait and
356 360 * busy times, dividing by the elapsed time, and multiplying by 100.
357 361 */
358 362 delta = u64delta(old->wtime.fmds_value.ui64,
359 363 new->wtime.fmds_value.ui64);
360 364
361 365 if (delta != 0)
362 366 mp->m_pct_w = ((double)delta / elapsed) * 100.0;
363 367 else
364 368 mp->m_pct_w = 0.0;
365 369
↓ open down ↓ |
329 lines elided |
↑ open up ↑ |
366 370 delta = u64delta(old->dtime.fmds_value.ui64,
367 371 new->dtime.fmds_value.ui64);
368 372
369 373 if (delta != 0)
370 374 mp->m_pct_b = ((double)delta / elapsed) * 100.0;
371 375 else
372 376 mp->m_pct_b = 0.0;
373 377 }
374 378
375 379 /*ARGSUSED*/
376 -static int
380 +static void
377 381 stat_one_xprt(id_t id, void *ignored)
378 382 {
379 383 fmd_adm_stats_t ams;
380 384 struct modstats *mp;
381 385
382 386 if (fmd_adm_xprt_stats(g_adm, id, &ams) != 0) {
383 387 warn("failed to retrieve statistics for transport %d", (int)id);
384 - return (0); /* continue on to the next transport */
388 + return;
385 389 }
386 390
387 391 for (mp = g_mods; mp != NULL; mp = mp->m_next) {
388 392 if (mp->m_id == id)
389 393 break;
390 394 }
391 395
392 396 if (mp == NULL && (mp = modstat_create(NULL, id)) == NULL) {
393 397 warn("failed to allocate memory for transport %d", (int)id);
394 398 (void) fmd_adm_stats_free(g_adm, &ams);
395 - return (0);
399 + return;
396 400 }
397 401
398 402 modstat_compute(mp, &ams);
399 403
400 404 (void) printf("%3d %5s %7llu %7llu %7llu %7llu "
401 405 "%4.1f %6.1f %3.0f %3.0f %s\n", (int)id,
402 406 mp->m_new->state.fmds_value.str,
403 407 u64delta(mp->m_old->prdequeued.fmds_value.ui64,
404 408 mp->m_new->prdequeued.fmds_value.ui64),
405 409 u64delta(mp->m_old->received.fmds_value.ui64,
406 410 mp->m_new->received.fmds_value.ui64),
407 411 u64delta(mp->m_old->discarded.fmds_value.ui64,
408 412 mp->m_new->discarded.fmds_value.ui64),
409 413 u64delta(mp->m_old->lost.fmds_value.ui64,
410 414 mp->m_new->lost.fmds_value.ui64),
411 415 mp->m_wait, mp->m_svc, mp->m_pct_w, mp->m_pct_b,
412 416 mp->m_new->module.fmds_value.str);
413 417
414 418 (void) fmd_adm_stats_free(g_adm, &ams);
415 - return (0);
416 419 }
417 420
418 421 static void
419 422 stat_xprt(void)
420 423 {
421 424 (void) printf("%3s %5s %7s %7s %7s %7s %4s %6s %3s %3s %s\n",
422 425 "id", "state", "ev_send", "ev_recv", "ev_drop", "ev_lost",
423 426 "wait", "svc_t", "%w", "%b", "module");
424 427
425 428 if (fmd_adm_xprt_iter(g_adm, stat_one_xprt, NULL) != 0)
426 429 die("failed to retrieve list of transports");
427 430 }
428 431
429 -static int
432 +static void
430 433 stat_one_xprt_auth(id_t id, void *arg)
431 434 {
432 435 const char *module = arg;
433 436 fmd_adm_stats_t ams;
434 437 struct modstats *mp;
435 438
436 439 if (fmd_adm_xprt_stats(g_adm, id, &ams) != 0) {
437 440 warn("failed to retrieve statistics for transport %d", (int)id);
438 - return (0); /* continue on to the next transport */
441 + return;
439 442 }
440 443
441 444 for (mp = g_mods; mp != NULL; mp = mp->m_next) {
442 445 if (mp->m_id == id)
443 446 break;
444 447 }
445 448
446 449 if (mp == NULL && (mp = modstat_create(NULL, id)) == NULL) {
447 450 warn("failed to allocate memory for transport %d", (int)id);
448 451 (void) fmd_adm_stats_free(g_adm, &ams);
449 - return (0);
452 + return;
450 453 }
451 454
452 455 modstat_compute(mp, &ams);
453 456
454 457 if (module == NULL ||
455 458 strcmp(module, mp->m_new->module.fmds_value.str) == 0) {
456 459 (void) printf("%3d %5s %-18s %s\n", (int)id,
457 460 mp->m_new->state.fmds_value.str,
458 461 mp->m_new->module.fmds_value.str,
459 462 mp->m_new->authority.fmds_value.str ?
460 463 mp->m_new->authority.fmds_value.str : "-");
461 464 }
462 465
463 466 (void) fmd_adm_stats_free(g_adm, &ams);
464 - return (0);
465 467 }
466 468
467 469 static void
468 470 stat_xprt_auth(const char *module)
469 471 {
470 472 (void) printf("%3s %5s %-18s %s\n",
471 473 "id", "state", "module", "authority");
472 474
473 475 if (fmd_adm_xprt_iter(g_adm, stat_one_xprt_auth, (void *)module) != 0)
474 476 die("failed to retrieve list of transports");
475 477 }
476 478
477 479 /*ARGSUSED*/
478 480 static int
479 481 stat_one_fmd(const fmd_adm_modinfo_t *ami, void *ignored)
480 482 {
481 483 char memsz[8], bufsz[8];
482 484 fmd_adm_stats_t ams;
483 485 struct modstats *mp;
484 486
485 487 if (fmd_adm_module_stats(g_adm, ami->ami_name, &ams) != 0) {
486 488 warn("failed to retrieve statistics for %s", ami->ami_name);
487 489 return (0); /* continue on to the next module */
488 490 }
489 491
490 492 for (mp = g_mods; mp != NULL; mp = mp->m_next) {
491 493 if (strcmp(mp->m_name, ami->ami_name) == 0)
492 494 break;
493 495 }
494 496
495 497 if (mp == NULL && (mp = modstat_create(ami->ami_name, 0)) == NULL) {
496 498 warn("failed to allocate memory for %s", ami->ami_name);
497 499 (void) fmd_adm_stats_free(g_adm, &ams);
498 500 return (0);
499 501 }
500 502
501 503 modstat_compute(mp, &ams);
502 504
503 505 (void) printf("%-18s %7llu %7llu %4.1f %6.1f %3.0f %3.0f "
504 506 "%5llu %5llu %6s %6s\n", ami->ami_name,
505 507 u64delta(mp->m_old->prdequeued.fmds_value.ui64,
506 508 mp->m_new->prdequeued.fmds_value.ui64),
507 509 u64delta(mp->m_old->accepted.fmds_value.ui64,
508 510 mp->m_new->accepted.fmds_value.ui64),
509 511 mp->m_wait, mp->m_svc, mp->m_pct_w, mp->m_pct_b,
510 512 mp->m_new->caseopen.fmds_value.ui64,
511 513 mp->m_new->casesolved.fmds_value.ui64,
512 514 size2str(memsz, sizeof (memsz),
513 515 mp->m_new->memtotal.fmds_value.ui64),
514 516 size2str(bufsz, sizeof (bufsz),
515 517 mp->m_new->buftotal.fmds_value.ui64));
516 518
517 519 (void) fmd_adm_stats_free(g_adm, &ams);
518 520 return (0);
519 521 }
520 522
521 523 static void
522 524 stat_fmd(void)
523 525 {
524 526 (void) printf("%-18s %7s %7s %4s %6s %3s %3s %5s %5s %6s %6s\n",
525 527 "module", "ev_recv", "ev_acpt", "wait", "svc_t", "%w", "%b",
526 528 "open", "solve", "memsz", "bufsz");
527 529
528 530 if (fmd_adm_module_iter(g_adm, stat_one_fmd, NULL) != 0)
529 531 die("failed to retrieve list of modules");
530 532 }
531 533
532 534 static void
533 535 stat_mod(const char *name, int aflag, int zflag)
534 536 {
535 537 fmd_adm_stats_t ams;
536 538 fmd_stat_t *sp;
537 539 char buf[64];
538 540
539 541 if (fmd_adm_stats_read(g_adm, name, &ams) != 0) {
540 542 die("failed to retrieve statistics for %s",
541 543 name ? name : "fmd(1M)");
542 544 }
543 545
544 546 (void) printf("%20s %-16s %s\n", "NAME", "VALUE", "DESCRIPTION");
545 547
546 548 for (sp = ams.ams_buf; sp < ams.ams_buf + ams.ams_len; sp++) {
547 549 if (aflag == 0 && strncmp(sp->fmds_name, "fmd.", 4) == 0)
548 550 continue; /* skip fmd-internal stats unless -a used */
549 551
550 552 if (zflag) {
551 553 switch (sp->fmds_type) {
552 554 case FMD_TYPE_INT32:
553 555 case FMD_TYPE_UINT32:
554 556 if (sp->fmds_value.ui32 == 0)
555 557 continue;
556 558 break;
557 559 case FMD_TYPE_INT64:
558 560 case FMD_TYPE_UINT64:
559 561 case FMD_TYPE_TIME:
560 562 case FMD_TYPE_SIZE:
561 563 if (sp->fmds_value.ui64 == 0)
562 564 continue;
563 565 break;
564 566 case FMD_TYPE_STRING:
565 567 if (sp->fmds_value.str == NULL ||
566 568 sp->fmds_value.str[0] == '\0')
567 569 continue;
568 570 break;
569 571 }
570 572 }
571 573
572 574 (void) printf("%20s ", sp->fmds_name);
573 575
574 576 switch (sp->fmds_type) {
575 577 case FMD_TYPE_BOOL:
576 578 (void) printf("%-16s",
577 579 sp->fmds_value.bool ? "true" : "false");
578 580 break;
579 581 case FMD_TYPE_INT32:
580 582 (void) printf("%-16d", sp->fmds_value.i32);
581 583 break;
582 584 case FMD_TYPE_UINT32:
583 585 (void) printf("%-16u", sp->fmds_value.ui32);
584 586 break;
585 587 case FMD_TYPE_INT64:
586 588 (void) printf("%-16lld", sp->fmds_value.i64);
587 589 break;
588 590 case FMD_TYPE_UINT64:
589 591 (void) printf("%-16llu", sp->fmds_value.ui64);
590 592 break;
591 593 case FMD_TYPE_STRING:
592 594 (void) printf("%-16s", sp->fmds_value.str ?
593 595 sp->fmds_value.str : "<<null>>");
594 596 break;
595 597 case FMD_TYPE_TIME:
596 598 (void) printf("%-16s",
597 599 time2str(buf, sizeof (buf), sp->fmds_value.ui64));
598 600 break;
599 601 case FMD_TYPE_SIZE:
600 602 (void) printf("%-16s",
601 603 size2str(buf, sizeof (buf), sp->fmds_value.ui64));
602 604 break;
603 605 default:
604 606 (void) snprintf(buf, sizeof (buf),
605 607 "<<type=%u>>\n", sp->fmds_type);
606 608 (void) printf("%-16s", buf);
607 609 }
608 610
609 611 (void) printf(" %s\n", sp->fmds_desc);
610 612 }
611 613
612 614 (void) fmd_adm_stats_free(g_adm, &ams);
613 615 }
614 616
615 617 /*ARGSUSED*/
616 618 static int
617 619 stat_one_serd(const fmd_adm_serdinfo_t *asi, void *ignored)
618 620 {
619 621 char buf1[32], buf2[32], n[32];
620 622
621 623 (void) snprintf(n, sizeof (n), ">%llu", asi->asi_n);
622 624
623 625 (void) printf("%-36s %3s %5s %3u %24s %s\n",
624 626 asi->asi_name, n, time2str(buf1, sizeof (buf1), asi->asi_t),
625 627 asi->asi_count, time2str(buf2, sizeof (buf2), asi->asi_delta),
626 628 (asi->asi_flags & FMD_ADM_SERD_FIRED) ? "fire" : "pend");
627 629
628 630 return (0);
629 631 }
630 632
631 633 static void
632 634 stat_mod_serd(const char *name)
633 635 {
634 636 (void) printf("%-36s %3s %5s %3s %24s %4s\n",
635 637 "NAME", ">N", "T", "CNT", "DELTA", "STAT");
636 638
637 639 if (fmd_adm_serd_iter(g_adm, name, stat_one_serd, NULL) != 0)
638 640 die("failed to retrieve serd engines for %s", name);
639 641 }
640 642
641 643 static int
642 644 getint(const char *name, const char *s)
643 645 {
644 646 long val;
645 647 char *p;
646 648
647 649 errno = 0;
648 650 val = strtol(s, &p, 10);
649 651
650 652 if (errno != 0 || p == s || *p != '\0' || val < 0 || val > INT_MAX) {
651 653 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n",
652 654 g_pname, name, s);
653 655 exit(FMSTAT_EXIT_USAGE);
654 656 }
655 657
656 658 return ((int)val);
657 659 }
658 660
659 661 static uint32_t
660 662 getu32(const char *name, const char *s)
661 663 {
662 664 u_longlong_t val;
663 665 char *p;
664 666
665 667 errno = 0;
666 668 val = strtoull(s, &p, 0);
667 669
668 670 if (errno != 0 || p == s || *p != '\0' || val > UINT32_MAX) {
669 671 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n",
670 672 g_pname, name, s);
671 673 exit(FMSTAT_EXIT_USAGE);
672 674 }
673 675
674 676 return ((uint32_t)val);
675 677 }
676 678
677 679 static int
678 680 usage(FILE *fp)
679 681 {
680 682 (void) fprintf(fp, "Usage: %s [-astTz] [-m module] "
681 683 "[-P prog] [-d d|u] [interval [count]]\n\n", g_pname);
682 684
683 685 (void) fprintf(fp,
684 686 "\t-a show all statistics, including those kept by fmd\n"
685 687 "\t-d display a timestamp in date (d) or unix time_t (u)\n"
686 688 "\t-m show module-specific statistics\n"
687 689 "\t-P connect to alternate fmd program\n"
688 690 "\t-s show module-specific serd engines\n"
689 691 "\t-t show transport-specific statistics\n"
690 692 "\t-T show transport modules and authorities\n"
691 693 "\t-z suppress zero-valued statistics\n");
692 694
693 695 return (FMSTAT_EXIT_USAGE);
694 696 }
695 697
696 698 int
697 699 main(int argc, char *argv[])
698 700 {
699 701 int opt_a = 0, opt_s = 0, opt_t = 0, opt_T = 0, opt_z = 0;
700 702 const char *opt_m = NULL;
701 703 int msec = 0, iter = 1;
702 704
703 705 uint32_t program;
704 706 char *p;
705 707 int c;
706 708
707 709 if ((p = strrchr(argv[0], '/')) == NULL)
708 710 g_pname = argv[0];
709 711 else
710 712 g_pname = p + 1;
711 713
712 714 if ((p = getenv("FMD_PROGRAM")) != NULL)
713 715 program = getu32("$FMD_PROGRAM", p);
714 716 else
715 717 program = FMD_ADM_PROGRAM;
716 718
717 719 (void) setlocale(LC_ALL, "");
718 720 (void) textdomain(TEXT_DOMAIN);
719 721
720 722 while ((c = getopt(argc, argv, "ad:m:P:stTz")) != EOF) {
721 723 switch (c) {
722 724 case 'a':
723 725 opt_a++;
724 726 break;
725 727 case 'd':
726 728 if (optarg) {
727 729 if (*optarg == 'u')
728 730 timestamp_fmt = UDATE;
729 731 else if (*optarg == 'd')
730 732 timestamp_fmt = DDATE;
731 733 else
732 734 return (usage(stderr));
733 735 } else {
734 736 return (usage(stderr));
735 737 }
736 738 break;
737 739 case 'm':
738 740 opt_m = optarg;
739 741 break;
740 742 case 'P':
741 743 program = getu32("program", optarg);
742 744 break;
743 745 case 's':
744 746 opt_s++;
745 747 break;
746 748 case 't':
747 749 opt_t++;
748 750 break;
749 751 case 'T':
750 752 opt_T++;
751 753 break;
752 754 case 'z':
753 755 opt_z++;
754 756 break;
755 757 default:
756 758 return (usage(stderr));
757 759 }
758 760 }
759 761
760 762 if (optind < argc) {
761 763 msec = getint("interval", argv[optind++]) * MILLISEC;
762 764 iter = -1;
763 765 }
764 766
765 767 if (optind < argc)
766 768 iter = getint("count", argv[optind++]);
767 769
768 770 if (optind < argc)
769 771 return (usage(stderr));
770 772
771 773 if (opt_t != 0 && (opt_m != NULL || opt_s != 0)) {
772 774 (void) fprintf(stderr,
773 775 "%s: -t cannot be used with -m or -s\n", g_pname);
774 776 return (FMSTAT_EXIT_USAGE);
775 777 }
776 778
777 779 if (opt_t != 0 && opt_T != 0) {
778 780 (void) fprintf(stderr,
779 781 "%s: -t and -T are mutually exclusive options\n", g_pname);
780 782 return (FMSTAT_EXIT_USAGE);
781 783 }
782 784
783 785 if (opt_m == NULL && opt_s != 0) {
784 786 (void) fprintf(stderr,
785 787 "%s: -s requires -m <module>\n", g_pname);
786 788 return (FMSTAT_EXIT_USAGE);
787 789 }
788 790
789 791 if ((g_adm = fmd_adm_open(NULL, program, FMD_ADM_VERSION)) == NULL)
790 792 die(NULL); /* fmd_adm_errmsg() has enough info */
791 793
792 794 while (iter < 0 || iter-- > 0) {
793 795 if (timestamp_fmt != NODATE)
794 796 print_timestamp(timestamp_fmt);
795 797 if (opt_s)
796 798 stat_mod_serd(opt_m);
797 799 else if (opt_T)
798 800 stat_xprt_auth(opt_m);
799 801 else if (opt_a || opt_m)
800 802 stat_mod(opt_m, opt_a, opt_z);
801 803 else if (opt_t)
802 804 stat_xprt();
803 805 else
804 806 stat_fmd();
805 807
806 808 if (iter != 0) {
807 809 (void) poll(NULL, 0, msec);
808 810 (void) putchar('\n');
809 811 }
810 812 }
811 813
812 814 fmd_adm_close(g_adm);
813 815 return (FMSTAT_EXIT_SUCCESS);
814 816 }
↓ open down ↓ |
340 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX