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