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