166448911SDavid Höppner /* 266448911SDavid Höppner * CDDL HEADER START 366448911SDavid Höppner * 466448911SDavid Höppner * The contents of this file are subject to the terms of the 566448911SDavid Höppner * Common Development and Distribution License (the "License"). 666448911SDavid Höppner * You may not use this file except in compliance with the License. 766448911SDavid Höppner * 866448911SDavid Höppner * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 966448911SDavid Höppner * or http://www.opensolaris.org/os/licensing. 1066448911SDavid Höppner * See the License for the specific language governing permissions 1166448911SDavid Höppner * and limitations under the License. 1266448911SDavid Höppner * 1366448911SDavid Höppner * When distributing Covered Code, include this CDDL HEADER in each 1466448911SDavid Höppner * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1566448911SDavid Höppner * If applicable, add the following below this CDDL HEADER, with the 1666448911SDavid Höppner * fields enclosed by brackets "[]" replaced with your own identifying 1766448911SDavid Höppner * information: Portions Copyright [yyyy] [name of copyright owner] 1866448911SDavid Höppner * 1966448911SDavid Höppner * CDDL HEADER END 2066448911SDavid Höppner */ 2166448911SDavid Höppner /* 2266448911SDavid Höppner * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 2366448911SDavid Höppner * Copyright 2013 David Hoeppner. All rights reserved. 2466448911SDavid Höppner * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 2566448911SDavid Höppner */ 2666448911SDavid Höppner 2766448911SDavid Höppner #ifndef _STAT_KSTAT_H 2866448911SDavid Höppner #define _STAT_KSTAT_H 2966448911SDavid Höppner 3066448911SDavid Höppner /* 3166448911SDavid Höppner * Structures needed by the kstat reader functions. 3266448911SDavid Höppner */ 3366448911SDavid Höppner #include <sys/var.h> 3466448911SDavid Höppner #include <sys/utsname.h> 3566448911SDavid Höppner #include <sys/sysinfo.h> 3666448911SDavid Höppner #include <sys/flock.h> 3766448911SDavid Höppner #include <sys/dnlc.h> 3866448911SDavid Höppner #include <regex.h> 3966448911SDavid Höppner #include <nfs/nfs.h> 4066448911SDavid Höppner #include <nfs/nfs_clnt.h> 4166448911SDavid Höppner 4266448911SDavid Höppner #ifdef __sparc 4366448911SDavid Höppner #include <vm/hat_sfmmu.h> 4466448911SDavid Höppner #include <sys/simmstat.h> 4566448911SDavid Höppner #include <sys/sysctrl.h> 4666448911SDavid Höppner #include <sys/fhc.h> 4766448911SDavid Höppner #endif 4866448911SDavid Höppner 4966448911SDavid Höppner #define KSTAT_DATA_HRTIME (KSTAT_DATA_STRING + 1) 5066448911SDavid Höppner 5166448911SDavid Höppner typedef union ks_value { 5266448911SDavid Höppner char c[16]; 5366448911SDavid Höppner int32_t i32; 5466448911SDavid Höppner uint32_t ui32; 5566448911SDavid Höppner struct { 5666448911SDavid Höppner union { 5766448911SDavid Höppner char *ptr; 5866448911SDavid Höppner char __pad[8]; 5966448911SDavid Höppner } addr; 6066448911SDavid Höppner uint32_t len; 6166448911SDavid Höppner } str; 6266448911SDavid Höppner 6366448911SDavid Höppner int64_t i64; 6466448911SDavid Höppner uint64_t ui64; 6566448911SDavid Höppner } ks_value_t; 6666448911SDavid Höppner 6766448911SDavid Höppner #define SAVE_HRTIME(I, S, N) \ 6866448911SDavid Höppner { \ 6966448911SDavid Höppner ks_value_t v; \ 7066448911SDavid Höppner v.ui64 = S->N; \ 7166448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_UINT64); \ 7266448911SDavid Höppner } 7366448911SDavid Höppner 7466448911SDavid Höppner #define SAVE_INT32(I, S, N) \ 7566448911SDavid Höppner { \ 7666448911SDavid Höppner ks_value_t v; \ 7766448911SDavid Höppner v.i32 = S->N; \ 7866448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_INT32); \ 7966448911SDavid Höppner } 8066448911SDavid Höppner 8166448911SDavid Höppner #define SAVE_UINT32(I, S, N) \ 8266448911SDavid Höppner { \ 8366448911SDavid Höppner ks_value_t v; \ 8466448911SDavid Höppner v.ui32 = S->N; \ 8566448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_UINT32); \ 8666448911SDavid Höppner } 8766448911SDavid Höppner 8866448911SDavid Höppner #define SAVE_INT64(I, S, N) \ 8966448911SDavid Höppner { \ 9066448911SDavid Höppner ks_value_t v; \ 9166448911SDavid Höppner v.i64 = S->N; \ 9266448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_INT64); \ 9366448911SDavid Höppner } 9466448911SDavid Höppner 9566448911SDavid Höppner #define SAVE_UINT64(I, S, N) \ 9666448911SDavid Höppner { \ 9766448911SDavid Höppner ks_value_t v; \ 9866448911SDavid Höppner v.ui64 = S->N; \ 9966448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_UINT64); \ 10066448911SDavid Höppner } 10166448911SDavid Höppner 10266448911SDavid Höppner /* 10366448911SDavid Höppner * We dont want const "strings" because we free 10466448911SDavid Höppner * the instances later. 10566448911SDavid Höppner */ 10666448911SDavid Höppner #define SAVE_STRING(I, S, N) \ 10766448911SDavid Höppner { \ 10866448911SDavid Höppner ks_value_t v; \ 10966448911SDavid Höppner v.str.addr.ptr = safe_strdup(S->N); \ 11066448911SDavid Höppner v.str.len = strlen(S->N); \ 11166448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_STRING); \ 11266448911SDavid Höppner } 11366448911SDavid Höppner 11466448911SDavid Höppner #define SAVE_HRTIME_X(I, N, V) \ 11566448911SDavid Höppner { \ 11666448911SDavid Höppner ks_value_t v; \ 11766448911SDavid Höppner v.ui64 = V; \ 11866448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_HRTIME); \ 11966448911SDavid Höppner } 12066448911SDavid Höppner 12166448911SDavid Höppner #define SAVE_INT32_X(I, N, V) \ 12266448911SDavid Höppner { \ 12366448911SDavid Höppner ks_value_t v; \ 12466448911SDavid Höppner v.i32 = V; \ 12566448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_INT32); \ 12666448911SDavid Höppner } 12766448911SDavid Höppner 12866448911SDavid Höppner #define SAVE_UINT32_X(I, N, V) \ 12966448911SDavid Höppner { \ 13066448911SDavid Höppner ks_value_t v; \ 13166448911SDavid Höppner v.ui32 = V; \ 13266448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_UINT32); \ 13366448911SDavid Höppner } 13466448911SDavid Höppner 13566448911SDavid Höppner #define SAVE_UINT64_X(I, N, V) \ 13666448911SDavid Höppner { \ 13766448911SDavid Höppner ks_value_t v; \ 13866448911SDavid Höppner v.ui64 = V; \ 13966448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_UINT64); \ 14066448911SDavid Höppner } 14166448911SDavid Höppner 14266448911SDavid Höppner #define SAVE_STRING_X(I, N, V) \ 14366448911SDavid Höppner { \ 14466448911SDavid Höppner ks_value_t v; \ 14566448911SDavid Höppner v.str.addr.ptr = safe_strdup(V); \ 146*861bfc89STheo Schlossnagle v.str.len = (V) ? strlen(V) : 0; \ 14766448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_STRING); \ 14866448911SDavid Höppner } 14966448911SDavid Höppner 15066448911SDavid Höppner #define SAVE_CHAR_X(I, N, V) \ 15166448911SDavid Höppner { \ 15266448911SDavid Höppner ks_value_t v; \ 153e633f2d7SRichard Lowe (void) asprintf(&v.str.addr.ptr, "%c", V); \ 15466448911SDavid Höppner v.str.len = 1; \ 15566448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_STRING); \ 15666448911SDavid Höppner } 15766448911SDavid Höppner 15866448911SDavid Höppner #define DFLT_FMT \ 15966448911SDavid Höppner "module: %-30.30s instance: %-6d\n" \ 16066448911SDavid Höppner "name: %-30.30s class: %-.30s\n" 16166448911SDavid Höppner 16266448911SDavid Höppner #define JSON_FMT \ 16366448911SDavid Höppner "{\n\t\"module\": \"%s\",\n" \ 16466448911SDavid Höppner "\t\"instance\": %d,\n" \ 16566448911SDavid Höppner "\t\"name\": \"%s\",\n" \ 16666448911SDavid Höppner "\t\"class\": \"%s\",\n" \ 16766448911SDavid Höppner "\t\"type\": %d,\n" 16866448911SDavid Höppner 16966448911SDavid Höppner #define KS_DFMT "\t%-30s " 17066448911SDavid Höppner #define KS_JFMT "\t\t\"%s\": " 17166448911SDavid Höppner #define KS_PFMT "%s:%d:%s:%s" 17266448911SDavid Höppner 17366448911SDavid Höppner typedef struct ks_instance { 17466448911SDavid Höppner list_node_t ks_next; 17566448911SDavid Höppner char ks_name[KSTAT_STRLEN]; 17666448911SDavid Höppner char ks_module[KSTAT_STRLEN]; 17766448911SDavid Höppner char ks_class[KSTAT_STRLEN]; 17866448911SDavid Höppner int ks_instance; 17966448911SDavid Höppner uchar_t ks_type; 18066448911SDavid Höppner hrtime_t ks_snaptime; 18166448911SDavid Höppner list_t ks_nvlist; 18266448911SDavid Höppner } ks_instance_t; 18366448911SDavid Höppner 18466448911SDavid Höppner typedef struct ks_nvpair { 18566448911SDavid Höppner list_node_t nv_next; 18666448911SDavid Höppner char name[KSTAT_STRLEN]; 18766448911SDavid Höppner uchar_t data_type; 18866448911SDavid Höppner ks_value_t value; 18966448911SDavid Höppner } ks_nvpair_t; 19066448911SDavid Höppner 19166448911SDavid Höppner typedef struct ks_pattern { 19266448911SDavid Höppner char *pstr; 19366448911SDavid Höppner regex_t preg; 19466448911SDavid Höppner } ks_pattern_t; 19566448911SDavid Höppner 19666448911SDavid Höppner typedef struct ks_selector { 19766448911SDavid Höppner list_node_t ks_next; 19866448911SDavid Höppner ks_pattern_t ks_module; 19966448911SDavid Höppner ks_pattern_t ks_instance; 20066448911SDavid Höppner ks_pattern_t ks_name; 20166448911SDavid Höppner ks_pattern_t ks_statistic; 20266448911SDavid Höppner } ks_selector_t; 20366448911SDavid Höppner 20466448911SDavid Höppner static void usage(void); 20566448911SDavid Höppner static int compare_instances(ks_instance_t *, ks_instance_t *); 20666448911SDavid Höppner static void nvpair_insert(ks_instance_t *, char *, ks_value_t *, uchar_t); 20766448911SDavid Höppner static boolean_t ks_match(const char *, ks_pattern_t *); 20866448911SDavid Höppner static ks_selector_t *new_selector(void); 20966448911SDavid Höppner static void ks_instances_read(kstat_ctl_t *); 21066448911SDavid Höppner static void ks_value_print(ks_nvpair_t *); 21166448911SDavid Höppner static void ks_instance_print(ks_instance_t *, ks_nvpair_t *); 21266448911SDavid Höppner static void ks_instances_print(void); 21366448911SDavid Höppner static char *ks_safe_strdup(char *); 21466448911SDavid Höppner static void ks_sleep_until(hrtime_t *, hrtime_t, int, int *); 21566448911SDavid Höppner 21666448911SDavid Höppner /* Raw kstat readers */ 21766448911SDavid Höppner static void save_cpu_stat(kstat_t *, ks_instance_t *); 21866448911SDavid Höppner static void save_var(kstat_t *, ks_instance_t *); 21966448911SDavid Höppner static void save_ncstats(kstat_t *, ks_instance_t *); 22066448911SDavid Höppner static void save_sysinfo(kstat_t *, ks_instance_t *); 22166448911SDavid Höppner static void save_vminfo(kstat_t *, ks_instance_t *); 22266448911SDavid Höppner static void save_nfs(kstat_t *, ks_instance_t *); 22366448911SDavid Höppner #ifdef __sparc 22466448911SDavid Höppner static void save_sfmmu_global_stat(kstat_t *, ks_instance_t *); 22566448911SDavid Höppner static void save_sfmmu_tsbsize_stat(kstat_t *, ks_instance_t *); 22666448911SDavid Höppner static void save_simmstat(kstat_t *, ks_instance_t *); 22766448911SDavid Höppner /* Helper function for save_temperature() */ 22866448911SDavid Höppner static char *short_array_to_string(short *, int); 22966448911SDavid Höppner static void save_temperature(kstat_t *, ks_instance_t *); 23066448911SDavid Höppner static void save_temp_over(kstat_t *, ks_instance_t *); 23166448911SDavid Höppner static void save_ps_shadow(kstat_t *, ks_instance_t *); 23266448911SDavid Höppner static void save_fault_list(kstat_t *, ks_instance_t *); 23366448911SDavid Höppner #endif 23466448911SDavid Höppner 23566448911SDavid Höppner /* Named kstat readers */ 23666448911SDavid Höppner static void save_named(kstat_t *, ks_instance_t *); 23766448911SDavid Höppner static void save_intr(kstat_t *, ks_instance_t *); 23866448911SDavid Höppner static void save_io(kstat_t *, ks_instance_t *); 23966448911SDavid Höppner static void save_timer(kstat_t *, ks_instance_t *); 24066448911SDavid Höppner 24166448911SDavid Höppner /* Typedef for raw kstat reader functions */ 24266448911SDavid Höppner typedef void (*kstat_raw_reader_t)(kstat_t *, ks_instance_t *); 24366448911SDavid Höppner 24466448911SDavid Höppner static struct { 24566448911SDavid Höppner kstat_raw_reader_t fn; 24666448911SDavid Höppner char *name; 24766448911SDavid Höppner } ks_raw_lookup[] = { 24866448911SDavid Höppner /* Function name kstat name */ 24966448911SDavid Höppner {save_cpu_stat, "cpu_stat:cpu_stat"}, 25066448911SDavid Höppner {save_var, "unix:var"}, 25166448911SDavid Höppner {save_ncstats, "unix:ncstats"}, 25266448911SDavid Höppner {save_sysinfo, "unix:sysinfo"}, 25366448911SDavid Höppner {save_vminfo, "unix:vminfo"}, 25466448911SDavid Höppner {save_nfs, "nfs:mntinfo"}, 25566448911SDavid Höppner #ifdef __sparc 25666448911SDavid Höppner {save_sfmmu_global_stat, "unix:sfmmu_global_stat"}, 25766448911SDavid Höppner {save_sfmmu_tsbsize_stat, "unix:sfmmu_tsbsize_stat"}, 25866448911SDavid Höppner {save_simmstat, "unix:simm-status"}, 25966448911SDavid Höppner {save_temperature, "unix:temperature"}, 26066448911SDavid Höppner {save_temp_over, "unix:temperature override"}, 26166448911SDavid Höppner {save_ps_shadow, "unix:ps_shadow"}, 26266448911SDavid Höppner {save_fault_list, "unix:fault_list"}, 26366448911SDavid Höppner #endif 26466448911SDavid Höppner {NULL, NULL}, 26566448911SDavid Höppner }; 26666448911SDavid Höppner 26766448911SDavid Höppner static kstat_raw_reader_t lookup_raw_kstat_fn(char *, char *); 26866448911SDavid Höppner 26966448911SDavid Höppner #endif /* _STAT_KSTAT_H */ 270