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 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Copyright 2012 David Hoeppner. All rights reserved.
24 */
25
26 #ifndef _STAT_KSTAT_H
27 #define _STAT_KSTAT_H
28
29 /*
30 * Structures needed by the kstat reader functions.
31 */
32 #include <sys/var.h>
33 #include <sys/utsname.h>
34 #include <sys/sysinfo.h>
35 #include <sys/flock.h>
36 #include <sys/dnlc.h>
37 #include <nfs/nfs.h>
38 #include <nfs/nfs_clnt.h>
39
40 #ifdef __sparc
41 #include <vm/hat_sfmmu.h>
42 #include <sys/simmstat.h>
43 #include <sys/sysctrl.h>
44 #include <sys/fhc.h>
45 #endif
46
47 #define KSTAT_DATA_HRTIME (KSTAT_DATA_STRING + 1)
48
49 typedef union ks_value {
50 char c[16];
51 int32_t i32;
52 uint32_t ui32;
53 struct {
54 union {
55 char *ptr;
56 char __pad[8];
57 } addr;
58 uint32_t len;
59 } str;
60
61 int64_t i64;
62 uint64_t ui64;
63 } ks_value_t;
64
65 #define SAVE_HRTIME(I, S, N) \
66 { \
67 ks_value_t v; \
68 v.ui64 = S->N; \
69 nvpair_insert(I, #N, &v, KSTAT_DATA_UINT64); \
70 }
71
72 #define SAVE_INT32(I, S, N) \
73 { \
74 ks_value_t v; \
75 v.i32 = S->N; \
76 nvpair_insert(I, #N, &v, KSTAT_DATA_INT32); \
77 }
78
79 #define SAVE_UINT32(I, S, N) \
80 { \
81 ks_value_t v; \
82 v.ui32 = S->N; \
83 nvpair_insert(I, #N, &v, KSTAT_DATA_UINT32); \
84 }
85
86 #define SAVE_INT64(I, S, N) \
87 { \
88 ks_value_t v; \
89 v.i64 = S->N; \
90 nvpair_insert(I, #N, &v, KSTAT_DATA_INT64); \
91 }
92
93 #define SAVE_UINT64(I, S, N) \
94 { \
95 ks_value_t v; \
96 v.ui64 = S->N; \
97 nvpair_insert(I, #N, &v, KSTAT_DATA_UINT64); \
98 }
99
100 /*
101 * We dont want const "strings" because we free
102 * the instances later.
103 */
104 #define SAVE_STRING(I, S, N) \
105 { \
106 ks_value_t v; \
107 v.str.addr.ptr = safe_strdup(S->N); \
108 v.str.len = strlen(S->N); \
109 nvpair_insert(I, #N, &v, KSTAT_DATA_STRING); \
110 }
111
112 #define SAVE_HRTIME_X(I, N, V) \
113 { \
114 ks_value_t v; \
115 v.ui64 = V; \
116 nvpair_insert(I, N, &v, KSTAT_DATA_HRTIME); \
117 }
118
119 #define SAVE_INT32_X(I, N, V) \
120 { \
121 ks_value_t v; \
122 v.i32 = V; \
123 nvpair_insert(I, N, &v, KSTAT_DATA_INT32); \
124 }
125
126 #define SAVE_UINT32_X(I, N, V) \
127 { \
128 ks_value_t v; \
129 v.ui32 = V; \
130 nvpair_insert(I, N, &v, KSTAT_DATA_UINT32); \
131 }
132
133 #define SAVE_UINT64_X(I, N, V) \
134 { \
135 ks_value_t v; \
136 v.ui64 = V; \
137 nvpair_insert(I, N, &v, KSTAT_DATA_UINT64); \
138 }
139
140 #define SAVE_STRING_X(I, N, V) \
141 { \
142 ks_value_t v; \
143 v.str.addr.ptr = safe_strdup(V); \
144 v.str.len = strlen(V); \
145 nvpair_insert(I, N, &v, KSTAT_DATA_STRING); \
146 }
147
148 #define SAVE_CHAR_X(I, N, V) \
149 { \
150 ks_value_t v; \
151 asprintf(&v.str.addr.ptr, "%c", V); \
152 v.str.len = 1; \
153 nvpair_insert(I, N, &v, KSTAT_DATA_STRING); \
154 }
155
156 #define DFLT_FMT \
157 "module: %-30.30s instance: %-6d\n" \
158 "name: %-30.30s class: %-.30s\n"
159
160 #define JSON_FMT \
161 "{\n\t\"module\": \"%s\",\n" \
162 "\t\"instance\": %d,\n" \
163 "\t\"name\": \"%s\",\n" \
164 "\t\"class\": \"%s\",\n" \
165 "\t\"type\": %d,\n"
166
167 #define KS_DFMT "\t%-30s "
168 #define KS_JFMT "\t\t\"%s\": "
169 #define KS_PFMT "%s:%d:%s:%s"
170
171 typedef struct ks_instance {
172 list_node_t ks_next;
173 char ks_name[KSTAT_STRLEN];
174 char ks_module[KSTAT_STRLEN];
175 char ks_class[KSTAT_STRLEN];
176 int ks_instance;
177 uchar_t ks_type;
178 hrtime_t ks_snaptime;
179 list_t ks_nvlist;
180 } ks_instance_t;
181
182 typedef struct ks_nvpair {
183 list_node_t nv_next;
184 char name[KSTAT_STRLEN];
185 uchar_t data_type;
186 ks_value_t value;
187 } ks_nvpair_t;
188
189 typedef struct ks_selector {
190 list_node_t ks_next;
191 char *ks_module;
192 char *ks_instance;
193 char *ks_name;
194 char *ks_statistic;
195 } ks_selector_t;
196
197 static void usage(void);
198 static int compare_instances(ks_instance_t *, ks_instance_t *);
199 static void nvpair_insert(ks_instance_t *, char *, ks_value_t *, uchar_t);
200 static ks_selector_t *new_selector(void);
201 static void ks_instances_read(kstat_ctl_t *);
202 static void ks_value_print(ks_nvpair_t *);
203 static void ks_instance_print(ks_instance_t *, ks_nvpair_t *);
204 static void ks_instances_print(void);
205 static char *ks_safe_strdup(char *);
206 static void ks_sleep_until(hrtime_t *, hrtime_t, int, int *);
207
208 /* Raw kstat readers */
209 static void save_cpu_stat(kstat_t *, ks_instance_t *);
210 static void save_var(kstat_t *, ks_instance_t *);
211 static void save_ncstats(kstat_t *, ks_instance_t *);
212 static void save_sysinfo(kstat_t *, ks_instance_t *);
213 static void save_vminfo(kstat_t *, ks_instance_t *);
214 static void save_nfs(kstat_t *, ks_instance_t *);
215 #ifdef __sparc
216 static void save_sfmmu_global_stat(kstat_t *, ks_instance_t *);
217 static void save_sfmmu_tsbsize_stat(kstat_t *, ks_instance_t *);
218 static void save_simmstat(kstat_t *, ks_instance_t *);
219 /* Helper function for save_temperature() */
220 static char *short_array_to_string(short *, int);
221 static void save_temperature(kstat_t *, ks_instance_t *);
222 static void save_temp_over(kstat_t *, ks_instance_t *);
223 static void save_ps_shadow(kstat_t *, ks_instance_t *);
224 static void save_fault_list(kstat_t *, ks_instance_t *);
225 #endif
226
227 /* Named kstat readers */
228 static void save_named(kstat_t *, ks_instance_t *);
229 static void save_intr(kstat_t *, ks_instance_t *);
230 static void save_io(kstat_t *, ks_instance_t *);
231 static void save_timer(kstat_t *, ks_instance_t *);
232
233 /* Typedef for raw kstat reader functions */
234 typedef void (*kstat_raw_reader_t)(kstat_t *, ks_instance_t *);
235
236 static struct {
237 kstat_raw_reader_t fn;
238 char *name;
239 } ks_raw_lookup[] = {
240 /* Function name kstat name */
241 {save_cpu_stat, "cpu_stat:cpu_stat"},
242 {save_var, "unix:var"},
243 {save_ncstats, "unix:ncstats"},
244 {save_sysinfo, "unix:sysinfo"},
245 {save_vminfo, "unix:vminfo"},
246 {save_nfs, "nfs:mntinfo"},
247 #ifdef __sparc
248 {save_sfmmu_global_stat, "unix:sfmmu_global_stat"},
249 {save_sfmmu_tsbsize_stat, "unix:sfmmu_tsbsize_stat"},
250 {save_simmstat, "unix:simm-status"},
251 {save_temperature, "unix:temperature"},
252 {save_temp_over, "unix:temperature override"},
253 {save_ps_shadow, "unix:ps_shadow"},
254 {save_fault_list, "unix:fault_list"},
255 #endif
256 {NULL, NULL},
257 };
258
259 static kstat_raw_reader_t lookup_raw_kstat_fn(char *, char *);
260
261 #endif /* _STAT_KSTAT_H */