xref: /illumos-gate/usr/src/cmd/stat/kstat/kstat.h (revision 20a7641f9918de8574b8b3b47dbe35c4bfc78df1)
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  * Copyright 2020 Peter Tribble.
26  */
27 
28 #ifndef _STAT_KSTAT_H
29 #define	_STAT_KSTAT_H
30 
31 /*
32  * Structures needed by the kstat reader functions.
33  */
34 #include <sys/var.h>
35 #include <sys/utsname.h>
36 #include <sys/sysinfo.h>
37 #include <sys/flock.h>
38 #include <sys/dnlc.h>
39 #include <regex.h>
40 #include <nfs/nfs.h>
41 #include <nfs/nfs_clnt.h>
42 
43 #ifdef __sparc
44 #include <vm/hat_sfmmu.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 = (V) ? strlen(V) : 0;		\
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 	(void) 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	KS_DFMT	"\t%-30s  "
161 #define	KS_PFMT	"%s:%d:%s:%s"
162 
163 typedef struct ks_instance {
164 	list_node_t	ks_next;
165 	char		ks_name[KSTAT_STRLEN];
166 	char		ks_module[KSTAT_STRLEN];
167 	char		ks_class[KSTAT_STRLEN];
168 	int		ks_instance;
169 	uchar_t		ks_type;
170 	hrtime_t	ks_snaptime;
171 	list_t		ks_nvlist;
172 } ks_instance_t;
173 
174 typedef struct ks_nvpair {
175 	list_node_t	nv_next;
176 	char		name[KSTAT_STRLEN];
177 	uchar_t		data_type;
178 	ks_value_t	value;
179 } ks_nvpair_t;
180 
181 typedef struct ks_pattern {
182 	char		*pstr;
183 	regex_t		preg;
184 } ks_pattern_t;
185 
186 typedef struct ks_selector {
187 	list_node_t	ks_next;
188 	ks_pattern_t	ks_module;
189 	ks_pattern_t	ks_instance;
190 	ks_pattern_t	ks_name;
191 	ks_pattern_t	ks_statistic;
192 } ks_selector_t;
193 
194 static void	usage(void);
195 static int	compare_instances(ks_instance_t *, ks_instance_t *);
196 static void	nvpair_insert(ks_instance_t *, char *, ks_value_t *, uchar_t);
197 static boolean_t	ks_match(const char *, ks_pattern_t *);
198 static ks_selector_t	*new_selector(void);
199 static void	ks_instances_read(kstat_ctl_t *);
200 static void	ks_value_print(ks_nvpair_t *);
201 static void	ks_instances_print(void);
202 static char	*ks_safe_strdup(char *);
203 static void	ks_sleep_until(hrtime_t *, hrtime_t, int, int *);
204 
205 /* Raw kstat readers */
206 static void	save_cpu_stat(kstat_t *, ks_instance_t *);
207 static void	save_var(kstat_t *, ks_instance_t *);
208 static void	save_ncstats(kstat_t *, ks_instance_t *);
209 static void	save_sysinfo(kstat_t *, ks_instance_t *);
210 static void	save_vminfo(kstat_t *, ks_instance_t *);
211 static void	save_nfs(kstat_t *, ks_instance_t *);
212 #ifdef __sparc
213 static void	save_sfmmu_global_stat(kstat_t *, ks_instance_t *);
214 static void	save_sfmmu_tsbsize_stat(kstat_t *, ks_instance_t *);
215 #endif
216 
217 /* Named kstat readers */
218 static void	save_named(kstat_t *, ks_instance_t *);
219 static void	save_intr(kstat_t *, ks_instance_t *);
220 static void	save_io(kstat_t *, ks_instance_t *);
221 static void	save_timer(kstat_t *, ks_instance_t *);
222 
223 /* Typedef for raw kstat reader functions */
224 typedef void	(*kstat_raw_reader_t)(kstat_t *, ks_instance_t *);
225 
226 static struct {
227 	kstat_raw_reader_t fn;
228 	char *name;
229 } ks_raw_lookup[] = {
230 	/* Function name		kstat name		*/
231 	{save_cpu_stat,			"cpu_stat:cpu_stat"},
232 	{save_var,			"unix:var"},
233 	{save_ncstats,			"unix:ncstats"},
234 	{save_sysinfo,			"unix:sysinfo"},
235 	{save_vminfo,			"unix:vminfo"},
236 	{save_nfs,			"nfs:mntinfo"},
237 #ifdef __sparc
238 	{save_sfmmu_global_stat,	"unix:sfmmu_global_stat"},
239 	{save_sfmmu_tsbsize_stat,	"unix:sfmmu_tsbsize_stat"},
240 #endif
241 	{NULL, NULL},
242 };
243 
244 static kstat_raw_reader_t	lookup_raw_kstat_fn(char *, char *);
245 
246 #endif /* _STAT_KSTAT_H */
247