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