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.
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.
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]
23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013 David Hoeppner. All rights reserved.
25 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
26 * Copyright 2016 Joyent, Inc.
30 * Display kernel statistics
32 * This is a reimplementation of the perl kstat command originally found
33 * under usr/src/cmd/kstat/kstat.pl
36 * - perl regular expressions replaced with extended REs bracketed by '/'
39 * -C similar to the -p option but value is separated by a colon
62 #include <sys/types.h>
65 #include "statcommon.h"
67 char *cmdname
= "kstat"; /* Name of this command */
68 int caught_cont
= 0; /* Have caught a SIGCONT */
70 static uint_t g_timestamp_fmt
= NODATE
;
72 /* Helper flag - header was printed already? */
73 static boolean_t g_headerflg
;
75 /* Saved command line options */
76 static boolean_t g_cflg
= B_FALSE
;
77 static boolean_t g_jflg
= B_FALSE
;
78 static boolean_t g_lflg
= B_FALSE
;
79 static boolean_t g_pflg
= B_FALSE
;
80 static boolean_t g_qflg
= B_FALSE
;
81 static ks_pattern_t g_ks_class
= {"*", 0};
83 static boolean_t g_matched
= B_FALSE
;
85 /* Sorted list of kstat instances */
86 static list_t instances_list
;
87 static list_t selector_list
;
90 main(int argc
, char **argv
)
92 ks_selector_t
*nselector
;
93 ks_selector_t
*uselector
;
97 boolean_t errflg
= B_FALSE
;
98 boolean_t nselflg
= B_FALSE
;
99 boolean_t uselflg
= B_FALSE
;
102 int infinite_cycles
= 0;
107 (void) setlocale(LC_ALL
, "");
108 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
109 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
111 (void) textdomain(TEXT_DOMAIN
);
114 * Create the selector list and a dummy default selector to match
115 * everything. While we process the cmdline options we will add
116 * selectors to this list.
118 list_create(&selector_list
, sizeof (ks_selector_t
),
119 offsetof(ks_selector_t
, ks_next
));
121 nselector
= new_selector();
124 * Parse named command line arguments.
126 while ((c
= getopt(argc
, argv
, "h?CqjlpT:m:i:n:s:c:")) != EOF
)
134 g_pflg
= g_cflg
= B_TRUE
;
141 * If we're printing JSON, we're going to force numeric
142 * representation to be in the C locale to assure that
143 * the decimal point is compliant with RFC 7159 (i.e.,
146 (void) setlocale(LC_NUMERIC
, "C");
150 g_pflg
= g_lflg
= B_TRUE
;
158 g_timestamp_fmt
= DDATE
;
161 g_timestamp_fmt
= UDATE
;
169 nselector
->ks_module
.pstr
=
170 (char *)ks_safe_strdup(optarg
);
174 nselector
->ks_instance
.pstr
=
175 (char *)ks_safe_strdup(optarg
);
179 nselector
->ks_name
.pstr
=
180 (char *)ks_safe_strdup(optarg
);
184 nselector
->ks_statistic
.pstr
=
185 (char *)ks_safe_strdup(optarg
);
189 (char *)ks_safe_strdup(optarg
);
196 if (g_qflg
&& (g_jflg
|| g_pflg
)) {
197 (void) fprintf(stderr
, gettext(
198 "-q and -lpj are mutually exclusive\n"));
211 * Consume the rest of the command line. Parsing the
212 * unnamed command line arguments.
216 tmp
= strtoul(*argv
, &q
, 10);
217 if (tmp
== ULONG_MAX
&& errno
== ERANGE
) {
219 (void) fprintf(stderr
, gettext(
220 "Interval is too large\n"));
222 (void) fprintf(stderr
, gettext(
223 "Count is too large\n"));
229 if (errno
!= 0 || *q
!= '\0') {
231 uselector
= new_selector();
232 while ((q
= (char *)strsep(argv
, ":")) != NULL
) {
243 uselector
->ks_module
.pstr
=
244 (char *)ks_safe_strdup(q
);
247 uselector
->ks_instance
.pstr
=
248 (char *)ks_safe_strdup(q
);
251 uselector
->ks_name
.pstr
=
252 (char *)ks_safe_strdup(q
);
255 uselector
->ks_statistic
.pstr
=
256 (char *)ks_safe_strdup(q
);
265 list_insert_tail(&selector_list
, uselector
);
269 (void) fprintf(stderr
, gettext(
270 "Interval must be an "
273 (void) fprintf(stderr
, gettext(
274 "Count must be an integer >= 1"));
295 * Check if we founded a named selector on the cmdline.
299 (void) fprintf(stderr
, gettext(
300 "[module[:instance[:name[:statistic]]]] and "
301 "-m -i -n -s are mutually exclusive"));
308 list_insert_tail(&selector_list
, nselector
);
311 assert(!list_is_empty(&selector_list
));
313 list_create(&instances_list
, sizeof (ks_instance_t
),
314 offsetof(ks_instance_t
, ks_next
));
316 while ((kc
= kstat_open()) == NULL
) {
317 if (errno
== EAGAIN
) {
318 (void) poll(NULL
, 0, 200);
320 perror("kstat_open");
326 if (signal(SIGCONT
, cont_handler
) == SIG_ERR
) {
327 (void) fprintf(stderr
, gettext(
333 period_n
= (hrtime_t
)interval
* NANOSEC
;
334 start_n
= gethrtime();
336 while (count
== -1 || count
-- > 0) {
337 ks_instances_read(kc
);
338 ks_instances_print();
340 if (interval
&& count
) {
341 ks_sleep_until(&start_n
, period_n
, infinite_cycles
,
343 (void) kstat_chain_update(kc
);
344 (void) putchar('\n');
348 (void) kstat_close(kc
);
351 * Return a non-zero exit code if we didn't match anything.
353 return (g_matched
? 0 : 1);
362 (void) fprintf(stderr
, gettext(
364 "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ]\n"
365 " [ -m module ] [ -i instance ] [ -n name ] [ -s statistic ]\n"
366 " [ interval [ count ] ]\n"
367 "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ]\n"
368 " [ module[:instance[:name[:statistic]]] ... ]\n"
369 " [ interval [ count ] ]\n"));
373 * Sort compare function.
376 compare_instances(ks_instance_t
*l_arg
, ks_instance_t
*r_arg
)
380 rval
= strcasecmp(l_arg
->ks_module
, r_arg
->ks_module
);
382 if (l_arg
->ks_instance
== r_arg
->ks_instance
) {
383 return (strcasecmp(l_arg
->ks_name
, r_arg
->ks_name
));
384 } else if (l_arg
->ks_instance
< r_arg
->ks_instance
) {
395 ks_safe_strdup(char *str
)
403 while ((ret
= strdup(str
)) == NULL
) {
404 if (errno
== EAGAIN
) {
405 (void) poll(NULL
, 0, 200);
416 ks_sleep_until(hrtime_t
*wakeup
, hrtime_t interval
, int forever
,
419 hrtime_t now
, pause
, pause_left
;
420 struct timespec pause_tv
;
424 pause
= *wakeup
+ interval
- now
;
426 if (pause
<= 0 || pause
< (interval
/ 4)) {
427 if (forever
|| *caught_cont
) {
428 *wakeup
= now
+ interval
;
431 pause
= interval
/ 2;
444 pause_tv
.tv_sec
= pause_left
/ NANOSEC
;
445 pause_tv
.tv_nsec
= pause_left
% NANOSEC
;
446 status
= nanosleep(&pause_tv
, (struct timespec
*)NULL
);
448 if (errno
== EINTR
) {
450 pause_left
= *wakeup
- now
;
451 if (pause_left
< 1000) {
459 } while (status
!= 0);
463 * Inserts an instance in the per selector list.
466 nvpair_insert(ks_instance_t
*ksi
, char *name
, ks_value_t
*value
,
469 ks_nvpair_t
*instance
;
472 instance
= (ks_nvpair_t
*)malloc(sizeof (ks_nvpair_t
));
473 if (instance
== NULL
) {
478 (void) strlcpy(instance
->name
, name
, KSTAT_STRLEN
);
479 (void) memcpy(&instance
->value
, value
, sizeof (ks_value_t
));
480 instance
->data_type
= data_type
;
482 tmp
= list_head(&ksi
->ks_nvlist
);
483 while (tmp
!= NULL
&& strcasecmp(instance
->name
, tmp
->name
) > 0)
484 tmp
= list_next(&ksi
->ks_nvlist
, tmp
);
486 list_insert_before(&ksi
->ks_nvlist
, tmp
, instance
);
490 * Allocates a new all-matching selector.
492 static ks_selector_t
*
495 ks_selector_t
*selector
;
497 selector
= (ks_selector_t
*)malloc(sizeof (ks_selector_t
));
498 if (selector
== NULL
) {
503 list_link_init(&selector
->ks_next
);
505 selector
->ks_module
.pstr
= "*";
506 selector
->ks_instance
.pstr
= "*";
507 selector
->ks_name
.pstr
= "*";
508 selector
->ks_statistic
.pstr
= "*";
514 * This function was taken from the perl kstat module code - please
515 * see for further comments there.
517 static kstat_raw_reader_t
518 lookup_raw_kstat_fn(char *module
, char *name
)
520 char key
[KSTAT_STRLEN
* 2];
521 register char *f
, *t
;
524 for (f
= module
, t
= key
; *f
!= '\0'; f
++, t
++) {
525 while (*f
!= '\0' && isdigit(*f
))
531 for (f
= name
; *f
!= '\0'; f
++, t
++) {
532 while (*f
!= '\0' && isdigit(*f
))
538 while (ks_raw_lookup
[n
].fn
!= NULL
) {
539 if (strncmp(ks_raw_lookup
[n
].name
, key
, strlen(key
)) == 0)
540 return (ks_raw_lookup
[n
].fn
);
548 * Match a string against a shell glob or extended regular expression.
551 ks_match(const char *str
, ks_pattern_t
*pattern
)
558 if (pattern
->pstr
!= NULL
&& gmatch(pattern
->pstr
, "/*/") != 0) {
559 /* All regex patterns are strdup'd copies */
560 regstr
= pattern
->pstr
+ 1;
561 *(strrchr(regstr
, '/')) = '\0';
563 regcode
= regcomp(&pattern
->preg
, regstr
,
564 REG_EXTENDED
| REG_NOSUB
);
566 bufsz
= regerror(regcode
, NULL
, NULL
, 0);
568 errbuf
= malloc(bufsz
);
569 if (errbuf
== NULL
) {
573 (void) regerror(regcode
, NULL
, errbuf
, bufsz
);
574 (void) fprintf(stderr
, "kstat: %s\n", errbuf
);
580 pattern
->pstr
= NULL
;
583 if (pattern
->pstr
== NULL
) {
584 return (regexec(&pattern
->preg
, str
, 0, NULL
, 0) == 0);
587 return ((gmatch(str
, pattern
->pstr
) != 0));
591 * Iterate over all kernel statistics and save matches.
594 ks_instances_read(kstat_ctl_t
*kc
)
596 kstat_raw_reader_t save_raw
= NULL
;
598 ks_selector_t
*selector
;
604 for (kp
= kc
->kc_chain
; kp
!= NULL
; kp
= kp
->ks_next
) {
605 /* Don't bother storing the kstat headers */
606 if (strncmp(kp
->ks_name
, "kstat_", 6) == 0) {
610 /* Don't bother storing raw stats we don't understand */
611 if (kp
->ks_type
== KSTAT_TYPE_RAW
) {
612 save_raw
= lookup_raw_kstat_fn(kp
->ks_module
,
614 if (save_raw
== NULL
) {
615 #ifdef REPORT_UNKNOWN
616 (void) fprintf(stderr
,
617 "Unknown kstat type %s:%d:%s - "
618 "%d of size %d\n", kp
->ks_module
,
619 kp
->ks_instance
, kp
->ks_name
,
620 kp
->ks_ndata
, kp
->ks_data_size
);
627 * Iterate over the list of selectors and skip
628 * instances we dont want. We filter for statistics
629 * later, as we dont know them yet.
632 selector
= list_head(&selector_list
);
633 while (selector
!= NULL
) {
634 if (ks_match(kp
->ks_module
, &selector
->ks_module
) &&
635 ks_match(kp
->ks_name
, &selector
->ks_name
)) {
639 selector
= list_next(&selector_list
, selector
);
647 * Allocate a new instance and fill in the values
650 ksi
= (ks_instance_t
*)malloc(sizeof (ks_instance_t
));
656 list_link_init(&ksi
->ks_next
);
658 (void) strlcpy(ksi
->ks_module
, kp
->ks_module
, KSTAT_STRLEN
);
659 (void) strlcpy(ksi
->ks_name
, kp
->ks_name
, KSTAT_STRLEN
);
660 (void) strlcpy(ksi
->ks_class
, kp
->ks_class
, KSTAT_STRLEN
);
662 ksi
->ks_instance
= kp
->ks_instance
;
663 ksi
->ks_snaptime
= kp
->ks_snaptime
;
664 ksi
->ks_type
= kp
->ks_type
;
666 list_create(&ksi
->ks_nvlist
, sizeof (ks_nvpair_t
),
667 offsetof(ks_nvpair_t
, nv_next
));
669 SAVE_HRTIME_X(ksi
, "crtime", kp
->ks_crtime
);
671 SAVE_STRING_X(ksi
, "class", kp
->ks_class
);
674 /* Insert this instance into a sorted list */
675 tmp
= list_head(&instances_list
);
676 while (tmp
!= NULL
&& compare_instances(ksi
, tmp
) > 0)
677 tmp
= list_next(&instances_list
, tmp
);
679 list_insert_before(&instances_list
, tmp
, ksi
);
681 /* Read the actual statistics */
682 id
= kstat_read(kc
, kp
, NULL
);
684 #ifdef REPORT_UNKNOWN
685 perror("kstat_read");
690 SAVE_HRTIME_X(ksi
, "snaptime", kp
->ks_snaptime
);
692 switch (kp
->ks_type
) {
696 case KSTAT_TYPE_NAMED
:
699 case KSTAT_TYPE_INTR
:
705 case KSTAT_TYPE_TIMER
:
709 assert(B_FALSE
); /* Invalid type */
716 * Print the value of a name-value pair.
719 ks_value_print(ks_nvpair_t
*nvpair
)
721 switch (nvpair
->data_type
) {
722 case KSTAT_DATA_CHAR
:
723 (void) fprintf(stdout
, "%s", nvpair
->value
.c
);
725 case KSTAT_DATA_INT32
:
726 (void) fprintf(stdout
, "%d", nvpair
->value
.i32
);
728 case KSTAT_DATA_UINT32
:
729 (void) fprintf(stdout
, "%u", nvpair
->value
.ui32
);
731 case KSTAT_DATA_INT64
:
732 (void) fprintf(stdout
, "%lld", nvpair
->value
.i64
);
734 case KSTAT_DATA_UINT64
:
735 (void) fprintf(stdout
, "%llu", nvpair
->value
.ui64
);
737 case KSTAT_DATA_STRING
:
738 (void) fprintf(stdout
, "%s", KSTAT_NAMED_STR_PTR(nvpair
));
740 case KSTAT_DATA_HRTIME
:
741 if (nvpair
->value
.ui64
== 0)
742 (void) fprintf(stdout
, "0");
744 (void) fprintf(stdout
, "%.9f",
745 nvpair
->value
.ui64
/ 1000000000.0);
753 * Print a single instance.
757 ks_instance_print(ks_instance_t
*ksi
, ks_nvpair_t
*nvpair
, boolean_t last
)
761 (void) fprintf(stdout
, DFLT_FMT
,
762 ksi
->ks_module
, ksi
->ks_instance
,
763 ksi
->ks_name
, ksi
->ks_class
);
765 g_headerflg
= B_FALSE
;
769 (void) fprintf(stdout
, KS_PFMT
,
770 ksi
->ks_module
, ksi
->ks_instance
,
771 ksi
->ks_name
, nvpair
->name
);
773 (void) putchar(g_cflg
? ':': '\t');
774 ks_value_print(nvpair
);
777 (void) fprintf(stdout
, KS_DFMT
, nvpair
->name
);
778 ks_value_print(nvpair
);
781 (void) putchar('\n');
785 * Print a C string as a JSON string.
788 ks_print_json_string(const char *str
)
794 while ((c
= *str
++) != '\0') {
796 * For readability, we use the allowed alternate escape
797 * sequence for quote, question mark, reverse solidus (look
798 * it up!), newline and tab -- and use the universal escape
799 * sequence for all other control characters.
805 (void) fprintf(stdout
, "\\%c", c
);
809 (void) fprintf(stdout
, "\\n");
813 (void) fprintf(stdout
, "\\t");
818 * By escaping those characters for which isprint(3C)
819 * is false, we escape both the RFC 7159 mandated
820 * escaped range of 0x01 through 0x1f as well as DEL
821 * (0x7f -- the control character that RFC 7159 forgot)
822 * and then everything else that's unprintable for
826 (void) fprintf(stdout
, "\\u%04hhx", (uint8_t)c
);
839 * Print a single instance in JSON format.
842 ks_instance_print_json(ks_instance_t
*ksi
, ks_nvpair_t
*nvpair
, boolean_t last
)
848 (void) fprintf(stdout
, ", ");
850 (void) fprintf(stdout
, "{\n\t\"module\": ");
851 ks_print_json_string(ksi
->ks_module
);
853 (void) fprintf(stdout
,
854 ",\n\t\"instance\": %d,\n\t\"name\": ", ksi
->ks_instance
);
855 ks_print_json_string(ksi
->ks_name
);
857 (void) fprintf(stdout
, ",\n\t\"class\": ");
858 ks_print_json_string(ksi
->ks_class
);
860 (void) fprintf(stdout
, ",\n\t\"type\": %d,\n", ksi
->ks_type
);
862 if (ksi
->ks_snaptime
== 0)
863 (void) fprintf(stdout
, "\t\"snaptime\": 0,\n");
865 (void) fprintf(stdout
, "\t\"snaptime\": %.9f,\n",
866 ksi
->ks_snaptime
/ 1000000000.0);
868 (void) fprintf(stdout
, "\t\"data\": {\n");
870 g_headerflg
= B_FALSE
;
873 (void) fprintf(stdout
, "\t\t");
874 ks_print_json_string(nvpair
->name
);
875 (void) fprintf(stdout
, ": ");
877 switch (nvpair
->data_type
) {
878 case KSTAT_DATA_CHAR
:
879 ks_print_json_string(nvpair
->value
.c
);
882 case KSTAT_DATA_STRING
:
883 ks_print_json_string(KSTAT_NAMED_STR_PTR(nvpair
));
887 ks_value_print(nvpair
);
894 (void) putchar('\n');
898 * Print all instances.
901 ks_instances_print(void)
903 ks_selector_t
*selector
;
904 ks_instance_t
*ksi
, *ktmp
;
905 ks_nvpair_t
*nvpair
, *ntmp
, *next
;
906 void (*ks_print_fn
)(ks_instance_t
*, ks_nvpair_t
*, boolean_t
);
909 if (g_timestamp_fmt
!= NODATE
)
910 print_timestamp(g_timestamp_fmt
);
913 ks_print_fn
= &ks_instance_print_json
;
916 ks_print_fn
= &ks_instance_print
;
919 /* Iterate over each selector */
920 selector
= list_head(&selector_list
);
921 while (selector
!= NULL
) {
923 /* Iterate over each instance */
924 for (ksi
= list_head(&instances_list
); ksi
!= NULL
;
925 ksi
= list_next(&instances_list
, ksi
)) {
927 (void) asprintf(&ks_number
, "%d", ksi
->ks_instance
);
928 if (!(ks_match(ksi
->ks_module
, &selector
->ks_module
) &&
929 ks_match(ksi
->ks_name
, &selector
->ks_name
) &&
930 ks_match(ks_number
, &selector
->ks_instance
) &&
931 ks_match(ksi
->ks_class
, &g_ks_class
))) {
938 g_headerflg
= B_TRUE
;
941 * Find our first statistic to print.
943 for (nvpair
= list_head(&ksi
->ks_nvlist
);
945 nvpair
= list_next(&ksi
->ks_nvlist
, nvpair
)) {
946 if (ks_match(nvpair
->name
,
947 &selector
->ks_statistic
))
951 while (nvpair
!= NULL
) {
955 * Find the next statistic to print so we can
956 * indicate to the print function if this
957 * statistic is the last to be printed for
960 for (next
= list_next(&ksi
->ks_nvlist
, nvpair
);
962 next
= list_next(&ksi
->ks_nvlist
, next
)) {
963 if (ks_match(next
->name
,
964 &selector
->ks_statistic
))
969 last
= next
== NULL
? B_TRUE
: B_FALSE
;
972 (*ks_print_fn
)(ksi
, nvpair
, last
);
979 (void) fprintf(stdout
, "\t}\n}");
980 } else if (!g_pflg
) {
981 (void) putchar('\n');
986 selector
= list_next(&selector_list
, selector
);
990 (void) fprintf(stdout
, "]\n");
992 (void) fflush(stdout
);
994 /* Free the instances list */
995 ksi
= list_head(&instances_list
);
996 while (ksi
!= NULL
) {
997 nvpair
= list_head(&ksi
->ks_nvlist
);
998 while (nvpair
!= NULL
) {
1000 nvpair
= list_next(&ksi
->ks_nvlist
, nvpair
);
1001 list_remove(&ksi
->ks_nvlist
, ntmp
);
1002 if (ntmp
->data_type
== KSTAT_DATA_STRING
)
1003 free(ntmp
->value
.str
.addr
.ptr
);
1008 ksi
= list_next(&instances_list
, ksi
);
1009 list_remove(&instances_list
, ktmp
);
1010 list_destroy(&ktmp
->ks_nvlist
);
1016 save_cpu_stat(kstat_t
*kp
, ks_instance_t
*ksi
)
1019 cpu_sysinfo_t
*sysinfo
;
1020 cpu_syswait_t
*syswait
;
1021 cpu_vminfo_t
*vminfo
;
1023 stat
= (cpu_stat_t
*)(kp
->ks_data
);
1024 sysinfo
= &stat
->cpu_sysinfo
;
1025 syswait
= &stat
->cpu_syswait
;
1026 vminfo
= &stat
->cpu_vminfo
;
1028 SAVE_UINT32_X(ksi
, "idle", sysinfo
->cpu
[CPU_IDLE
]);
1029 SAVE_UINT32_X(ksi
, "user", sysinfo
->cpu
[CPU_USER
]);
1030 SAVE_UINT32_X(ksi
, "kernel", sysinfo
->cpu
[CPU_KERNEL
]);
1031 SAVE_UINT32_X(ksi
, "wait", sysinfo
->cpu
[CPU_WAIT
]);
1032 SAVE_UINT32_X(ksi
, "wait_io", sysinfo
->wait
[W_IO
]);
1033 SAVE_UINT32_X(ksi
, "wait_swap", sysinfo
->wait
[W_SWAP
]);
1034 SAVE_UINT32_X(ksi
, "wait_pio", sysinfo
->wait
[W_PIO
]);
1035 SAVE_UINT32(ksi
, sysinfo
, bread
);
1036 SAVE_UINT32(ksi
, sysinfo
, bwrite
);
1037 SAVE_UINT32(ksi
, sysinfo
, lread
);
1038 SAVE_UINT32(ksi
, sysinfo
, lwrite
);
1039 SAVE_UINT32(ksi
, sysinfo
, phread
);
1040 SAVE_UINT32(ksi
, sysinfo
, phwrite
);
1041 SAVE_UINT32(ksi
, sysinfo
, pswitch
);
1042 SAVE_UINT32(ksi
, sysinfo
, trap
);
1043 SAVE_UINT32(ksi
, sysinfo
, intr
);
1044 SAVE_UINT32(ksi
, sysinfo
, syscall
);
1045 SAVE_UINT32(ksi
, sysinfo
, sysread
);
1046 SAVE_UINT32(ksi
, sysinfo
, syswrite
);
1047 SAVE_UINT32(ksi
, sysinfo
, sysfork
);
1048 SAVE_UINT32(ksi
, sysinfo
, sysvfork
);
1049 SAVE_UINT32(ksi
, sysinfo
, sysexec
);
1050 SAVE_UINT32(ksi
, sysinfo
, readch
);
1051 SAVE_UINT32(ksi
, sysinfo
, writech
);
1052 SAVE_UINT32(ksi
, sysinfo
, rcvint
);
1053 SAVE_UINT32(ksi
, sysinfo
, xmtint
);
1054 SAVE_UINT32(ksi
, sysinfo
, mdmint
);
1055 SAVE_UINT32(ksi
, sysinfo
, rawch
);
1056 SAVE_UINT32(ksi
, sysinfo
, canch
);
1057 SAVE_UINT32(ksi
, sysinfo
, outch
);
1058 SAVE_UINT32(ksi
, sysinfo
, msg
);
1059 SAVE_UINT32(ksi
, sysinfo
, sema
);
1060 SAVE_UINT32(ksi
, sysinfo
, namei
);
1061 SAVE_UINT32(ksi
, sysinfo
, ufsiget
);
1062 SAVE_UINT32(ksi
, sysinfo
, ufsdirblk
);
1063 SAVE_UINT32(ksi
, sysinfo
, ufsipage
);
1064 SAVE_UINT32(ksi
, sysinfo
, ufsinopage
);
1065 SAVE_UINT32(ksi
, sysinfo
, inodeovf
);
1066 SAVE_UINT32(ksi
, sysinfo
, fileovf
);
1067 SAVE_UINT32(ksi
, sysinfo
, procovf
);
1068 SAVE_UINT32(ksi
, sysinfo
, intrthread
);
1069 SAVE_UINT32(ksi
, sysinfo
, intrblk
);
1070 SAVE_UINT32(ksi
, sysinfo
, idlethread
);
1071 SAVE_UINT32(ksi
, sysinfo
, inv_swtch
);
1072 SAVE_UINT32(ksi
, sysinfo
, nthreads
);
1073 SAVE_UINT32(ksi
, sysinfo
, cpumigrate
);
1074 SAVE_UINT32(ksi
, sysinfo
, xcalls
);
1075 SAVE_UINT32(ksi
, sysinfo
, mutex_adenters
);
1076 SAVE_UINT32(ksi
, sysinfo
, rw_rdfails
);
1077 SAVE_UINT32(ksi
, sysinfo
, rw_wrfails
);
1078 SAVE_UINT32(ksi
, sysinfo
, modload
);
1079 SAVE_UINT32(ksi
, sysinfo
, modunload
);
1080 SAVE_UINT32(ksi
, sysinfo
, bawrite
);
1081 #ifdef STATISTICS /* see header file */
1082 SAVE_UINT32(ksi
, sysinfo
, rw_enters
);
1083 SAVE_UINT32(ksi
, sysinfo
, win_uo_cnt
);
1084 SAVE_UINT32(ksi
, sysinfo
, win_uu_cnt
);
1085 SAVE_UINT32(ksi
, sysinfo
, win_so_cnt
);
1086 SAVE_UINT32(ksi
, sysinfo
, win_su_cnt
);
1087 SAVE_UINT32(ksi
, sysinfo
, win_suo_cnt
);
1090 SAVE_INT32(ksi
, syswait
, iowait
);
1091 SAVE_INT32(ksi
, syswait
, swap
);
1092 SAVE_INT32(ksi
, syswait
, physio
);
1094 SAVE_UINT32(ksi
, vminfo
, pgrec
);
1095 SAVE_UINT32(ksi
, vminfo
, pgfrec
);
1096 SAVE_UINT32(ksi
, vminfo
, pgin
);
1097 SAVE_UINT32(ksi
, vminfo
, pgpgin
);
1098 SAVE_UINT32(ksi
, vminfo
, pgout
);
1099 SAVE_UINT32(ksi
, vminfo
, pgpgout
);
1100 SAVE_UINT32(ksi
, vminfo
, swapin
);
1101 SAVE_UINT32(ksi
, vminfo
, pgswapin
);
1102 SAVE_UINT32(ksi
, vminfo
, swapout
);
1103 SAVE_UINT32(ksi
, vminfo
, pgswapout
);
1104 SAVE_UINT32(ksi
, vminfo
, zfod
);
1105 SAVE_UINT32(ksi
, vminfo
, dfree
);
1106 SAVE_UINT32(ksi
, vminfo
, scan
);
1107 SAVE_UINT32(ksi
, vminfo
, rev
);
1108 SAVE_UINT32(ksi
, vminfo
, hat_fault
);
1109 SAVE_UINT32(ksi
, vminfo
, as_fault
);
1110 SAVE_UINT32(ksi
, vminfo
, maj_fault
);
1111 SAVE_UINT32(ksi
, vminfo
, cow_fault
);
1112 SAVE_UINT32(ksi
, vminfo
, prot_fault
);
1113 SAVE_UINT32(ksi
, vminfo
, softlock
);
1114 SAVE_UINT32(ksi
, vminfo
, kernel_asflt
);
1115 SAVE_UINT32(ksi
, vminfo
, pgrrun
);
1116 SAVE_UINT32(ksi
, vminfo
, execpgin
);
1117 SAVE_UINT32(ksi
, vminfo
, execpgout
);
1118 SAVE_UINT32(ksi
, vminfo
, execfree
);
1119 SAVE_UINT32(ksi
, vminfo
, anonpgin
);
1120 SAVE_UINT32(ksi
, vminfo
, anonpgout
);
1121 SAVE_UINT32(ksi
, vminfo
, anonfree
);
1122 SAVE_UINT32(ksi
, vminfo
, fspgin
);
1123 SAVE_UINT32(ksi
, vminfo
, fspgout
);
1124 SAVE_UINT32(ksi
, vminfo
, fsfree
);
1128 save_var(kstat_t
*kp
, ks_instance_t
*ksi
)
1130 struct var
*var
= (struct var
*)(kp
->ks_data
);
1132 assert(kp
->ks_data_size
== sizeof (struct var
));
1134 SAVE_INT32(ksi
, var
, v_buf
);
1135 SAVE_INT32(ksi
, var
, v_call
);
1136 SAVE_INT32(ksi
, var
, v_proc
);
1137 SAVE_INT32(ksi
, var
, v_maxupttl
);
1138 SAVE_INT32(ksi
, var
, v_nglobpris
);
1139 SAVE_INT32(ksi
, var
, v_maxsyspri
);
1140 SAVE_INT32(ksi
, var
, v_clist
);
1141 SAVE_INT32(ksi
, var
, v_maxup
);
1142 SAVE_INT32(ksi
, var
, v_hbuf
);
1143 SAVE_INT32(ksi
, var
, v_hmask
);
1144 SAVE_INT32(ksi
, var
, v_pbuf
);
1145 SAVE_INT32(ksi
, var
, v_sptmap
);
1146 SAVE_INT32(ksi
, var
, v_maxpmem
);
1147 SAVE_INT32(ksi
, var
, v_autoup
);
1148 SAVE_INT32(ksi
, var
, v_bufhwm
);
1152 save_ncstats(kstat_t
*kp
, ks_instance_t
*ksi
)
1154 struct ncstats
*ncstats
= (struct ncstats
*)(kp
->ks_data
);
1156 assert(kp
->ks_data_size
== sizeof (struct ncstats
));
1158 SAVE_INT32(ksi
, ncstats
, hits
);
1159 SAVE_INT32(ksi
, ncstats
, misses
);
1160 SAVE_INT32(ksi
, ncstats
, enters
);
1161 SAVE_INT32(ksi
, ncstats
, dbl_enters
);
1162 SAVE_INT32(ksi
, ncstats
, long_enter
);
1163 SAVE_INT32(ksi
, ncstats
, long_look
);
1164 SAVE_INT32(ksi
, ncstats
, move_to_front
);
1165 SAVE_INT32(ksi
, ncstats
, purges
);
1169 save_sysinfo(kstat_t
*kp
, ks_instance_t
*ksi
)
1171 sysinfo_t
*sysinfo
= (sysinfo_t
*)(kp
->ks_data
);
1173 assert(kp
->ks_data_size
== sizeof (sysinfo_t
));
1175 SAVE_UINT32(ksi
, sysinfo
, updates
);
1176 SAVE_UINT32(ksi
, sysinfo
, runque
);
1177 SAVE_UINT32(ksi
, sysinfo
, runocc
);
1178 SAVE_UINT32(ksi
, sysinfo
, swpque
);
1179 SAVE_UINT32(ksi
, sysinfo
, swpocc
);
1180 SAVE_UINT32(ksi
, sysinfo
, waiting
);
1184 save_vminfo(kstat_t
*kp
, ks_instance_t
*ksi
)
1186 vminfo_t
*vminfo
= (vminfo_t
*)(kp
->ks_data
);
1188 assert(kp
->ks_data_size
== sizeof (vminfo_t
));
1190 SAVE_UINT64(ksi
, vminfo
, freemem
);
1191 SAVE_UINT64(ksi
, vminfo
, swap_resv
);
1192 SAVE_UINT64(ksi
, vminfo
, swap_alloc
);
1193 SAVE_UINT64(ksi
, vminfo
, swap_avail
);
1194 SAVE_UINT64(ksi
, vminfo
, swap_free
);
1195 SAVE_UINT64(ksi
, vminfo
, updates
);
1199 save_nfs(kstat_t
*kp
, ks_instance_t
*ksi
)
1201 struct mntinfo_kstat
*mntinfo
= (struct mntinfo_kstat
*)(kp
->ks_data
);
1203 assert(kp
->ks_data_size
== sizeof (struct mntinfo_kstat
));
1205 SAVE_STRING(ksi
, mntinfo
, mik_proto
);
1206 SAVE_UINT32(ksi
, mntinfo
, mik_vers
);
1207 SAVE_UINT32(ksi
, mntinfo
, mik_flags
);
1208 SAVE_UINT32(ksi
, mntinfo
, mik_secmod
);
1209 SAVE_UINT32(ksi
, mntinfo
, mik_curread
);
1210 SAVE_UINT32(ksi
, mntinfo
, mik_curwrite
);
1211 SAVE_INT32(ksi
, mntinfo
, mik_timeo
);
1212 SAVE_INT32(ksi
, mntinfo
, mik_retrans
);
1213 SAVE_UINT32(ksi
, mntinfo
, mik_acregmin
);
1214 SAVE_UINT32(ksi
, mntinfo
, mik_acregmax
);
1215 SAVE_UINT32(ksi
, mntinfo
, mik_acdirmin
);
1216 SAVE_UINT32(ksi
, mntinfo
, mik_acdirmax
);
1217 SAVE_UINT32_X(ksi
, "lookup_srtt", mntinfo
->mik_timers
[0].srtt
);
1218 SAVE_UINT32_X(ksi
, "lookup_deviate", mntinfo
->mik_timers
[0].deviate
);
1219 SAVE_UINT32_X(ksi
, "lookup_rtxcur", mntinfo
->mik_timers
[0].rtxcur
);
1220 SAVE_UINT32_X(ksi
, "read_srtt", mntinfo
->mik_timers
[1].srtt
);
1221 SAVE_UINT32_X(ksi
, "read_deviate", mntinfo
->mik_timers
[1].deviate
);
1222 SAVE_UINT32_X(ksi
, "read_rtxcur", mntinfo
->mik_timers
[1].rtxcur
);
1223 SAVE_UINT32_X(ksi
, "write_srtt", mntinfo
->mik_timers
[2].srtt
);
1224 SAVE_UINT32_X(ksi
, "write_deviate", mntinfo
->mik_timers
[2].deviate
);
1225 SAVE_UINT32_X(ksi
, "write_rtxcur", mntinfo
->mik_timers
[2].rtxcur
);
1226 SAVE_UINT32(ksi
, mntinfo
, mik_noresponse
);
1227 SAVE_UINT32(ksi
, mntinfo
, mik_failover
);
1228 SAVE_UINT32(ksi
, mntinfo
, mik_remap
);
1229 SAVE_STRING(ksi
, mntinfo
, mik_curserver
);
1234 save_sfmmu_global_stat(kstat_t
*kp
, ks_instance_t
*ksi
)
1236 struct sfmmu_global_stat
*sfmmug
=
1237 (struct sfmmu_global_stat
*)(kp
->ks_data
);
1239 assert(kp
->ks_data_size
== sizeof (struct sfmmu_global_stat
));
1241 SAVE_INT32(ksi
, sfmmug
, sf_tsb_exceptions
);
1242 SAVE_INT32(ksi
, sfmmug
, sf_tsb_raise_exception
);
1243 SAVE_INT32(ksi
, sfmmug
, sf_pagefaults
);
1244 SAVE_INT32(ksi
, sfmmug
, sf_uhash_searches
);
1245 SAVE_INT32(ksi
, sfmmug
, sf_uhash_links
);
1246 SAVE_INT32(ksi
, sfmmug
, sf_khash_searches
);
1247 SAVE_INT32(ksi
, sfmmug
, sf_khash_links
);
1248 SAVE_INT32(ksi
, sfmmug
, sf_swapout
);
1249 SAVE_INT32(ksi
, sfmmug
, sf_tsb_alloc
);
1250 SAVE_INT32(ksi
, sfmmug
, sf_tsb_allocfail
);
1251 SAVE_INT32(ksi
, sfmmug
, sf_tsb_sectsb_create
);
1252 SAVE_INT32(ksi
, sfmmug
, sf_scd_1sttsb_alloc
);
1253 SAVE_INT32(ksi
, sfmmug
, sf_scd_2ndtsb_alloc
);
1254 SAVE_INT32(ksi
, sfmmug
, sf_scd_1sttsb_allocfail
);
1255 SAVE_INT32(ksi
, sfmmug
, sf_scd_2ndtsb_allocfail
);
1256 SAVE_INT32(ksi
, sfmmug
, sf_tteload8k
);
1257 SAVE_INT32(ksi
, sfmmug
, sf_tteload64k
);
1258 SAVE_INT32(ksi
, sfmmug
, sf_tteload512k
);
1259 SAVE_INT32(ksi
, sfmmug
, sf_tteload4m
);
1260 SAVE_INT32(ksi
, sfmmug
, sf_tteload32m
);
1261 SAVE_INT32(ksi
, sfmmug
, sf_tteload256m
);
1262 SAVE_INT32(ksi
, sfmmug
, sf_tsb_load8k
);
1263 SAVE_INT32(ksi
, sfmmug
, sf_tsb_load4m
);
1264 SAVE_INT32(ksi
, sfmmug
, sf_hblk_hit
);
1265 SAVE_INT32(ksi
, sfmmug
, sf_hblk8_ncreate
);
1266 SAVE_INT32(ksi
, sfmmug
, sf_hblk8_nalloc
);
1267 SAVE_INT32(ksi
, sfmmug
, sf_hblk1_ncreate
);
1268 SAVE_INT32(ksi
, sfmmug
, sf_hblk1_nalloc
);
1269 SAVE_INT32(ksi
, sfmmug
, sf_hblk_slab_cnt
);
1270 SAVE_INT32(ksi
, sfmmug
, sf_hblk_reserve_cnt
);
1271 SAVE_INT32(ksi
, sfmmug
, sf_hblk_recurse_cnt
);
1272 SAVE_INT32(ksi
, sfmmug
, sf_hblk_reserve_hit
);
1273 SAVE_INT32(ksi
, sfmmug
, sf_get_free_success
);
1274 SAVE_INT32(ksi
, sfmmug
, sf_get_free_throttle
);
1275 SAVE_INT32(ksi
, sfmmug
, sf_get_free_fail
);
1276 SAVE_INT32(ksi
, sfmmug
, sf_put_free_success
);
1277 SAVE_INT32(ksi
, sfmmug
, sf_put_free_fail
);
1278 SAVE_INT32(ksi
, sfmmug
, sf_pgcolor_conflict
);
1279 SAVE_INT32(ksi
, sfmmug
, sf_uncache_conflict
);
1280 SAVE_INT32(ksi
, sfmmug
, sf_unload_conflict
);
1281 SAVE_INT32(ksi
, sfmmug
, sf_ism_uncache
);
1282 SAVE_INT32(ksi
, sfmmug
, sf_ism_recache
);
1283 SAVE_INT32(ksi
, sfmmug
, sf_recache
);
1284 SAVE_INT32(ksi
, sfmmug
, sf_steal_count
);
1285 SAVE_INT32(ksi
, sfmmug
, sf_pagesync
);
1286 SAVE_INT32(ksi
, sfmmug
, sf_clrwrt
);
1287 SAVE_INT32(ksi
, sfmmug
, sf_pagesync_invalid
);
1288 SAVE_INT32(ksi
, sfmmug
, sf_kernel_xcalls
);
1289 SAVE_INT32(ksi
, sfmmug
, sf_user_xcalls
);
1290 SAVE_INT32(ksi
, sfmmug
, sf_tsb_grow
);
1291 SAVE_INT32(ksi
, sfmmug
, sf_tsb_shrink
);
1292 SAVE_INT32(ksi
, sfmmug
, sf_tsb_resize_failures
);
1293 SAVE_INT32(ksi
, sfmmug
, sf_tsb_reloc
);
1294 SAVE_INT32(ksi
, sfmmug
, sf_user_vtop
);
1295 SAVE_INT32(ksi
, sfmmug
, sf_ctx_inv
);
1296 SAVE_INT32(ksi
, sfmmug
, sf_tlb_reprog_pgsz
);
1297 SAVE_INT32(ksi
, sfmmug
, sf_region_remap_demap
);
1298 SAVE_INT32(ksi
, sfmmug
, sf_create_scd
);
1299 SAVE_INT32(ksi
, sfmmug
, sf_join_scd
);
1300 SAVE_INT32(ksi
, sfmmug
, sf_leave_scd
);
1301 SAVE_INT32(ksi
, sfmmug
, sf_destroy_scd
);
1307 save_sfmmu_tsbsize_stat(kstat_t
*kp
, ks_instance_t
*ksi
)
1309 struct sfmmu_tsbsize_stat
*sfmmut
;
1311 assert(kp
->ks_data_size
== sizeof (struct sfmmu_tsbsize_stat
));
1312 sfmmut
= (struct sfmmu_tsbsize_stat
*)(kp
->ks_data
);
1314 SAVE_INT32(ksi
, sfmmut
, sf_tsbsz_8k
);
1315 SAVE_INT32(ksi
, sfmmut
, sf_tsbsz_16k
);
1316 SAVE_INT32(ksi
, sfmmut
, sf_tsbsz_32k
);
1317 SAVE_INT32(ksi
, sfmmut
, sf_tsbsz_64k
);
1318 SAVE_INT32(ksi
, sfmmut
, sf_tsbsz_128k
);
1319 SAVE_INT32(ksi
, sfmmut
, sf_tsbsz_256k
);
1320 SAVE_INT32(ksi
, sfmmut
, sf_tsbsz_512k
);
1321 SAVE_INT32(ksi
, sfmmut
, sf_tsbsz_1m
);
1322 SAVE_INT32(ksi
, sfmmut
, sf_tsbsz_2m
);
1323 SAVE_INT32(ksi
, sfmmut
, sf_tsbsz_4m
);
1329 save_simmstat(kstat_t
*kp
, ks_instance_t
*ksi
)
1336 assert(kp
->ks_data_size
== sizeof (uchar_t
) * SIMM_COUNT
);
1338 for (i
= 0, simmstat
= (uchar_t
*)(kp
->ks_data
); i
< SIMM_COUNT
- 1;
1341 (void) asprintf(&simm_buf
, "%d,", *simmstat
);
1343 (void) asprintf(&simm_buf
, "%s%d,", list
, *simmstat
);
1349 (void) asprintf(&simm_buf
, "%s%d", list
, *simmstat
);
1350 SAVE_STRING_X(ksi
, "status", simm_buf
);
1358 * Helper function for save_temperature().
1361 short_array_to_string(short *shortp
, int len
)
1366 for (; len
> 1; len
--, shortp
++) {
1368 (void) asprintf(&list_buf
, "%hd,", *shortp
);
1370 (void) asprintf(&list_buf
, "%s%hd,", list
, *shortp
);
1376 (void) asprintf(&list_buf
, "%s%hd", list
, *shortp
);
1382 save_temperature(kstat_t
*kp
, ks_instance_t
*ksi
)
1384 struct temp_stats
*temps
= (struct temp_stats
*)(kp
->ks_data
);
1387 assert(kp
->ks_data_size
== sizeof (struct temp_stats
));
1389 SAVE_UINT32(ksi
, temps
, index
);
1391 buf
= short_array_to_string(temps
->l1
, L1_SZ
);
1392 SAVE_STRING_X(ksi
, "l1", buf
);
1395 buf
= short_array_to_string(temps
->l2
, L2_SZ
);
1396 SAVE_STRING_X(ksi
, "l2", buf
);
1399 buf
= short_array_to_string(temps
->l3
, L3_SZ
);
1400 SAVE_STRING_X(ksi
, "l3", buf
);
1403 buf
= short_array_to_string(temps
->l4
, L4_SZ
);
1404 SAVE_STRING_X(ksi
, "l4", buf
);
1407 buf
= short_array_to_string(temps
->l5
, L5_SZ
);
1408 SAVE_STRING_X(ksi
, "l5", buf
);
1411 SAVE_INT32(ksi
, temps
, max
);
1412 SAVE_INT32(ksi
, temps
, min
);
1413 SAVE_INT32(ksi
, temps
, state
);
1414 SAVE_INT32(ksi
, temps
, temp_cnt
);
1415 SAVE_INT32(ksi
, temps
, shutdown_cnt
);
1416 SAVE_INT32(ksi
, temps
, version
);
1417 SAVE_INT32(ksi
, temps
, trend
);
1418 SAVE_INT32(ksi
, temps
, override
);
1424 save_temp_over(kstat_t
*kp
, ks_instance_t
*ksi
)
1426 short *sh
= (short *)(kp
->ks_data
);
1429 assert(kp
->ks_data_size
== sizeof (short));
1431 (void) asprintf(&value
, "%hu", *sh
);
1432 SAVE_STRING_X(ksi
, "override", value
);
1439 save_ps_shadow(kstat_t
*kp
, ks_instance_t
*ksi
)
1441 uchar_t
*uchar
= (uchar_t
*)(kp
->ks_data
);
1443 assert(kp
->ks_data_size
== SYS_PS_COUNT
);
1445 SAVE_CHAR_X(ksi
, "core_0", *uchar
++);
1446 SAVE_CHAR_X(ksi
, "core_1", *uchar
++);
1447 SAVE_CHAR_X(ksi
, "core_2", *uchar
++);
1448 SAVE_CHAR_X(ksi
, "core_3", *uchar
++);
1449 SAVE_CHAR_X(ksi
, "core_4", *uchar
++);
1450 SAVE_CHAR_X(ksi
, "core_5", *uchar
++);
1451 SAVE_CHAR_X(ksi
, "core_6", *uchar
++);
1452 SAVE_CHAR_X(ksi
, "core_7", *uchar
++);
1453 SAVE_CHAR_X(ksi
, "pps_0", *uchar
++);
1454 SAVE_CHAR_X(ksi
, "clk_33", *uchar
++);
1455 SAVE_CHAR_X(ksi
, "clk_50", *uchar
++);
1456 SAVE_CHAR_X(ksi
, "v5_p", *uchar
++);
1457 SAVE_CHAR_X(ksi
, "v12_p", *uchar
++);
1458 SAVE_CHAR_X(ksi
, "v5_aux", *uchar
++);
1459 SAVE_CHAR_X(ksi
, "v5_p_pch", *uchar
++);
1460 SAVE_CHAR_X(ksi
, "v12_p_pch", *uchar
++);
1461 SAVE_CHAR_X(ksi
, "v3_pch", *uchar
++);
1462 SAVE_CHAR_X(ksi
, "v5_pch", *uchar
++);
1463 SAVE_CHAR_X(ksi
, "p_fan", *uchar
++);
1469 save_fault_list(kstat_t
*kp
, ks_instance_t
*ksi
)
1471 struct ft_list
*fault
;
1472 char name
[KSTAT_STRLEN
+ 7];
1475 for (i
= 1, fault
= (struct ft_list
*)(kp
->ks_data
);
1476 i
<= 999999 && i
<= kp
->ks_data_size
/ sizeof (struct ft_list
);
1478 (void) snprintf(name
, sizeof (name
), "unit_%d", i
);
1479 SAVE_INT32_X(ksi
, name
, fault
->unit
);
1480 (void) snprintf(name
, sizeof (name
), "type_%d", i
);
1481 SAVE_INT32_X(ksi
, name
, fault
->type
);
1482 (void) snprintf(name
, sizeof (name
), "fclass_%d", i
);
1483 SAVE_INT32_X(ksi
, name
, fault
->fclass
);
1484 (void) snprintf(name
, sizeof (name
), "create_time_%d", i
);
1485 SAVE_HRTIME_X(ksi
, name
, fault
->create_time
);
1486 (void) snprintf(name
, sizeof (name
), "msg_%d", i
);
1487 SAVE_STRING_X(ksi
, name
, fault
->msg
);
1493 save_named(kstat_t
*kp
, ks_instance_t
*ksi
)
1498 for (n
= kp
->ks_ndata
, knp
= KSTAT_NAMED_PTR(kp
); n
> 0; n
--, knp
++) {
1500 * Annoyingly, some drivers have kstats with uninitialized
1501 * members (which kstat_install(9F) is sadly powerless to
1502 * prevent, and kstat_read(3KSTAT) unfortunately does nothing
1503 * to stop). To prevent these from confusing us to be
1504 * KSTAT_DATA_CHAR statistics, we skip over them.
1506 if (knp
->name
[0] == '\0')
1509 switch (knp
->data_type
) {
1510 case KSTAT_DATA_CHAR
:
1511 nvpair_insert(ksi
, knp
->name
,
1512 (ks_value_t
*)&knp
->value
, KSTAT_DATA_CHAR
);
1514 case KSTAT_DATA_INT32
:
1515 nvpair_insert(ksi
, knp
->name
,
1516 (ks_value_t
*)&knp
->value
, KSTAT_DATA_INT32
);
1518 case KSTAT_DATA_UINT32
:
1519 nvpair_insert(ksi
, knp
->name
,
1520 (ks_value_t
*)&knp
->value
, KSTAT_DATA_UINT32
);
1522 case KSTAT_DATA_INT64
:
1523 nvpair_insert(ksi
, knp
->name
,
1524 (ks_value_t
*)&knp
->value
, KSTAT_DATA_INT64
);
1526 case KSTAT_DATA_UINT64
:
1527 nvpair_insert(ksi
, knp
->name
,
1528 (ks_value_t
*)&knp
->value
, KSTAT_DATA_UINT64
);
1530 case KSTAT_DATA_STRING
:
1531 SAVE_STRING_X(ksi
, knp
->name
, KSTAT_NAMED_STR_PTR(knp
));
1534 assert(B_FALSE
); /* Invalid data type */
1541 save_intr(kstat_t
*kp
, ks_instance_t
*ksi
)
1543 kstat_intr_t
*intr
= KSTAT_INTR_PTR(kp
);
1544 char *intr_names
[] = {"hard", "soft", "watchdog", "spurious",
1545 "multiple_service"};
1548 for (n
= 0; n
< KSTAT_NUM_INTRS
; n
++)
1549 SAVE_UINT32_X(ksi
, intr_names
[n
], intr
->intrs
[n
]);
1553 save_io(kstat_t
*kp
, ks_instance_t
*ksi
)
1555 kstat_io_t
*ksio
= KSTAT_IO_PTR(kp
);
1557 SAVE_UINT64(ksi
, ksio
, nread
);
1558 SAVE_UINT64(ksi
, ksio
, nwritten
);
1559 SAVE_UINT32(ksi
, ksio
, reads
);
1560 SAVE_UINT32(ksi
, ksio
, writes
);
1561 SAVE_HRTIME(ksi
, ksio
, wtime
);
1562 SAVE_HRTIME(ksi
, ksio
, wlentime
);
1563 SAVE_HRTIME(ksi
, ksio
, wlastupdate
);
1564 SAVE_HRTIME(ksi
, ksio
, rtime
);
1565 SAVE_HRTIME(ksi
, ksio
, rlentime
);
1566 SAVE_HRTIME(ksi
, ksio
, rlastupdate
);
1567 SAVE_UINT32(ksi
, ksio
, wcnt
);
1568 SAVE_UINT32(ksi
, ksio
, rcnt
);
1572 save_timer(kstat_t
*kp
, ks_instance_t
*ksi
)
1574 kstat_timer_t
*ktimer
= KSTAT_TIMER_PTR(kp
);
1576 SAVE_STRING(ksi
, ktimer
, name
);
1577 SAVE_UINT64(ksi
, ktimer
, num_events
);
1578 SAVE_HRTIME(ksi
, ktimer
, elapsed_time
);
1579 SAVE_HRTIME(ksi
, ktimer
, min_time
);
1580 SAVE_HRTIME(ksi
, ktimer
, max_time
);
1581 SAVE_HRTIME(ksi
, ktimer
, start_time
);
1582 SAVE_HRTIME(ksi
, ktimer
, stop_time
);