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