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 = strlen(V); \ 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