Print this page
check return from clock_gettime.
fix cstyle
codereview and testing fixes.
6558 kstat: desire type for timestamps
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/stat/kstat/kstat.c
+++ new/usr/src/cmd/stat/kstat/kstat.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 (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright (c) 2013 David Hoeppner. All rights reserved.
25 25 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
26 26 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
27 + * Copyright 2016 Garrett D'Amore
27 28 */
28 29
29 30 /*
30 31 * Display kernel statistics
31 32 *
32 33 * This is a reimplementation of the perl kstat command originally found
33 34 * under usr/src/cmd/kstat/kstat.pl
34 35 *
35 36 * Incompatibilities:
36 37 * - perl regular expressions replaced with extended REs bracketed by '/'
37 38 *
38 39 * Flags added:
39 40 * -C similar to the -p option but value is separated by a colon
40 41 * -h display help
41 42 * -j json format
43 + * -H b display hrtime as seconds since boot
44 + * -H d display hrtime as date
45 + * -H u display hrtime as UNIX seconds (since epoch)
46 + * -H I display hrtime as ISO-8601 local time
47 + * -H Z display hrtime as ISO-8601 UTC
48 + * -H n display hrtime as nanoseconds (since epoch)
42 49 */
43 50
44 51 #include <assert.h>
45 52 #include <ctype.h>
46 53 #include <errno.h>
47 54 #include <kstat.h>
48 55 #include <langinfo.h>
49 56 #include <libgen.h>
50 57 #include <limits.h>
51 58 #include <locale.h>
52 59 #include <signal.h>
53 60 #include <stddef.h>
54 61 #include <stdio.h>
55 62 #include <stdlib.h>
56 63 #include <string.h>
57 64 #include <strings.h>
58 65 #include <time.h>
59 66 #include <unistd.h>
60 67 #include <sys/list.h>
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
61 68 #include <sys/time.h>
62 69 #include <sys/types.h>
63 70
64 71 #include "kstat.h"
65 72 #include "statcommon.h"
66 73
67 74 char *cmdname = "kstat"; /* Name of this command */
68 75 int caught_cont = 0; /* Have caught a SIGCONT */
69 76
70 77 static uint_t g_timestamp_fmt = NODATE;
78 +static uint_t g_hrtime_fmt = KS_HRFMT_DEFAULT;
71 79
72 80 /* Helper flag - header was printed already? */
73 81 static boolean_t g_headerflg;
74 82
75 83 /* Saved command line options */
76 84 static boolean_t g_cflg = B_FALSE;
77 85 static boolean_t g_jflg = B_FALSE;
78 86 static boolean_t g_lflg = B_FALSE;
79 87 static boolean_t g_pflg = B_FALSE;
80 88 static boolean_t g_qflg = B_FALSE;
81 89 static ks_pattern_t g_ks_class = {"*", 0};
82 90
83 91 /* Return zero if a selector did match */
84 92 static int g_matched = 1;
85 93
86 94 /* Sorted list of kstat instances */
87 95 static list_t instances_list;
88 96 static list_t selector_list;
89 97
98 +static hrtime_t hrtime_origin;
99 +
90 100 int
91 101 main(int argc, char **argv)
92 102 {
93 103 ks_selector_t *nselector;
94 104 ks_selector_t *uselector;
95 105 kstat_ctl_t *kc;
96 106 hrtime_t start_n;
97 107 hrtime_t period_n;
98 108 boolean_t errflg = B_FALSE;
99 109 boolean_t nselflg = B_FALSE;
100 110 boolean_t uselflg = B_FALSE;
101 111 char *q;
102 112 int count = 1;
103 113 int infinite_cycles = 0;
104 114 int interval = 0;
105 115 int n = 0;
106 116 int c, m, tmp;
107 117
108 118 (void) setlocale(LC_ALL, "");
109 119 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
110 120 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
111 121 #endif
112 122 (void) textdomain(TEXT_DOMAIN);
113 123
114 124 /*
115 125 * Create the selector list and a dummy default selector to match
116 126 * everything. While we process the cmdline options we will add
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
117 127 * selectors to this list.
118 128 */
119 129 list_create(&selector_list, sizeof (ks_selector_t),
120 130 offsetof(ks_selector_t, ks_next));
121 131
122 132 nselector = new_selector();
123 133
124 134 /*
125 135 * Parse named command line arguments.
126 136 */
127 - while ((c = getopt(argc, argv, "h?CqjlpT:m:i:n:s:c:")) != EOF)
137 + while ((c = getopt(argc, argv, "h?CqjlpT:m:i:n:s:c:H:")) != EOF)
128 138 switch (c) {
129 139 case 'h':
130 140 case '?':
131 141 usage();
132 142 exit(0);
133 143 break;
134 144 case 'C':
135 145 g_pflg = g_cflg = B_TRUE;
136 146 break;
137 147 case 'q':
138 148 g_qflg = B_TRUE;
139 149 break;
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
140 150 case 'j':
141 151 g_jflg = B_TRUE;
142 152 break;
143 153 case 'l':
144 154 g_pflg = g_lflg = B_TRUE;
145 155 break;
146 156 case 'p':
147 157 g_pflg = B_TRUE;
148 158 break;
149 159 case 'T':
160 + if (strlen(optarg) != 1) {
161 + errflg = B_TRUE;
162 + }
150 163 switch (*optarg) {
151 164 case 'd':
152 165 g_timestamp_fmt = DDATE;
153 166 break;
154 167 case 'u':
155 168 g_timestamp_fmt = UDATE;
156 169 break;
157 170 default:
158 171 errflg = B_TRUE;
159 172 }
160 173 break;
161 174 case 'm':
162 175 nselflg = B_TRUE;
163 176 nselector->ks_module.pstr =
164 177 (char *)ks_safe_strdup(optarg);
165 178 break;
166 179 case 'i':
167 180 nselflg = B_TRUE;
168 181 nselector->ks_instance.pstr =
169 182 (char *)ks_safe_strdup(optarg);
170 183 break;
171 184 case 'n':
172 185 nselflg = B_TRUE;
173 186 nselector->ks_name.pstr =
174 187 (char *)ks_safe_strdup(optarg);
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
175 188 break;
176 189 case 's':
177 190 nselflg = B_TRUE;
178 191 nselector->ks_statistic.pstr =
179 192 (char *)ks_safe_strdup(optarg);
180 193 break;
181 194 case 'c':
182 195 g_ks_class.pstr =
183 196 (char *)ks_safe_strdup(optarg);
184 197 break;
198 + case 'H':
199 + switch (*optarg) {
200 + case 'o':
201 + case 'b':
202 + case 'n':
203 + case 'I':
204 + case 'Z':
205 + case 'd':
206 + case 'u':
207 + if (strlen(optarg) != 1) {
208 + errflg = B_TRUE;
209 + }
210 + g_hrtime_fmt = *optarg;
211 + break;
212 + default:
213 + errflg = B_TRUE;
214 + break;
215 + }
216 + break;
185 217 default:
186 218 errflg = B_TRUE;
187 219 break;
188 220 }
189 221
190 222 if (g_qflg && (g_jflg || g_pflg)) {
191 223 (void) fprintf(stderr, gettext(
192 224 "-q and -lpj are mutually exclusive\n"));
193 225 errflg = B_TRUE;
194 226 }
195 227
228 + switch (g_hrtime_fmt) {
229 + case KS_HRFMT_DEFAULT:
230 + case KS_HRFMT_BOOT:
231 + break;
232 + default: {
233 + struct timespec ts;
234 + if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
235 + perror("clock_gettime(CLOCK_REALTIME)");
236 + exit(3);
237 + }
238 + hrtime_origin = ts.tv_sec;
239 + hrtime_origin *= 1000000000;
240 + hrtime_origin += ts.tv_nsec;
241 + hrtime_origin -= gethrtime();
242 + }
243 + }
244 +
196 245 if (errflg) {
197 246 usage();
198 247 exit(2);
199 248 }
200 249
201 250 argc -= optind;
202 251 argv += optind;
203 252
204 253 /*
205 254 * Consume the rest of the command line. Parsing the
206 255 * unnamed command line arguments.
207 256 */
208 257 while (argc--) {
209 258 errno = 0;
210 259 tmp = strtoul(*argv, &q, 10);
211 260 if (tmp == ULONG_MAX && errno == ERANGE) {
212 261 if (n == 0) {
213 262 (void) fprintf(stderr, gettext(
214 263 "Interval is too large\n"));
215 264 } else if (n == 1) {
216 265 (void) fprintf(stderr, gettext(
217 266 "Count is too large\n"));
218 267 }
219 268 usage();
220 269 exit(2);
221 270 }
222 271
223 272 if (errno != 0 || *q != '\0') {
224 273 m = 0;
225 274 uselector = new_selector();
226 275 while ((q = (char *)strsep(argv, ":")) != NULL) {
227 276 m++;
228 277 if (m > 4) {
229 278 free(uselector);
230 279 usage();
231 280 exit(2);
232 281 }
233 282
234 283 if (*q != '\0') {
235 284 switch (m) {
236 285 case 1:
237 286 uselector->ks_module.pstr =
238 287 (char *)ks_safe_strdup(q);
239 288 break;
240 289 case 2:
241 290 uselector->ks_instance.pstr =
242 291 (char *)ks_safe_strdup(q);
243 292 break;
244 293 case 3:
245 294 uselector->ks_name.pstr =
246 295 (char *)ks_safe_strdup(q);
247 296 break;
248 297 case 4:
249 298 uselector->ks_statistic.pstr =
250 299 (char *)ks_safe_strdup(q);
251 300 break;
252 301 default:
253 302 assert(B_FALSE);
254 303 }
255 304 }
256 305 }
257 306
258 307 uselflg = B_TRUE;
259 308 list_insert_tail(&selector_list, uselector);
260 309 } else {
261 310 if (tmp < 1) {
262 311 if (n == 0) {
263 312 (void) fprintf(stderr, gettext(
264 313 "Interval must be an "
265 314 "integer >= 1"));
266 315 } else if (n == 1) {
267 316 (void) fprintf(stderr, gettext(
268 317 "Count must be an integer >= 1"));
269 318 }
270 319 usage();
271 320 exit(2);
272 321 } else {
273 322 if (n == 0) {
274 323 interval = tmp;
275 324 count = -1;
276 325 } else if (n == 1) {
277 326 count = tmp;
278 327 } else {
279 328 usage();
280 329 exit(2);
281 330 }
282 331 }
283 332 n++;
284 333 }
285 334 argv++;
286 335 }
287 336
288 337 /*
289 338 * Check if we founded a named selector on the cmdline.
290 339 */
291 340 if (uselflg) {
292 341 if (nselflg) {
293 342 (void) fprintf(stderr, gettext(
294 343 "[module[:instance[:name[:statistic]]]] and "
295 344 "-m -i -n -s are mutually exclusive"));
296 345 usage();
297 346 exit(2);
298 347 } else {
299 348 free(nselector);
300 349 }
301 350 } else {
302 351 list_insert_tail(&selector_list, nselector);
303 352 }
304 353
305 354 assert(!list_is_empty(&selector_list));
306 355
307 356 list_create(&instances_list, sizeof (ks_instance_t),
308 357 offsetof(ks_instance_t, ks_next));
309 358
310 359 while ((kc = kstat_open()) == NULL) {
311 360 if (errno == EAGAIN) {
312 361 (void) poll(NULL, 0, 200);
313 362 } else {
314 363 perror("kstat_open");
315 364 exit(3);
316 365 }
317 366 }
318 367
319 368 if (count > 1) {
320 369 if (signal(SIGCONT, cont_handler) == SIG_ERR) {
321 370 (void) fprintf(stderr, gettext(
322 371 "signal failed"));
323 372 exit(3);
324 373 }
325 374 }
326 375
327 376 period_n = (hrtime_t)interval * NANOSEC;
328 377 start_n = gethrtime();
329 378
330 379 while (count == -1 || count-- > 0) {
331 380 ks_instances_read(kc);
332 381 ks_instances_print();
333 382
334 383 if (interval && count) {
335 384 ks_sleep_until(&start_n, period_n, infinite_cycles,
336 385 &caught_cont);
337 386 (void) kstat_chain_update(kc);
338 387 (void) putchar('\n');
339 388 }
340 389 }
341 390
342 391 (void) kstat_close(kc);
343 392
344 393 return (g_matched);
↓ open down ↓ |
139 lines elided |
↑ open up ↑ |
345 394 }
346 395
347 396 /*
348 397 * Print usage.
349 398 */
350 399 static void
351 400 usage(void)
352 401 {
353 402 (void) fprintf(stderr, gettext(
354 403 "Usage:\n"
355 - "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ]\n"
404 + "kstat [ -Cjlpq ] [ -T d|u ] [ -H d|n|u|I|Z ] [ -c class ]\n"
356 405 " [ -m module ] [ -i instance ] [ -n name ] [ -s statistic ]\n"
357 406 " [ interval [ count ] ]\n"
358 - "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ]\n"
407 + "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ] [ -H d|n|u|I|Z ]\n"
359 408 " [ module[:instance[:name[:statistic]]] ... ]\n"
360 409 " [ interval [ count ] ]\n"));
361 410 }
362 411
363 412 /*
364 413 * Sort compare function.
365 414 */
366 415 static int
367 416 compare_instances(ks_instance_t *l_arg, ks_instance_t *r_arg)
368 417 {
369 418 int rval;
370 419
371 420 rval = strcasecmp(l_arg->ks_module, r_arg->ks_module);
372 421 if (rval == 0) {
373 422 if (l_arg->ks_instance == r_arg->ks_instance) {
374 423 return (strcasecmp(l_arg->ks_name, r_arg->ks_name));
375 424 } else if (l_arg->ks_instance < r_arg->ks_instance) {
376 425 return (-1);
377 426 } else {
378 427 return (1);
379 428 }
380 429 } else {
381 430 return (rval);
382 431 }
383 432 }
384 433
385 434 static char *
386 435 ks_safe_strdup(char *str)
387 436 {
388 437 char *ret;
389 438
390 439 if (str == NULL) {
391 440 return (NULL);
392 441 }
393 442
394 443 while ((ret = strdup(str)) == NULL) {
395 444 if (errno == EAGAIN) {
396 445 (void) poll(NULL, 0, 200);
397 446 } else {
398 447 perror("strdup");
399 448 exit(3);
400 449 }
401 450 }
402 451
403 452 return (ret);
404 453 }
405 454
406 455 static void
407 456 ks_sleep_until(hrtime_t *wakeup, hrtime_t interval, int forever,
408 457 int *caught_cont)
409 458 {
410 459 hrtime_t now, pause, pause_left;
411 460 struct timespec pause_tv;
412 461 int status;
413 462
414 463 now = gethrtime();
415 464 pause = *wakeup + interval - now;
416 465
417 466 if (pause <= 0 || pause < (interval / 4)) {
418 467 if (forever || *caught_cont) {
419 468 *wakeup = now + interval;
420 469 pause = interval;
421 470 } else {
422 471 pause = interval / 2;
423 472 *wakeup += interval;
424 473 }
425 474 } else {
426 475 *wakeup += interval;
427 476 }
428 477
429 478 if (pause < 1000) {
430 479 return;
431 480 }
432 481
433 482 pause_left = pause;
434 483 do {
435 484 pause_tv.tv_sec = pause_left / NANOSEC;
436 485 pause_tv.tv_nsec = pause_left % NANOSEC;
437 486 status = nanosleep(&pause_tv, (struct timespec *)NULL);
438 487 if (status < 0) {
439 488 if (errno == EINTR) {
440 489 now = gethrtime();
441 490 pause_left = *wakeup - now;
442 491 if (pause_left < 1000) {
443 492 return;
444 493 }
445 494 } else {
446 495 perror("nanosleep");
447 496 exit(3);
448 497 }
449 498 }
450 499 } while (status != 0);
451 500 }
452 501
453 502 /*
454 503 * Inserts an instance in the per selector list.
455 504 */
456 505 static void
457 506 nvpair_insert(ks_instance_t *ksi, char *name, ks_value_t *value,
458 507 uchar_t data_type)
459 508 {
460 509 ks_nvpair_t *instance;
461 510 ks_nvpair_t *tmp;
462 511
463 512 instance = (ks_nvpair_t *)malloc(sizeof (ks_nvpair_t));
464 513 if (instance == NULL) {
465 514 perror("malloc");
466 515 exit(3);
467 516 }
468 517
469 518 (void) strlcpy(instance->name, name, KSTAT_STRLEN);
470 519 (void) memcpy(&instance->value, value, sizeof (ks_value_t));
471 520 instance->data_type = data_type;
472 521
473 522 tmp = list_head(&ksi->ks_nvlist);
474 523 while (tmp != NULL && strcasecmp(instance->name, tmp->name) > 0)
475 524 tmp = list_next(&ksi->ks_nvlist, tmp);
476 525
477 526 list_insert_before(&ksi->ks_nvlist, tmp, instance);
478 527 }
479 528
480 529 /*
481 530 * Allocates a new all-matching selector.
482 531 */
483 532 static ks_selector_t *
484 533 new_selector(void)
485 534 {
486 535 ks_selector_t *selector;
487 536
488 537 selector = (ks_selector_t *)malloc(sizeof (ks_selector_t));
489 538 if (selector == NULL) {
490 539 perror("malloc");
491 540 exit(3);
492 541 }
493 542
494 543 list_link_init(&selector->ks_next);
495 544
496 545 selector->ks_module.pstr = "*";
497 546 selector->ks_instance.pstr = "*";
498 547 selector->ks_name.pstr = "*";
499 548 selector->ks_statistic.pstr = "*";
500 549
501 550 return (selector);
502 551 }
503 552
504 553 /*
505 554 * This function was taken from the perl kstat module code - please
506 555 * see for further comments there.
507 556 */
508 557 static kstat_raw_reader_t
509 558 lookup_raw_kstat_fn(char *module, char *name)
510 559 {
511 560 char key[KSTAT_STRLEN * 2];
512 561 register char *f, *t;
513 562 int n = 0;
514 563
515 564 for (f = module, t = key; *f != '\0'; f++, t++) {
516 565 while (*f != '\0' && isdigit(*f))
517 566 f++;
518 567 *t = *f;
519 568 }
520 569 *t++ = ':';
521 570
522 571 for (f = name; *f != '\0'; f++, t++) {
523 572 while (*f != '\0' && isdigit(*f))
524 573 f++;
525 574 *t = *f;
526 575 }
527 576 *t = '\0';
528 577
529 578 while (ks_raw_lookup[n].fn != NULL) {
530 579 if (strncmp(ks_raw_lookup[n].name, key, strlen(key)) == 0)
531 580 return (ks_raw_lookup[n].fn);
532 581 n++;
533 582 }
534 583
535 584 return (0);
536 585 }
537 586
538 587 /*
539 588 * Match a string against a shell glob or extended regular expression.
540 589 */
541 590 static boolean_t
542 591 ks_match(const char *str, ks_pattern_t *pattern)
543 592 {
544 593 int regcode;
545 594 char *regstr;
546 595 char *errbuf;
547 596 size_t bufsz;
548 597
549 598 if (pattern->pstr != NULL && gmatch(pattern->pstr, "/*/") != 0) {
550 599 /* All regex patterns are strdup'd copies */
551 600 regstr = pattern->pstr + 1;
552 601 *(strrchr(regstr, '/')) = '\0';
553 602
554 603 regcode = regcomp(&pattern->preg, regstr,
555 604 REG_EXTENDED | REG_NOSUB);
556 605 if (regcode != 0) {
557 606 bufsz = regerror(regcode, NULL, NULL, 0);
558 607 if (bufsz != 0) {
559 608 errbuf = malloc(bufsz);
560 609 if (errbuf == NULL) {
561 610 perror("malloc");
562 611 exit(3);
563 612 }
564 613 (void) regerror(regcode, NULL, errbuf, bufsz);
565 614 (void) fprintf(stderr, "kstat: %s\n", errbuf);
566 615 }
567 616 usage();
568 617 exit(2);
569 618 }
570 619
571 620 pattern->pstr = NULL;
572 621 }
573 622
574 623 if (pattern->pstr == NULL) {
575 624 return (regexec(&pattern->preg, str, 0, NULL, 0) == 0);
576 625 }
577 626
578 627 return ((gmatch(str, pattern->pstr) != 0));
579 628 }
580 629
581 630 /*
582 631 * Iterate over all kernel statistics and save matches.
583 632 */
584 633 static void
585 634 ks_instances_read(kstat_ctl_t *kc)
586 635 {
587 636 kstat_raw_reader_t save_raw = NULL;
588 637 kid_t id;
589 638 ks_selector_t *selector;
590 639 ks_instance_t *ksi;
591 640 ks_instance_t *tmp;
592 641 kstat_t *kp;
593 642 boolean_t skip;
594 643
595 644 for (kp = kc->kc_chain; kp != NULL; kp = kp->ks_next) {
596 645 /* Don't bother storing the kstat headers */
597 646 if (strncmp(kp->ks_name, "kstat_", 6) == 0) {
598 647 continue;
599 648 }
600 649
601 650 /* Don't bother storing raw stats we don't understand */
602 651 if (kp->ks_type == KSTAT_TYPE_RAW) {
603 652 save_raw = lookup_raw_kstat_fn(kp->ks_module,
604 653 kp->ks_name);
605 654 if (save_raw == NULL) {
606 655 #ifdef REPORT_UNKNOWN
607 656 (void) fprintf(stderr,
608 657 "Unknown kstat type %s:%d:%s - "
609 658 "%d of size %d\n", kp->ks_module,
610 659 kp->ks_instance, kp->ks_name,
611 660 kp->ks_ndata, kp->ks_data_size);
612 661 #endif
613 662 continue;
614 663 }
615 664 }
616 665
617 666 /*
618 667 * Iterate over the list of selectors and skip
619 668 * instances we dont want. We filter for statistics
620 669 * later, as we dont know them yet.
621 670 */
622 671 skip = B_TRUE;
623 672 selector = list_head(&selector_list);
624 673 while (selector != NULL) {
625 674 if (ks_match(kp->ks_module, &selector->ks_module) &&
626 675 ks_match(kp->ks_name, &selector->ks_name)) {
627 676 skip = B_FALSE;
628 677 break;
629 678 }
630 679 selector = list_next(&selector_list, selector);
631 680 }
632 681
633 682 if (skip) {
634 683 continue;
635 684 }
636 685
637 686 /*
638 687 * Allocate a new instance and fill in the values
639 688 * we know so far.
640 689 */
641 690 ksi = (ks_instance_t *)malloc(sizeof (ks_instance_t));
642 691 if (ksi == NULL) {
643 692 perror("malloc");
644 693 exit(3);
645 694 }
646 695
647 696 list_link_init(&ksi->ks_next);
648 697
649 698 (void) strlcpy(ksi->ks_module, kp->ks_module, KSTAT_STRLEN);
650 699 (void) strlcpy(ksi->ks_name, kp->ks_name, KSTAT_STRLEN);
651 700 (void) strlcpy(ksi->ks_class, kp->ks_class, KSTAT_STRLEN);
652 701
653 702 ksi->ks_instance = kp->ks_instance;
654 703 ksi->ks_snaptime = kp->ks_snaptime;
655 704 ksi->ks_type = kp->ks_type;
656 705
657 706 list_create(&ksi->ks_nvlist, sizeof (ks_nvpair_t),
658 707 offsetof(ks_nvpair_t, nv_next));
659 708
660 709 SAVE_HRTIME_X(ksi, "crtime", kp->ks_crtime);
661 710 SAVE_HRTIME_X(ksi, "snaptime", kp->ks_snaptime);
662 711 if (g_pflg) {
663 712 SAVE_STRING_X(ksi, "class", kp->ks_class);
664 713 }
665 714
666 715 /* Insert this instance into a sorted list */
667 716 tmp = list_head(&instances_list);
668 717 while (tmp != NULL && compare_instances(ksi, tmp) > 0)
669 718 tmp = list_next(&instances_list, tmp);
670 719
671 720 list_insert_before(&instances_list, tmp, ksi);
672 721
673 722 /* Read the actual statistics */
674 723 id = kstat_read(kc, kp, NULL);
675 724 if (id == -1) {
676 725 #ifdef REPORT_UNKNOWN
677 726 perror("kstat_read");
678 727 #endif
679 728 continue;
680 729 }
681 730
682 731 switch (kp->ks_type) {
683 732 case KSTAT_TYPE_RAW:
684 733 save_raw(kp, ksi);
685 734 break;
686 735 case KSTAT_TYPE_NAMED:
687 736 save_named(kp, ksi);
688 737 break;
689 738 case KSTAT_TYPE_INTR:
690 739 save_intr(kp, ksi);
691 740 break;
692 741 case KSTAT_TYPE_IO:
693 742 save_io(kp, ksi);
694 743 break;
695 744 case KSTAT_TYPE_TIMER:
696 745 save_timer(kp, ksi);
697 746 break;
698 747 default:
699 748 assert(B_FALSE); /* Invalid type */
700 749 break;
↓ open down ↓ |
332 lines elided |
↑ open up ↑ |
701 750 }
702 751 }
703 752 }
704 753
705 754 /*
706 755 * Print the value of a name-value pair.
707 756 */
708 757 static void
709 758 ks_value_print(ks_nvpair_t *nvpair)
710 759 {
760 + char dstr[64];
761 + char zstr[8];
762 + time_t t;
763 +
711 764 switch (nvpair->data_type) {
712 765 case KSTAT_DATA_CHAR:
713 766 (void) fprintf(stdout, "%s", nvpair->value.c);
714 767 break;
715 768 case KSTAT_DATA_INT32:
716 769 (void) fprintf(stdout, "%d", nvpair->value.i32);
717 770 break;
718 771 case KSTAT_DATA_UINT32:
719 772 (void) fprintf(stdout, "%u", nvpair->value.ui32);
720 773 break;
721 774 case KSTAT_DATA_INT64:
722 775 (void) fprintf(stdout, "%lld", nvpair->value.i64);
723 776 break;
724 777 case KSTAT_DATA_UINT64:
725 778 (void) fprintf(stdout, "%llu", nvpair->value.ui64);
726 779 break;
727 780 case KSTAT_DATA_STRING:
728 781 (void) fprintf(stdout, "%s", KSTAT_NAMED_STR_PTR(nvpair));
729 782 break;
730 - case KSTAT_DATA_HRTIME:
731 - if (nvpair->value.ui64 == 0)
732 - (void) fprintf(stdout, "0");
733 - else
783 + case KSTAT_DATA_TIME:
784 + switch (g_hrtime_fmt) {
785 + case KS_HRFMT_UNIX:
734 786 (void) fprintf(stdout, "%.9f",
735 - nvpair->value.ui64 / 1000000000.0);
787 + (nvpair->value.t + hrtime_origin) / 1000000000.0);
788 + break;
789 + case KS_HRFMT_NANO:
790 + (void) fprintf(stdout, "%llu",
791 + (nvpair->value.t + hrtime_origin));
792 + break;
793 + case KS_HRFMT_DATE:
794 + t = (time_t)
795 + ((nvpair->value.t + hrtime_origin) / 1000000000);
796 + (void) strftime(dstr,
797 + sizeof (dstr), "%+", localtime(&t));
798 + (void) fprintf(stdout, "%s", dstr);
799 + break;
800 + case KS_HRFMT_ZISO:
801 + t = (time_t)
802 + ((nvpair->value.t + hrtime_origin) / 1000000000);
803 + (void) strftime(dstr, sizeof (dstr), "%FT%T",
804 + gmtime(&t));
805 + (void) fprintf(stdout, "%s.%06uZ", dstr,
806 + (unsigned)(nvpair->value.t % 1000000000)/1000);
807 + break;
808 + case KS_HRFMT_ISO:
809 + t = (time_t)
810 + ((nvpair->value.t + hrtime_origin) / 1000000000);
811 + (void) strftime(dstr, sizeof (dstr), "%FT%T",
812 + localtime(&t));
813 + (void) strftime(zstr, sizeof (zstr), "%z",
814 + localtime(&t));
815 + (void) fprintf(stdout, "%s.%06u%s", dstr,
816 + (unsigned)(nvpair->value.t % 1000000000)/1000,
817 + zstr);
818 + break;
819 + case KS_HRFMT_DEFAULT:
820 + case KS_HRFMT_BOOT:
821 + if (nvpair->value.ui64 == 0)
822 + (void) fprintf(stdout, "0");
823 + else
824 + (void) fprintf(stdout, "%.9f",
825 + nvpair->value.ui64 / 1000000000.0);
826 + break;
827 + default:
828 + abort();
829 + }
736 830 break;
737 831 default:
738 832 assert(B_FALSE);
739 833 }
740 834 }
741 835
742 836 /*
743 837 * Print a single instance.
744 838 */
745 839 static void
746 840 ks_instance_print(ks_instance_t *ksi, ks_nvpair_t *nvpair)
747 841 {
748 842 if (g_headerflg) {
749 843 if (!g_pflg) {
750 844 (void) fprintf(stdout, DFLT_FMT,
751 845 ksi->ks_module, ksi->ks_instance,
752 846 ksi->ks_name, ksi->ks_class);
753 847 }
754 848 g_headerflg = B_FALSE;
755 849 }
756 850
757 851 if (g_pflg) {
758 852 (void) fprintf(stdout, KS_PFMT,
759 853 ksi->ks_module, ksi->ks_instance,
760 854 ksi->ks_name, nvpair->name);
761 855 if (!g_lflg) {
762 856 (void) putchar(g_cflg ? ':': '\t');
763 857 ks_value_print(nvpair);
764 858 }
765 859 } else {
766 860 (void) fprintf(stdout, KS_DFMT, nvpair->name);
767 861 ks_value_print(nvpair);
768 862 }
769 863
770 864 (void) putchar('\n');
771 865 }
772 866
773 867 /*
774 868 * Print a single instance in JSON format.
775 869 */
776 870 static void
777 871 ks_instance_print_json(ks_instance_t *ksi, ks_nvpair_t *nvpair)
778 872 {
779 873 if (g_headerflg) {
780 874 (void) fprintf(stdout, JSON_FMT,
781 875 ksi->ks_module, ksi->ks_instance,
782 876 ksi->ks_name, ksi->ks_class,
783 877 ksi->ks_type);
784 878
785 879 if (ksi->ks_snaptime == 0)
786 880 (void) fprintf(stdout, "\t\"snaptime\": 0,\n");
787 881 else
788 882 (void) fprintf(stdout, "\t\"snaptime\": %.9f,\n",
789 883 ksi->ks_snaptime / 1000000000.0);
790 884
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
791 885 (void) fprintf(stdout, "\t\"data\": {\n");
792 886
793 887 g_headerflg = B_FALSE;
794 888 }
795 889
796 890 (void) fprintf(stdout, KS_JFMT, nvpair->name);
797 891 if (nvpair->data_type == KSTAT_DATA_STRING) {
798 892 (void) putchar('\"');
799 893 ks_value_print(nvpair);
800 894 (void) putchar('\"');
895 + } else if (nvpair->data_type == KSTAT_DATA_TIME) {
896 + switch (g_hrtime_fmt) {
897 + case KS_HRFMT_ISO:
898 + case KS_HRFMT_ZISO:
899 + case KS_HRFMT_DATE:
900 + (void) putchar('\"');
901 + ks_value_print(nvpair);
902 + (void) putchar('\"');
903 + break;
904 + default:
905 + ks_value_print(nvpair);
906 + }
801 907 } else {
802 908 ks_value_print(nvpair);
803 909 }
804 910 if (nvpair != list_tail(&ksi->ks_nvlist))
805 911 (void) putchar(',');
806 912
807 913 (void) putchar('\n');
808 914 }
809 915
810 916 /*
811 917 * Print all instances.
812 918 */
813 919 static void
814 920 ks_instances_print(void)
815 921 {
816 922 ks_selector_t *selector;
817 923 ks_instance_t *ksi, *ktmp;
818 924 ks_nvpair_t *nvpair, *ntmp;
819 925 void (*ks_print_fn)(ks_instance_t *, ks_nvpair_t *);
820 926 char *ks_number;
821 927
822 928 if (g_timestamp_fmt != NODATE)
823 929 print_timestamp(g_timestamp_fmt);
824 930
825 931 if (g_jflg) {
826 932 ks_print_fn = &ks_instance_print_json;
827 933 (void) putchar('[');
828 934 } else {
829 935 ks_print_fn = &ks_instance_print;
830 936 }
831 937
832 938 /* Iterate over each selector */
833 939 selector = list_head(&selector_list);
834 940 while (selector != NULL) {
835 941
836 942 /* Iterate over each instance */
837 943 for (ksi = list_head(&instances_list); ksi != NULL;
838 944 ksi = list_next(&instances_list, ksi)) {
839 945
840 946 (void) asprintf(&ks_number, "%d", ksi->ks_instance);
841 947 if (!(ks_match(ksi->ks_module, &selector->ks_module) &&
842 948 ks_match(ksi->ks_name, &selector->ks_name) &&
843 949 ks_match(ks_number, &selector->ks_instance) &&
844 950 ks_match(ksi->ks_class, &g_ks_class))) {
845 951 free(ks_number);
846 952 continue;
847 953 }
848 954
849 955 free(ks_number);
850 956
851 957 /* Finally iterate over each statistic */
852 958 g_headerflg = B_TRUE;
853 959 for (nvpair = list_head(&ksi->ks_nvlist);
854 960 nvpair != NULL;
855 961 nvpair = list_next(&ksi->ks_nvlist, nvpair)) {
856 962 if (!ks_match(nvpair->name,
857 963 &selector->ks_statistic))
858 964 continue;
859 965
860 966 g_matched = 0;
861 967 if (!g_qflg)
862 968 (*ks_print_fn)(ksi, nvpair);
863 969 }
864 970
865 971 if (!g_headerflg) {
866 972 if (g_jflg) {
867 973 (void) fprintf(stdout, "\t}\n}");
868 974 if (ksi != list_tail(&instances_list))
869 975 (void) putchar(',');
870 976 } else if (!g_pflg) {
871 977 (void) putchar('\n');
872 978 }
873 979 }
874 980 }
875 981
876 982 selector = list_next(&selector_list, selector);
877 983 }
878 984
879 985 if (g_jflg)
880 986 (void) fprintf(stdout, "]\n");
881 987
882 988 (void) fflush(stdout);
883 989
884 990 /* Free the instances list */
885 991 ksi = list_head(&instances_list);
886 992 while (ksi != NULL) {
887 993 nvpair = list_head(&ksi->ks_nvlist);
888 994 while (nvpair != NULL) {
889 995 ntmp = nvpair;
890 996 nvpair = list_next(&ksi->ks_nvlist, nvpair);
891 997 list_remove(&ksi->ks_nvlist, ntmp);
892 998 if (ntmp->data_type == KSTAT_DATA_STRING)
893 999 free(ntmp->value.str.addr.ptr);
894 1000 free(ntmp);
895 1001 }
896 1002
897 1003 ktmp = ksi;
898 1004 ksi = list_next(&instances_list, ksi);
899 1005 list_remove(&instances_list, ktmp);
900 1006 list_destroy(&ktmp->ks_nvlist);
901 1007 free(ktmp);
902 1008 }
903 1009 }
904 1010
905 1011 static void
906 1012 save_cpu_stat(kstat_t *kp, ks_instance_t *ksi)
907 1013 {
908 1014 cpu_stat_t *stat;
909 1015 cpu_sysinfo_t *sysinfo;
910 1016 cpu_syswait_t *syswait;
911 1017 cpu_vminfo_t *vminfo;
912 1018
913 1019 stat = (cpu_stat_t *)(kp->ks_data);
914 1020 sysinfo = &stat->cpu_sysinfo;
915 1021 syswait = &stat->cpu_syswait;
916 1022 vminfo = &stat->cpu_vminfo;
917 1023
918 1024 SAVE_UINT32_X(ksi, "idle", sysinfo->cpu[CPU_IDLE]);
919 1025 SAVE_UINT32_X(ksi, "user", sysinfo->cpu[CPU_USER]);
920 1026 SAVE_UINT32_X(ksi, "kernel", sysinfo->cpu[CPU_KERNEL]);
921 1027 SAVE_UINT32_X(ksi, "wait", sysinfo->cpu[CPU_WAIT]);
922 1028 SAVE_UINT32_X(ksi, "wait_io", sysinfo->wait[W_IO]);
923 1029 SAVE_UINT32_X(ksi, "wait_swap", sysinfo->wait[W_SWAP]);
924 1030 SAVE_UINT32_X(ksi, "wait_pio", sysinfo->wait[W_PIO]);
925 1031 SAVE_UINT32(ksi, sysinfo, bread);
926 1032 SAVE_UINT32(ksi, sysinfo, bwrite);
927 1033 SAVE_UINT32(ksi, sysinfo, lread);
928 1034 SAVE_UINT32(ksi, sysinfo, lwrite);
929 1035 SAVE_UINT32(ksi, sysinfo, phread);
930 1036 SAVE_UINT32(ksi, sysinfo, phwrite);
931 1037 SAVE_UINT32(ksi, sysinfo, pswitch);
932 1038 SAVE_UINT32(ksi, sysinfo, trap);
933 1039 SAVE_UINT32(ksi, sysinfo, intr);
934 1040 SAVE_UINT32(ksi, sysinfo, syscall);
935 1041 SAVE_UINT32(ksi, sysinfo, sysread);
936 1042 SAVE_UINT32(ksi, sysinfo, syswrite);
937 1043 SAVE_UINT32(ksi, sysinfo, sysfork);
938 1044 SAVE_UINT32(ksi, sysinfo, sysvfork);
939 1045 SAVE_UINT32(ksi, sysinfo, sysexec);
940 1046 SAVE_UINT32(ksi, sysinfo, readch);
941 1047 SAVE_UINT32(ksi, sysinfo, writech);
942 1048 SAVE_UINT32(ksi, sysinfo, rcvint);
943 1049 SAVE_UINT32(ksi, sysinfo, xmtint);
944 1050 SAVE_UINT32(ksi, sysinfo, mdmint);
945 1051 SAVE_UINT32(ksi, sysinfo, rawch);
946 1052 SAVE_UINT32(ksi, sysinfo, canch);
947 1053 SAVE_UINT32(ksi, sysinfo, outch);
948 1054 SAVE_UINT32(ksi, sysinfo, msg);
949 1055 SAVE_UINT32(ksi, sysinfo, sema);
950 1056 SAVE_UINT32(ksi, sysinfo, namei);
951 1057 SAVE_UINT32(ksi, sysinfo, ufsiget);
952 1058 SAVE_UINT32(ksi, sysinfo, ufsdirblk);
953 1059 SAVE_UINT32(ksi, sysinfo, ufsipage);
954 1060 SAVE_UINT32(ksi, sysinfo, ufsinopage);
955 1061 SAVE_UINT32(ksi, sysinfo, inodeovf);
956 1062 SAVE_UINT32(ksi, sysinfo, fileovf);
957 1063 SAVE_UINT32(ksi, sysinfo, procovf);
958 1064 SAVE_UINT32(ksi, sysinfo, intrthread);
959 1065 SAVE_UINT32(ksi, sysinfo, intrblk);
960 1066 SAVE_UINT32(ksi, sysinfo, idlethread);
961 1067 SAVE_UINT32(ksi, sysinfo, inv_swtch);
962 1068 SAVE_UINT32(ksi, sysinfo, nthreads);
963 1069 SAVE_UINT32(ksi, sysinfo, cpumigrate);
964 1070 SAVE_UINT32(ksi, sysinfo, xcalls);
965 1071 SAVE_UINT32(ksi, sysinfo, mutex_adenters);
966 1072 SAVE_UINT32(ksi, sysinfo, rw_rdfails);
967 1073 SAVE_UINT32(ksi, sysinfo, rw_wrfails);
968 1074 SAVE_UINT32(ksi, sysinfo, modload);
969 1075 SAVE_UINT32(ksi, sysinfo, modunload);
970 1076 SAVE_UINT32(ksi, sysinfo, bawrite);
971 1077 #ifdef STATISTICS /* see header file */
972 1078 SAVE_UINT32(ksi, sysinfo, rw_enters);
973 1079 SAVE_UINT32(ksi, sysinfo, win_uo_cnt);
974 1080 SAVE_UINT32(ksi, sysinfo, win_uu_cnt);
975 1081 SAVE_UINT32(ksi, sysinfo, win_so_cnt);
976 1082 SAVE_UINT32(ksi, sysinfo, win_su_cnt);
977 1083 SAVE_UINT32(ksi, sysinfo, win_suo_cnt);
978 1084 #endif
979 1085
980 1086 SAVE_INT32(ksi, syswait, iowait);
981 1087 SAVE_INT32(ksi, syswait, swap);
982 1088 SAVE_INT32(ksi, syswait, physio);
983 1089
984 1090 SAVE_UINT32(ksi, vminfo, pgrec);
985 1091 SAVE_UINT32(ksi, vminfo, pgfrec);
986 1092 SAVE_UINT32(ksi, vminfo, pgin);
987 1093 SAVE_UINT32(ksi, vminfo, pgpgin);
988 1094 SAVE_UINT32(ksi, vminfo, pgout);
989 1095 SAVE_UINT32(ksi, vminfo, pgpgout);
990 1096 SAVE_UINT32(ksi, vminfo, swapin);
991 1097 SAVE_UINT32(ksi, vminfo, pgswapin);
992 1098 SAVE_UINT32(ksi, vminfo, swapout);
993 1099 SAVE_UINT32(ksi, vminfo, pgswapout);
994 1100 SAVE_UINT32(ksi, vminfo, zfod);
995 1101 SAVE_UINT32(ksi, vminfo, dfree);
996 1102 SAVE_UINT32(ksi, vminfo, scan);
997 1103 SAVE_UINT32(ksi, vminfo, rev);
998 1104 SAVE_UINT32(ksi, vminfo, hat_fault);
999 1105 SAVE_UINT32(ksi, vminfo, as_fault);
1000 1106 SAVE_UINT32(ksi, vminfo, maj_fault);
1001 1107 SAVE_UINT32(ksi, vminfo, cow_fault);
1002 1108 SAVE_UINT32(ksi, vminfo, prot_fault);
1003 1109 SAVE_UINT32(ksi, vminfo, softlock);
1004 1110 SAVE_UINT32(ksi, vminfo, kernel_asflt);
1005 1111 SAVE_UINT32(ksi, vminfo, pgrrun);
1006 1112 SAVE_UINT32(ksi, vminfo, execpgin);
1007 1113 SAVE_UINT32(ksi, vminfo, execpgout);
1008 1114 SAVE_UINT32(ksi, vminfo, execfree);
1009 1115 SAVE_UINT32(ksi, vminfo, anonpgin);
1010 1116 SAVE_UINT32(ksi, vminfo, anonpgout);
1011 1117 SAVE_UINT32(ksi, vminfo, anonfree);
1012 1118 SAVE_UINT32(ksi, vminfo, fspgin);
1013 1119 SAVE_UINT32(ksi, vminfo, fspgout);
1014 1120 SAVE_UINT32(ksi, vminfo, fsfree);
1015 1121 }
1016 1122
1017 1123 static void
1018 1124 save_var(kstat_t *kp, ks_instance_t *ksi)
1019 1125 {
1020 1126 struct var *var = (struct var *)(kp->ks_data);
1021 1127
1022 1128 assert(kp->ks_data_size == sizeof (struct var));
1023 1129
1024 1130 SAVE_INT32(ksi, var, v_buf);
1025 1131 SAVE_INT32(ksi, var, v_call);
1026 1132 SAVE_INT32(ksi, var, v_proc);
1027 1133 SAVE_INT32(ksi, var, v_maxupttl);
1028 1134 SAVE_INT32(ksi, var, v_nglobpris);
1029 1135 SAVE_INT32(ksi, var, v_maxsyspri);
1030 1136 SAVE_INT32(ksi, var, v_clist);
1031 1137 SAVE_INT32(ksi, var, v_maxup);
1032 1138 SAVE_INT32(ksi, var, v_hbuf);
1033 1139 SAVE_INT32(ksi, var, v_hmask);
1034 1140 SAVE_INT32(ksi, var, v_pbuf);
1035 1141 SAVE_INT32(ksi, var, v_sptmap);
1036 1142 SAVE_INT32(ksi, var, v_maxpmem);
1037 1143 SAVE_INT32(ksi, var, v_autoup);
1038 1144 SAVE_INT32(ksi, var, v_bufhwm);
1039 1145 }
1040 1146
1041 1147 static void
1042 1148 save_ncstats(kstat_t *kp, ks_instance_t *ksi)
1043 1149 {
1044 1150 struct ncstats *ncstats = (struct ncstats *)(kp->ks_data);
1045 1151
1046 1152 assert(kp->ks_data_size == sizeof (struct ncstats));
1047 1153
1048 1154 SAVE_INT32(ksi, ncstats, hits);
1049 1155 SAVE_INT32(ksi, ncstats, misses);
1050 1156 SAVE_INT32(ksi, ncstats, enters);
1051 1157 SAVE_INT32(ksi, ncstats, dbl_enters);
1052 1158 SAVE_INT32(ksi, ncstats, long_enter);
1053 1159 SAVE_INT32(ksi, ncstats, long_look);
1054 1160 SAVE_INT32(ksi, ncstats, move_to_front);
1055 1161 SAVE_INT32(ksi, ncstats, purges);
1056 1162 }
1057 1163
1058 1164 static void
1059 1165 save_sysinfo(kstat_t *kp, ks_instance_t *ksi)
1060 1166 {
1061 1167 sysinfo_t *sysinfo = (sysinfo_t *)(kp->ks_data);
1062 1168
1063 1169 assert(kp->ks_data_size == sizeof (sysinfo_t));
1064 1170
1065 1171 SAVE_UINT32(ksi, sysinfo, updates);
1066 1172 SAVE_UINT32(ksi, sysinfo, runque);
1067 1173 SAVE_UINT32(ksi, sysinfo, runocc);
1068 1174 SAVE_UINT32(ksi, sysinfo, swpque);
1069 1175 SAVE_UINT32(ksi, sysinfo, swpocc);
1070 1176 SAVE_UINT32(ksi, sysinfo, waiting);
1071 1177 }
1072 1178
1073 1179 static void
1074 1180 save_vminfo(kstat_t *kp, ks_instance_t *ksi)
1075 1181 {
1076 1182 vminfo_t *vminfo = (vminfo_t *)(kp->ks_data);
1077 1183
1078 1184 assert(kp->ks_data_size == sizeof (vminfo_t));
1079 1185
1080 1186 SAVE_UINT64(ksi, vminfo, freemem);
1081 1187 SAVE_UINT64(ksi, vminfo, swap_resv);
1082 1188 SAVE_UINT64(ksi, vminfo, swap_alloc);
1083 1189 SAVE_UINT64(ksi, vminfo, swap_avail);
1084 1190 SAVE_UINT64(ksi, vminfo, swap_free);
1085 1191 SAVE_UINT64(ksi, vminfo, updates);
1086 1192 }
1087 1193
1088 1194 static void
1089 1195 save_nfs(kstat_t *kp, ks_instance_t *ksi)
1090 1196 {
1091 1197 struct mntinfo_kstat *mntinfo = (struct mntinfo_kstat *)(kp->ks_data);
1092 1198
1093 1199 assert(kp->ks_data_size == sizeof (struct mntinfo_kstat));
1094 1200
1095 1201 SAVE_STRING(ksi, mntinfo, mik_proto);
1096 1202 SAVE_UINT32(ksi, mntinfo, mik_vers);
1097 1203 SAVE_UINT32(ksi, mntinfo, mik_flags);
1098 1204 SAVE_UINT32(ksi, mntinfo, mik_secmod);
1099 1205 SAVE_UINT32(ksi, mntinfo, mik_curread);
1100 1206 SAVE_UINT32(ksi, mntinfo, mik_curwrite);
1101 1207 SAVE_INT32(ksi, mntinfo, mik_timeo);
1102 1208 SAVE_INT32(ksi, mntinfo, mik_retrans);
1103 1209 SAVE_UINT32(ksi, mntinfo, mik_acregmin);
1104 1210 SAVE_UINT32(ksi, mntinfo, mik_acregmax);
1105 1211 SAVE_UINT32(ksi, mntinfo, mik_acdirmin);
1106 1212 SAVE_UINT32(ksi, mntinfo, mik_acdirmax);
1107 1213 SAVE_UINT32_X(ksi, "lookup_srtt", mntinfo->mik_timers[0].srtt);
1108 1214 SAVE_UINT32_X(ksi, "lookup_deviate", mntinfo->mik_timers[0].deviate);
1109 1215 SAVE_UINT32_X(ksi, "lookup_rtxcur", mntinfo->mik_timers[0].rtxcur);
1110 1216 SAVE_UINT32_X(ksi, "read_srtt", mntinfo->mik_timers[1].srtt);
1111 1217 SAVE_UINT32_X(ksi, "read_deviate", mntinfo->mik_timers[1].deviate);
1112 1218 SAVE_UINT32_X(ksi, "read_rtxcur", mntinfo->mik_timers[1].rtxcur);
1113 1219 SAVE_UINT32_X(ksi, "write_srtt", mntinfo->mik_timers[2].srtt);
1114 1220 SAVE_UINT32_X(ksi, "write_deviate", mntinfo->mik_timers[2].deviate);
1115 1221 SAVE_UINT32_X(ksi, "write_rtxcur", mntinfo->mik_timers[2].rtxcur);
1116 1222 SAVE_UINT32(ksi, mntinfo, mik_noresponse);
1117 1223 SAVE_UINT32(ksi, mntinfo, mik_failover);
1118 1224 SAVE_UINT32(ksi, mntinfo, mik_remap);
1119 1225 SAVE_STRING(ksi, mntinfo, mik_curserver);
1120 1226 }
1121 1227
1122 1228 #ifdef __sparc
1123 1229 static void
1124 1230 save_sfmmu_global_stat(kstat_t *kp, ks_instance_t *ksi)
1125 1231 {
1126 1232 struct sfmmu_global_stat *sfmmug =
1127 1233 (struct sfmmu_global_stat *)(kp->ks_data);
1128 1234
1129 1235 assert(kp->ks_data_size == sizeof (struct sfmmu_global_stat));
1130 1236
1131 1237 SAVE_INT32(ksi, sfmmug, sf_tsb_exceptions);
1132 1238 SAVE_INT32(ksi, sfmmug, sf_tsb_raise_exception);
1133 1239 SAVE_INT32(ksi, sfmmug, sf_pagefaults);
1134 1240 SAVE_INT32(ksi, sfmmug, sf_uhash_searches);
1135 1241 SAVE_INT32(ksi, sfmmug, sf_uhash_links);
1136 1242 SAVE_INT32(ksi, sfmmug, sf_khash_searches);
1137 1243 SAVE_INT32(ksi, sfmmug, sf_khash_links);
1138 1244 SAVE_INT32(ksi, sfmmug, sf_swapout);
1139 1245 SAVE_INT32(ksi, sfmmug, sf_tsb_alloc);
1140 1246 SAVE_INT32(ksi, sfmmug, sf_tsb_allocfail);
1141 1247 SAVE_INT32(ksi, sfmmug, sf_tsb_sectsb_create);
1142 1248 SAVE_INT32(ksi, sfmmug, sf_scd_1sttsb_alloc);
1143 1249 SAVE_INT32(ksi, sfmmug, sf_scd_2ndtsb_alloc);
1144 1250 SAVE_INT32(ksi, sfmmug, sf_scd_1sttsb_allocfail);
1145 1251 SAVE_INT32(ksi, sfmmug, sf_scd_2ndtsb_allocfail);
1146 1252 SAVE_INT32(ksi, sfmmug, sf_tteload8k);
1147 1253 SAVE_INT32(ksi, sfmmug, sf_tteload64k);
1148 1254 SAVE_INT32(ksi, sfmmug, sf_tteload512k);
1149 1255 SAVE_INT32(ksi, sfmmug, sf_tteload4m);
1150 1256 SAVE_INT32(ksi, sfmmug, sf_tteload32m);
1151 1257 SAVE_INT32(ksi, sfmmug, sf_tteload256m);
1152 1258 SAVE_INT32(ksi, sfmmug, sf_tsb_load8k);
1153 1259 SAVE_INT32(ksi, sfmmug, sf_tsb_load4m);
1154 1260 SAVE_INT32(ksi, sfmmug, sf_hblk_hit);
1155 1261 SAVE_INT32(ksi, sfmmug, sf_hblk8_ncreate);
1156 1262 SAVE_INT32(ksi, sfmmug, sf_hblk8_nalloc);
1157 1263 SAVE_INT32(ksi, sfmmug, sf_hblk1_ncreate);
1158 1264 SAVE_INT32(ksi, sfmmug, sf_hblk1_nalloc);
1159 1265 SAVE_INT32(ksi, sfmmug, sf_hblk_slab_cnt);
1160 1266 SAVE_INT32(ksi, sfmmug, sf_hblk_reserve_cnt);
1161 1267 SAVE_INT32(ksi, sfmmug, sf_hblk_recurse_cnt);
1162 1268 SAVE_INT32(ksi, sfmmug, sf_hblk_reserve_hit);
1163 1269 SAVE_INT32(ksi, sfmmug, sf_get_free_success);
1164 1270 SAVE_INT32(ksi, sfmmug, sf_get_free_throttle);
1165 1271 SAVE_INT32(ksi, sfmmug, sf_get_free_fail);
1166 1272 SAVE_INT32(ksi, sfmmug, sf_put_free_success);
1167 1273 SAVE_INT32(ksi, sfmmug, sf_put_free_fail);
1168 1274 SAVE_INT32(ksi, sfmmug, sf_pgcolor_conflict);
1169 1275 SAVE_INT32(ksi, sfmmug, sf_uncache_conflict);
1170 1276 SAVE_INT32(ksi, sfmmug, sf_unload_conflict);
1171 1277 SAVE_INT32(ksi, sfmmug, sf_ism_uncache);
1172 1278 SAVE_INT32(ksi, sfmmug, sf_ism_recache);
1173 1279 SAVE_INT32(ksi, sfmmug, sf_recache);
1174 1280 SAVE_INT32(ksi, sfmmug, sf_steal_count);
1175 1281 SAVE_INT32(ksi, sfmmug, sf_pagesync);
1176 1282 SAVE_INT32(ksi, sfmmug, sf_clrwrt);
1177 1283 SAVE_INT32(ksi, sfmmug, sf_pagesync_invalid);
1178 1284 SAVE_INT32(ksi, sfmmug, sf_kernel_xcalls);
1179 1285 SAVE_INT32(ksi, sfmmug, sf_user_xcalls);
1180 1286 SAVE_INT32(ksi, sfmmug, sf_tsb_grow);
1181 1287 SAVE_INT32(ksi, sfmmug, sf_tsb_shrink);
1182 1288 SAVE_INT32(ksi, sfmmug, sf_tsb_resize_failures);
1183 1289 SAVE_INT32(ksi, sfmmug, sf_tsb_reloc);
1184 1290 SAVE_INT32(ksi, sfmmug, sf_user_vtop);
1185 1291 SAVE_INT32(ksi, sfmmug, sf_ctx_inv);
1186 1292 SAVE_INT32(ksi, sfmmug, sf_tlb_reprog_pgsz);
1187 1293 SAVE_INT32(ksi, sfmmug, sf_region_remap_demap);
1188 1294 SAVE_INT32(ksi, sfmmug, sf_create_scd);
1189 1295 SAVE_INT32(ksi, sfmmug, sf_join_scd);
1190 1296 SAVE_INT32(ksi, sfmmug, sf_leave_scd);
1191 1297 SAVE_INT32(ksi, sfmmug, sf_destroy_scd);
1192 1298 }
1193 1299 #endif
1194 1300
1195 1301 #ifdef __sparc
1196 1302 static void
1197 1303 save_sfmmu_tsbsize_stat(kstat_t *kp, ks_instance_t *ksi)
1198 1304 {
1199 1305 struct sfmmu_tsbsize_stat *sfmmut;
1200 1306
1201 1307 assert(kp->ks_data_size == sizeof (struct sfmmu_tsbsize_stat));
1202 1308 sfmmut = (struct sfmmu_tsbsize_stat *)(kp->ks_data);
1203 1309
1204 1310 SAVE_INT32(ksi, sfmmut, sf_tsbsz_8k);
1205 1311 SAVE_INT32(ksi, sfmmut, sf_tsbsz_16k);
1206 1312 SAVE_INT32(ksi, sfmmut, sf_tsbsz_32k);
1207 1313 SAVE_INT32(ksi, sfmmut, sf_tsbsz_64k);
1208 1314 SAVE_INT32(ksi, sfmmut, sf_tsbsz_128k);
1209 1315 SAVE_INT32(ksi, sfmmut, sf_tsbsz_256k);
1210 1316 SAVE_INT32(ksi, sfmmut, sf_tsbsz_512k);
1211 1317 SAVE_INT32(ksi, sfmmut, sf_tsbsz_1m);
1212 1318 SAVE_INT32(ksi, sfmmut, sf_tsbsz_2m);
1213 1319 SAVE_INT32(ksi, sfmmut, sf_tsbsz_4m);
1214 1320 }
1215 1321 #endif
1216 1322
1217 1323 #ifdef __sparc
1218 1324 static void
1219 1325 save_simmstat(kstat_t *kp, ks_instance_t *ksi)
1220 1326 {
1221 1327 uchar_t *simmstat;
1222 1328 char *simm_buf;
1223 1329 char *list = NULL;
1224 1330 int i;
1225 1331
1226 1332 assert(kp->ks_data_size == sizeof (uchar_t) * SIMM_COUNT);
1227 1333
1228 1334 for (i = 0, simmstat = (uchar_t *)(kp->ks_data); i < SIMM_COUNT - 1;
1229 1335 i++, simmstat++) {
1230 1336 if (list == NULL) {
1231 1337 (void) asprintf(&simm_buf, "%d,", *simmstat);
1232 1338 } else {
1233 1339 (void) asprintf(&simm_buf, "%s%d,", list, *simmstat);
1234 1340 free(list);
1235 1341 }
1236 1342 list = simm_buf;
1237 1343 }
1238 1344
1239 1345 (void) asprintf(&simm_buf, "%s%d", list, *simmstat);
1240 1346 SAVE_STRING_X(ksi, "status", simm_buf);
1241 1347 free(list);
1242 1348 free(simm_buf);
1243 1349 }
1244 1350 #endif
1245 1351
1246 1352 #ifdef __sparc
1247 1353 /*
1248 1354 * Helper function for save_temperature().
1249 1355 */
1250 1356 static char *
1251 1357 short_array_to_string(short *shortp, int len)
1252 1358 {
1253 1359 char *list = NULL;
1254 1360 char *list_buf;
1255 1361
1256 1362 for (; len > 1; len--, shortp++) {
1257 1363 if (list == NULL) {
1258 1364 (void) asprintf(&list_buf, "%hd,", *shortp);
1259 1365 } else {
1260 1366 (void) asprintf(&list_buf, "%s%hd,", list, *shortp);
1261 1367 free(list);
1262 1368 }
1263 1369 list = list_buf;
1264 1370 }
1265 1371
1266 1372 (void) asprintf(&list_buf, "%s%hd", list, *shortp);
1267 1373 free(list);
1268 1374 return (list_buf);
1269 1375 }
1270 1376
1271 1377 static void
1272 1378 save_temperature(kstat_t *kp, ks_instance_t *ksi)
1273 1379 {
1274 1380 struct temp_stats *temps = (struct temp_stats *)(kp->ks_data);
1275 1381 char *buf;
1276 1382
1277 1383 assert(kp->ks_data_size == sizeof (struct temp_stats));
1278 1384
1279 1385 SAVE_UINT32(ksi, temps, index);
1280 1386
1281 1387 buf = short_array_to_string(temps->l1, L1_SZ);
1282 1388 SAVE_STRING_X(ksi, "l1", buf);
1283 1389 free(buf);
1284 1390
1285 1391 buf = short_array_to_string(temps->l2, L2_SZ);
1286 1392 SAVE_STRING_X(ksi, "l2", buf);
1287 1393 free(buf);
1288 1394
1289 1395 buf = short_array_to_string(temps->l3, L3_SZ);
1290 1396 SAVE_STRING_X(ksi, "l3", buf);
1291 1397 free(buf);
1292 1398
1293 1399 buf = short_array_to_string(temps->l4, L4_SZ);
1294 1400 SAVE_STRING_X(ksi, "l4", buf);
1295 1401 free(buf);
1296 1402
1297 1403 buf = short_array_to_string(temps->l5, L5_SZ);
1298 1404 SAVE_STRING_X(ksi, "l5", buf);
1299 1405 free(buf);
1300 1406
1301 1407 SAVE_INT32(ksi, temps, max);
1302 1408 SAVE_INT32(ksi, temps, min);
1303 1409 SAVE_INT32(ksi, temps, state);
1304 1410 SAVE_INT32(ksi, temps, temp_cnt);
1305 1411 SAVE_INT32(ksi, temps, shutdown_cnt);
1306 1412 SAVE_INT32(ksi, temps, version);
1307 1413 SAVE_INT32(ksi, temps, trend);
1308 1414 SAVE_INT32(ksi, temps, override);
1309 1415 }
1310 1416 #endif
1311 1417
1312 1418 #ifdef __sparc
1313 1419 static void
1314 1420 save_temp_over(kstat_t *kp, ks_instance_t *ksi)
1315 1421 {
1316 1422 short *sh = (short *)(kp->ks_data);
1317 1423 char *value;
1318 1424
1319 1425 assert(kp->ks_data_size == sizeof (short));
1320 1426
1321 1427 (void) asprintf(&value, "%hu", *sh);
1322 1428 SAVE_STRING_X(ksi, "override", value);
1323 1429 free(value);
1324 1430 }
1325 1431 #endif
1326 1432
1327 1433 #ifdef __sparc
1328 1434 static void
1329 1435 save_ps_shadow(kstat_t *kp, ks_instance_t *ksi)
1330 1436 {
1331 1437 uchar_t *uchar = (uchar_t *)(kp->ks_data);
1332 1438
1333 1439 assert(kp->ks_data_size == SYS_PS_COUNT);
1334 1440
1335 1441 SAVE_CHAR_X(ksi, "core_0", *uchar++);
1336 1442 SAVE_CHAR_X(ksi, "core_1", *uchar++);
1337 1443 SAVE_CHAR_X(ksi, "core_2", *uchar++);
1338 1444 SAVE_CHAR_X(ksi, "core_3", *uchar++);
1339 1445 SAVE_CHAR_X(ksi, "core_4", *uchar++);
1340 1446 SAVE_CHAR_X(ksi, "core_5", *uchar++);
1341 1447 SAVE_CHAR_X(ksi, "core_6", *uchar++);
1342 1448 SAVE_CHAR_X(ksi, "core_7", *uchar++);
1343 1449 SAVE_CHAR_X(ksi, "pps_0", *uchar++);
1344 1450 SAVE_CHAR_X(ksi, "clk_33", *uchar++);
1345 1451 SAVE_CHAR_X(ksi, "clk_50", *uchar++);
1346 1452 SAVE_CHAR_X(ksi, "v5_p", *uchar++);
1347 1453 SAVE_CHAR_X(ksi, "v12_p", *uchar++);
1348 1454 SAVE_CHAR_X(ksi, "v5_aux", *uchar++);
1349 1455 SAVE_CHAR_X(ksi, "v5_p_pch", *uchar++);
1350 1456 SAVE_CHAR_X(ksi, "v12_p_pch", *uchar++);
1351 1457 SAVE_CHAR_X(ksi, "v3_pch", *uchar++);
1352 1458 SAVE_CHAR_X(ksi, "v5_pch", *uchar++);
1353 1459 SAVE_CHAR_X(ksi, "p_fan", *uchar++);
1354 1460 }
1355 1461 #endif
1356 1462
1357 1463 #ifdef __sparc
1358 1464 static void
1359 1465 save_fault_list(kstat_t *kp, ks_instance_t *ksi)
1360 1466 {
1361 1467 struct ft_list *fault;
1362 1468 char name[KSTAT_STRLEN + 7];
1363 1469 int i;
1364 1470
1365 1471 for (i = 1, fault = (struct ft_list *)(kp->ks_data);
1366 1472 i <= 999999 && i <= kp->ks_data_size / sizeof (struct ft_list);
1367 1473 i++, fault++) {
1368 1474 (void) snprintf(name, sizeof (name), "unit_%d", i);
1369 1475 SAVE_INT32_X(ksi, name, fault->unit);
1370 1476 (void) snprintf(name, sizeof (name), "type_%d", i);
1371 1477 SAVE_INT32_X(ksi, name, fault->type);
1372 1478 (void) snprintf(name, sizeof (name), "fclass_%d", i);
1373 1479 SAVE_INT32_X(ksi, name, fault->fclass);
1374 1480 (void) snprintf(name, sizeof (name), "create_time_%d", i);
1375 1481 SAVE_HRTIME_X(ksi, name, fault->create_time);
1376 1482 (void) snprintf(name, sizeof (name), "msg_%d", i);
1377 1483 SAVE_STRING_X(ksi, name, fault->msg);
1378 1484 }
1379 1485 }
1380 1486 #endif
↓ open down ↓ |
570 lines elided |
↑ open up ↑ |
1381 1487
1382 1488 static void
1383 1489 save_named(kstat_t *kp, ks_instance_t *ksi)
1384 1490 {
1385 1491 kstat_named_t *knp;
1386 1492 int n;
1387 1493
1388 1494 for (n = kp->ks_ndata, knp = KSTAT_NAMED_PTR(kp); n > 0; n--, knp++) {
1389 1495 switch (knp->data_type) {
1390 1496 case KSTAT_DATA_CHAR:
1391 - nvpair_insert(ksi, knp->name,
1392 - (ks_value_t *)&knp->value, KSTAT_DATA_CHAR);
1393 - break;
1394 1497 case KSTAT_DATA_INT32:
1395 - nvpair_insert(ksi, knp->name,
1396 - (ks_value_t *)&knp->value, KSTAT_DATA_INT32);
1397 - break;
1398 1498 case KSTAT_DATA_UINT32:
1399 - nvpair_insert(ksi, knp->name,
1400 - (ks_value_t *)&knp->value, KSTAT_DATA_UINT32);
1401 - break;
1402 1499 case KSTAT_DATA_INT64:
1403 - nvpair_insert(ksi, knp->name,
1404 - (ks_value_t *)&knp->value, KSTAT_DATA_INT64);
1405 - break;
1406 1500 case KSTAT_DATA_UINT64:
1501 + case KSTAT_DATA_TIME:
1407 1502 nvpair_insert(ksi, knp->name,
1408 - (ks_value_t *)&knp->value, KSTAT_DATA_UINT64);
1503 + (ks_value_t *)&knp->value, knp->data_type);
1409 1504 break;
1410 1505 case KSTAT_DATA_STRING:
1411 1506 SAVE_STRING_X(ksi, knp->name, KSTAT_NAMED_STR_PTR(knp));
1412 1507 break;
1413 1508 default:
1414 1509 assert(B_FALSE); /* Invalid data type */
1415 1510 break;
1416 1511 }
1417 1512 }
1418 1513 }
1419 1514
1420 1515 static void
1421 1516 save_intr(kstat_t *kp, ks_instance_t *ksi)
1422 1517 {
1423 1518 kstat_intr_t *intr = KSTAT_INTR_PTR(kp);
1424 1519 char *intr_names[] = {"hard", "soft", "watchdog", "spurious",
1425 1520 "multiple_service"};
1426 1521 int n;
1427 1522
1428 1523 for (n = 0; n < KSTAT_NUM_INTRS; n++)
1429 1524 SAVE_UINT32_X(ksi, intr_names[n], intr->intrs[n]);
1430 1525 }
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
1431 1526
1432 1527 static void
1433 1528 save_io(kstat_t *kp, ks_instance_t *ksi)
1434 1529 {
1435 1530 kstat_io_t *ksio = KSTAT_IO_PTR(kp);
1436 1531
1437 1532 SAVE_UINT64(ksi, ksio, nread);
1438 1533 SAVE_UINT64(ksi, ksio, nwritten);
1439 1534 SAVE_UINT32(ksi, ksio, reads);
1440 1535 SAVE_UINT32(ksi, ksio, writes);
1441 - SAVE_HRTIME(ksi, ksio, wtime);
1442 - SAVE_HRTIME(ksi, ksio, wlentime);
1536 + SAVE_UINT64(ksi, ksio, wtime);
1537 + SAVE_UINT64(ksi, ksio, wlentime);
1443 1538 SAVE_HRTIME(ksi, ksio, wlastupdate);
1444 - SAVE_HRTIME(ksi, ksio, rtime);
1445 - SAVE_HRTIME(ksi, ksio, rlentime);
1539 + SAVE_UINT64(ksi, ksio, rtime);
1540 + SAVE_UINT64(ksi, ksio, rlentime);
1446 1541 SAVE_HRTIME(ksi, ksio, rlastupdate);
1447 1542 SAVE_UINT32(ksi, ksio, wcnt);
1448 1543 SAVE_UINT32(ksi, ksio, rcnt);
1449 1544 }
1450 1545
1451 1546 static void
1452 1547 save_timer(kstat_t *kp, ks_instance_t *ksi)
1453 1548 {
1454 1549 kstat_timer_t *ktimer = KSTAT_TIMER_PTR(kp);
1455 1550
1456 1551 SAVE_STRING(ksi, ktimer, name);
1457 1552 SAVE_UINT64(ksi, ktimer, num_events);
1458 - SAVE_HRTIME(ksi, ktimer, elapsed_time);
1459 - SAVE_HRTIME(ksi, ktimer, min_time);
1460 - SAVE_HRTIME(ksi, ktimer, max_time);
1553 + SAVE_UINT64(ksi, ktimer, elapsed_time);
1554 + SAVE_UINT64(ksi, ktimer, min_time);
1555 + SAVE_UINT64(ksi, ktimer, max_time);
1461 1556 SAVE_HRTIME(ksi, ktimer, start_time);
1462 1557 SAVE_HRTIME(ksi, ktimer, stop_time);
1463 1558 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX