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. 25*8af765f5SPeter Tribble * Copyright 2020 Peter Tribble. 2666448911SDavid Höppner */ 2766448911SDavid Höppner 2866448911SDavid Höppner #ifndef _STAT_KSTAT_H 2966448911SDavid Höppner #define _STAT_KSTAT_H 3066448911SDavid Höppner 3166448911SDavid Höppner /* 3266448911SDavid Höppner * Structures needed by the kstat reader functions. 3366448911SDavid Höppner */ 3466448911SDavid Höppner #include <sys/var.h> 3566448911SDavid Höppner #include <sys/utsname.h> 3666448911SDavid Höppner #include <sys/sysinfo.h> 3766448911SDavid Höppner #include <sys/flock.h> 3866448911SDavid Höppner #include <sys/dnlc.h> 3966448911SDavid Höppner #include <regex.h> 4066448911SDavid Höppner #include <nfs/nfs.h> 4166448911SDavid Höppner #include <nfs/nfs_clnt.h> 4266448911SDavid Höppner 4366448911SDavid Höppner #ifdef __sparc 4466448911SDavid Höppner #include <vm/hat_sfmmu.h> 4566448911SDavid Höppner #endif 4666448911SDavid Höppner 4766448911SDavid Höppner #define KSTAT_DATA_HRTIME (KSTAT_DATA_STRING + 1) 4866448911SDavid Höppner 4966448911SDavid Höppner typedef union ks_value { 5066448911SDavid Höppner char c[16]; 5166448911SDavid Höppner int32_t i32; 5266448911SDavid Höppner uint32_t ui32; 5366448911SDavid Höppner struct { 5466448911SDavid Höppner union { 5566448911SDavid Höppner char *ptr; 5666448911SDavid Höppner char __pad[8]; 5766448911SDavid Höppner } addr; 5866448911SDavid Höppner uint32_t len; 5966448911SDavid Höppner } str; 6066448911SDavid Höppner 6166448911SDavid Höppner int64_t i64; 6266448911SDavid Höppner uint64_t ui64; 6366448911SDavid Höppner } ks_value_t; 6466448911SDavid Höppner 6566448911SDavid Höppner #define SAVE_HRTIME(I, S, N) \ 6666448911SDavid Höppner { \ 6766448911SDavid Höppner ks_value_t v; \ 6866448911SDavid Höppner v.ui64 = S->N; \ 6966448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_UINT64); \ 7066448911SDavid Höppner } 7166448911SDavid Höppner 7266448911SDavid Höppner #define SAVE_INT32(I, S, N) \ 7366448911SDavid Höppner { \ 7466448911SDavid Höppner ks_value_t v; \ 7566448911SDavid Höppner v.i32 = S->N; \ 7666448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_INT32); \ 7766448911SDavid Höppner } 7866448911SDavid Höppner 7966448911SDavid Höppner #define SAVE_UINT32(I, S, N) \ 8066448911SDavid Höppner { \ 8166448911SDavid Höppner ks_value_t v; \ 8266448911SDavid Höppner v.ui32 = S->N; \ 8366448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_UINT32); \ 8466448911SDavid Höppner } 8566448911SDavid Höppner 86*8af765f5SPeter Tribble #define SAVE_INT64(I, S, N) \ 8766448911SDavid Höppner { \ 8866448911SDavid Höppner ks_value_t v; \ 8966448911SDavid Höppner v.i64 = S->N; \ 9066448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_INT64); \ 9166448911SDavid Höppner } 9266448911SDavid Höppner 9366448911SDavid Höppner #define SAVE_UINT64(I, S, N) \ 9466448911SDavid Höppner { \ 9566448911SDavid Höppner ks_value_t v; \ 9666448911SDavid Höppner v.ui64 = S->N; \ 9766448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_UINT64); \ 9866448911SDavid Höppner } 9966448911SDavid Höppner 10066448911SDavid Höppner /* 10166448911SDavid Höppner * We dont want const "strings" because we free 10266448911SDavid Höppner * the instances later. 10366448911SDavid Höppner */ 10466448911SDavid Höppner #define SAVE_STRING(I, S, N) \ 10566448911SDavid Höppner { \ 10666448911SDavid Höppner ks_value_t v; \ 10766448911SDavid Höppner v.str.addr.ptr = safe_strdup(S->N); \ 10866448911SDavid Höppner v.str.len = strlen(S->N); \ 10966448911SDavid Höppner nvpair_insert(I, #N, &v, KSTAT_DATA_STRING); \ 11066448911SDavid Höppner } 11166448911SDavid Höppner 11266448911SDavid Höppner #define SAVE_HRTIME_X(I, N, V) \ 11366448911SDavid Höppner { \ 11466448911SDavid Höppner ks_value_t v; \ 11566448911SDavid Höppner v.ui64 = V; \ 11666448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_HRTIME); \ 11766448911SDavid Höppner } 11866448911SDavid Höppner 11966448911SDavid Höppner #define SAVE_INT32_X(I, N, V) \ 12066448911SDavid Höppner { \ 12166448911SDavid Höppner ks_value_t v; \ 12266448911SDavid Höppner v.i32 = V; \ 12366448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_INT32); \ 12466448911SDavid Höppner } 12566448911SDavid Höppner 12666448911SDavid Höppner #define SAVE_UINT32_X(I, N, V) \ 12766448911SDavid Höppner { \ 12866448911SDavid Höppner ks_value_t v; \ 12966448911SDavid Höppner v.ui32 = V; \ 13066448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_UINT32); \ 13166448911SDavid Höppner } 13266448911SDavid Höppner 13366448911SDavid Höppner #define SAVE_UINT64_X(I, N, V) \ 13466448911SDavid Höppner { \ 13566448911SDavid Höppner ks_value_t v; \ 13666448911SDavid Höppner v.ui64 = V; \ 13766448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_UINT64); \ 13866448911SDavid Höppner } 13966448911SDavid Höppner 14066448911SDavid Höppner #define SAVE_STRING_X(I, N, V) \ 14166448911SDavid Höppner { \ 14266448911SDavid Höppner ks_value_t v; \ 14366448911SDavid Höppner v.str.addr.ptr = safe_strdup(V); \ 144861bfc89STheo Schlossnagle v.str.len = (V) ? strlen(V) : 0; \ 14566448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_STRING); \ 14666448911SDavid Höppner } 14766448911SDavid Höppner 14866448911SDavid Höppner #define SAVE_CHAR_X(I, N, V) \ 14966448911SDavid Höppner { \ 15066448911SDavid Höppner ks_value_t v; \ 151e633f2d7SRichard Lowe (void) asprintf(&v.str.addr.ptr, "%c", V); \ 15266448911SDavid Höppner v.str.len = 1; \ 15366448911SDavid Höppner nvpair_insert(I, N, &v, KSTAT_DATA_STRING); \ 15466448911SDavid Höppner } 15566448911SDavid Höppner 15666448911SDavid Höppner #define DFLT_FMT \ 15766448911SDavid Höppner "module: %-30.30s instance: %-6d\n" \ 15866448911SDavid Höppner "name: %-30.30s class: %-.30s\n" 15966448911SDavid Höppner 16066448911SDavid Höppner #define KS_DFMT "\t%-30s " 16166448911SDavid Höppner #define KS_PFMT "%s:%d:%s:%s" 16266448911SDavid Höppner 16366448911SDavid Höppner typedef struct ks_instance { 16466448911SDavid Höppner list_node_t ks_next; 16566448911SDavid Höppner char ks_name[KSTAT_STRLEN]; 16666448911SDavid Höppner char ks_module[KSTAT_STRLEN]; 16766448911SDavid Höppner char ks_class[KSTAT_STRLEN]; 168*8af765f5SPeter Tribble int ks_instance; 16966448911SDavid Höppner uchar_t ks_type; 17066448911SDavid Höppner hrtime_t ks_snaptime; 17166448911SDavid Höppner list_t ks_nvlist; 17266448911SDavid Höppner } ks_instance_t; 17366448911SDavid Höppner 17466448911SDavid Höppner typedef struct ks_nvpair { 17566448911SDavid Höppner list_node_t nv_next; 17666448911SDavid Höppner char name[KSTAT_STRLEN]; 17766448911SDavid Höppner uchar_t data_type; 17866448911SDavid Höppner ks_value_t value; 17966448911SDavid Höppner } ks_nvpair_t; 18066448911SDavid Höppner 18166448911SDavid Höppner typedef struct ks_pattern { 18266448911SDavid Höppner char *pstr; 18366448911SDavid Höppner regex_t preg; 18466448911SDavid Höppner } ks_pattern_t; 18566448911SDavid Höppner 18666448911SDavid Höppner typedef struct ks_selector { 18766448911SDavid Höppner list_node_t ks_next; 18866448911SDavid Höppner ks_pattern_t ks_module; 18966448911SDavid Höppner ks_pattern_t ks_instance; 19066448911SDavid Höppner ks_pattern_t ks_name; 19166448911SDavid Höppner ks_pattern_t ks_statistic; 19266448911SDavid Höppner } ks_selector_t; 19366448911SDavid Höppner 19466448911SDavid Höppner static void usage(void); 19566448911SDavid Höppner static int compare_instances(ks_instance_t *, ks_instance_t *); 19666448911SDavid Höppner static void nvpair_insert(ks_instance_t *, char *, ks_value_t *, uchar_t); 19766448911SDavid Höppner static boolean_t ks_match(const char *, ks_pattern_t *); 19866448911SDavid Höppner static ks_selector_t *new_selector(void); 19966448911SDavid Höppner static void ks_instances_read(kstat_ctl_t *); 20066448911SDavid Höppner static void ks_value_print(ks_nvpair_t *); 20166448911SDavid Höppner static void ks_instances_print(void); 20266448911SDavid Höppner static char *ks_safe_strdup(char *); 20366448911SDavid Höppner static void ks_sleep_until(hrtime_t *, hrtime_t, int, int *); 20466448911SDavid Höppner 20566448911SDavid Höppner /* Raw kstat readers */ 20666448911SDavid Höppner static void save_cpu_stat(kstat_t *, ks_instance_t *); 20766448911SDavid Höppner static void save_var(kstat_t *, ks_instance_t *); 20866448911SDavid Höppner static void save_ncstats(kstat_t *, ks_instance_t *); 20966448911SDavid Höppner static void save_sysinfo(kstat_t *, ks_instance_t *); 21066448911SDavid Höppner static void save_vminfo(kstat_t *, ks_instance_t *); 21166448911SDavid Höppner static void save_nfs(kstat_t *, ks_instance_t *); 21266448911SDavid Höppner #ifdef __sparc 21366448911SDavid Höppner static void save_sfmmu_global_stat(kstat_t *, ks_instance_t *); 21466448911SDavid Höppner static void save_sfmmu_tsbsize_stat(kstat_t *, ks_instance_t *); 21566448911SDavid Höppner #endif 21666448911SDavid Höppner 21766448911SDavid Höppner /* Named kstat readers */ 21866448911SDavid Höppner static void save_named(kstat_t *, ks_instance_t *); 21966448911SDavid Höppner static void save_intr(kstat_t *, ks_instance_t *); 22066448911SDavid Höppner static void save_io(kstat_t *, ks_instance_t *); 22166448911SDavid Höppner static void save_timer(kstat_t *, ks_instance_t *); 22266448911SDavid Höppner 22366448911SDavid Höppner /* Typedef for raw kstat reader functions */ 22466448911SDavid Höppner typedef void (*kstat_raw_reader_t)(kstat_t *, ks_instance_t *); 22566448911SDavid Höppner 22666448911SDavid Höppner static struct { 22766448911SDavid Höppner kstat_raw_reader_t fn; 22866448911SDavid Höppner char *name; 22966448911SDavid Höppner } ks_raw_lookup[] = { 23066448911SDavid Höppner /* Function name kstat name */ 23166448911SDavid Höppner {save_cpu_stat, "cpu_stat:cpu_stat"}, 23266448911SDavid Höppner {save_var, "unix:var"}, 23366448911SDavid Höppner {save_ncstats, "unix:ncstats"}, 23466448911SDavid Höppner {save_sysinfo, "unix:sysinfo"}, 23566448911SDavid Höppner {save_vminfo, "unix:vminfo"}, 23666448911SDavid Höppner {save_nfs, "nfs:mntinfo"}, 23766448911SDavid Höppner #ifdef __sparc 23866448911SDavid Höppner {save_sfmmu_global_stat, "unix:sfmmu_global_stat"}, 23966448911SDavid Höppner {save_sfmmu_tsbsize_stat, "unix:sfmmu_tsbsize_stat"}, 24066448911SDavid Höppner #endif 24166448911SDavid Höppner {NULL, NULL}, 24266448911SDavid Höppner }; 24366448911SDavid Höppner 24466448911SDavid Höppner static kstat_raw_reader_t lookup_raw_kstat_fn(char *, char *); 24566448911SDavid Höppner 24666448911SDavid Höppner #endif /* _STAT_KSTAT_H */ 247