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