diff options
author | Kody A Kantor <kody@kkantor.com> | 2019-06-28 16:24:40 +0000 |
---|---|---|
committer | Trent Mick <trentm@gmail.com> | 2019-06-28 16:24:40 +0000 |
commit | 98df7a44da07e453a319dc546a20ef15d1619b7c (patch) | |
tree | c0bf635585206b1c359c88c5fd5874dc81ce2726 | |
parent | 9f27b084492b24583dbcc44e59ce9eaacd78ed68 (diff) | |
download | illumos-joyent-98df7a44da07e453a319dc546a20ef15d1619b7c.tar.gz |
OS-7869 want kstat mdb modulecr6523-OS-7869
-rw-r--r-- | manifest | 1 | ||||
-rw-r--r-- | usr/src/cmd/mdb/Makefile.common | 3 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_argvec.c | 21 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_argvec.h | 10 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_modapi.h | 3 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/modules/kstat/kstat.c | 191 | ||||
-rw-r--r-- | usr/src/cmd/mdb/intel/amd64/kstat/Makefile | 27 | ||||
-rw-r--r-- | usr/src/cmd/mdb/sparc/v9/kstat/Makefile | 27 |
8 files changed, 274 insertions, 9 deletions
@@ -9836,6 +9836,7 @@ f usr/lib/mdb/kvm/amd64/ip.so 0555 root sys f usr/lib/mdb/kvm/amd64/ipc.so 0555 root sys f usr/lib/mdb/kvm/amd64/ipp.so 0555 root sys f usr/lib/mdb/kvm/amd64/krtld.so 0555 root sys +f usr/lib/mdb/kvm/amd64/kstat.so 0555 root sys f usr/lib/mdb/kvm/amd64/lofs.so 0555 root sys f usr/lib/mdb/kvm/amd64/logindmux.so 0555 root sys f usr/lib/mdb/kvm/amd64/mac.so 0555 root sys diff --git a/usr/src/cmd/mdb/Makefile.common b/usr/src/cmd/mdb/Makefile.common index 4fc3f3d317..2d15fe5896 100644 --- a/usr/src/cmd/mdb/Makefile.common +++ b/usr/src/cmd/mdb/Makefile.common @@ -21,7 +21,7 @@ # # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2016 Joyent, Inc. +# Copyright 2019 Joyent, Inc. # Copyright 2018 Nexenta Systems, Inc. # @@ -77,6 +77,7 @@ COMMON_MODULES_KVM = \ ipc \ ipp \ krtld \ + kstat \ lofs \ logindmux \ mac \ diff --git a/usr/src/cmd/mdb/common/mdb/mdb_argvec.c b/usr/src/cmd/mdb/common/mdb/mdb_argvec.c index 3505906683..56faea6bbe 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_argvec.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_argvec.c @@ -24,7 +24,9 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright 2019 Joyent, Inc. + */ #include <mdb/mdb_types.h> #include <mdb/mdb_argvec.h> @@ -186,6 +188,7 @@ argvec_process_opt(const mdb_opt_t *opt, const mdb_arg_t *arg) { uint64_t ui64; uintptr_t uip; + int i; switch (opt->opt_type) { case MDB_OPT_SETBITS: @@ -224,6 +227,15 @@ argvec_process_opt(const mdb_opt_t *opt, const mdb_arg_t *arg) *((uint64_t *)opt->opt_valp) = ui64; break; + case MDB_OPT_INT_SET: + *opt->opt_flag = TRUE; + if (arg->a_type == MDB_TYPE_STRING) + i = (int)mdb_strtoull(arg->a_un.a_str); + else + i = (int)arg->a_un.a_val; + *((int *)opt->opt_valp) = i; + break; + case MDB_OPT_SUBOPTS: if (arg->a_type != MDB_TYPE_STRING) { warn("string argument required for -%c\n", @@ -300,7 +312,8 @@ argvec_getopts(const mdb_opt_t *opts, const mdb_arg_t *argv, int argc) optp->opt_type == MDB_OPT_UINTPTR || optp->opt_type == MDB_OPT_UINTPTR_SET || optp->opt_type == MDB_OPT_SUBOPTS || - optp->opt_type == MDB_OPT_UINT64) { + optp->opt_type == MDB_OPT_UINT64 || + optp->opt_type == MDB_OPT_INT_SET) { /* * More text after the option letter: * forge a string argument from remainder. @@ -364,7 +377,9 @@ mdb_getopts(int argc, const mdb_arg_t *argv, ...) if (op->opt_type == MDB_OPT_SETBITS || op->opt_type == MDB_OPT_CLRBITS) { op->opt_bits = va_arg(alist, uint_t); - } else if (op->opt_type == MDB_OPT_UINTPTR_SET) { + } else if (op->opt_type == MDB_OPT_UINTPTR_SET || + op->opt_type == MDB_OPT_INT_SET) { + op->opt_flag = va_arg(alist, boolean_t *); } else if (op->opt_type == MDB_OPT_SUBOPTS) { op->opt_subopts = va_arg(alist, mdb_subopt_t *); diff --git a/usr/src/cmd/mdb/common/mdb/mdb_argvec.h b/usr/src/cmd/mdb/common/mdb/mdb_argvec.h index d76280d86d..ecbf8ca090 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_argvec.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_argvec.h @@ -24,11 +24,13 @@ * Use is subject to license terms. */ +/* + * Copyright 2019 Joyent, Inc. + */ + #ifndef _MDB_ARGVEC_H #define _MDB_ARGVEC_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #ifdef __cplusplus @@ -43,8 +45,8 @@ typedef struct mdb_argvec { size_t a_size; /* Array size */ } mdb_argvec_t; -/* see mdb_modapi.h for 1-6 */ -#define MDB_OPT_SUBOPTS 7 /* Option requires a mdb_subopt_t */ +/* see mdb_modapi.h for 1-7 */ +#define MDB_OPT_SUBOPTS 8 /* Option requires a mdb_subopt_t */ /* list and a value argument */ typedef struct mdb_subopt { diff --git a/usr/src/cmd/mdb/common/mdb/mdb_modapi.h b/usr/src/cmd/mdb/common/mdb/mdb_modapi.h index 0e53be9b4d..f84793732b 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_modapi.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_modapi.h @@ -22,7 +22,7 @@ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. - * Copyright (c) 2013 Joyent, Inc. All rights reserved. + * Copyright 2019 Joyent, Inc. */ #ifndef _MDB_MODAPI_H @@ -249,6 +249,7 @@ extern int mdb_getareg(mdb_tid_t, const char *, mdb_reg_t *); #define MDB_OPT_UINTPTR 4 /* uintptr_t argument */ #define MDB_OPT_UINT64 5 /* uint64_t argument */ #define MDB_OPT_UINTPTR_SET 6 /* boolean_t+uintptr_t args */ +#define MDB_OPT_INT_SET 7 /* int argument */ extern int mdb_getopts(int, const mdb_arg_t *, ...); diff --git a/usr/src/cmd/mdb/common/modules/kstat/kstat.c b/usr/src/cmd/mdb/common/modules/kstat/kstat.c new file mode 100644 index 0000000000..306d5c8b1a --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/kstat/kstat.c @@ -0,0 +1,191 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. + */ + +#include <mdb/mdb_ctf.h> +#include <sys/mdb_modapi.h> + +#include <sys/kstat.h> + +typedef enum mdb_kstat_flags { + MDB_KSTAT_FLAG_ADDRESS = 1 << 0, +} mdb_kstat_flags_t; + +/* + * The kstat framework wraps kstat_t in an ekstat_t struct that holds some + * internal data. + */ +typedef struct mdb_ekstat { + kstat_t e_ks; +} mdb_ekstat_t; + +/* + * ::kstat + * + * Print some relevant fields from kstats on the system. + * + */ +static int +kstat_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + const char *mod, *name, *class; + int inst; + int output_flags; + const char *search_mod = NULL; + const char *search_name = NULL; + const char *search_class = NULL; + int search_inst; + boolean_t search_inst_set = B_FALSE; + + mdb_ekstat_t ekstat; + + if (!(flags & DCMD_ADDRSPEC)) { + if (mdb_walk_dcmd("kstat", "kstat", argc, argv) == -1) { + return (DCMD_ERR); + } + + return (DCMD_OK); + } + + if (mdb_getopts(argc, argv, + 'm', MDB_OPT_STR, &search_mod, + 'i', MDB_OPT_INT_SET, &search_inst_set, &search_inst, + 'n', MDB_OPT_STR, &search_name, + 'c', MDB_OPT_STR, &search_class, + 'a', MDB_OPT_SETBITS, MDB_KSTAT_FLAG_ADDRESS, &output_flags, + NULL) != argc) { + return (DCMD_USAGE); + } + + if ((search_mod != NULL && strlen(search_mod) >= KSTAT_STRLEN) || + (search_name != NULL && strlen(search_name) >= KSTAT_STRLEN) || + (search_class != NULL && strlen(search_class) >= KSTAT_STRLEN)) { + mdb_warn("provided module, class, and name lengths must be" + " < KSTAT_STRLEN\n"); + return (DCMD_ERR); + } + + if (DCMD_HDRSPEC(flags)) { + if (output_flags & MDB_KSTAT_FLAG_ADDRESS) { + mdb_printf("%<u>%-?s %</u>", "ADDRESS"); + } + mdb_printf("%<u>%-10s %-10s %-20s %-15s%</u>\n", "MODULE", + "INSTANCE", "NAME", "CLASS"); + } + + if (mdb_ctf_vread(&ekstat, "ekstat_t", "mdb_ekstat_t", addr, 0) == -1) { + mdb_warn("unable to read CTF data for 'ekstat_t'"); + return (DCMD_ERR); + } + + mod = ekstat.e_ks.ks_module; + inst = ekstat.e_ks.ks_instance; + name = ekstat.e_ks.ks_name; + class = ekstat.e_ks.ks_class; + + /* + * Short circuit if the kstat in question doesn't match the user's + * filter(s). + */ + if ((search_mod != NULL && + strncmp(mod, search_mod, KSTAT_STRLEN) != 0) || + (search_name != NULL && + strncmp(name, search_name, KSTAT_STRLEN) != 0) || + (search_class != NULL && + strncmp(class, search_class, KSTAT_STRLEN) != 0) || + (search_inst_set && search_inst != inst)) { + + return (DCMD_OK); + } + + if (output_flags & MDB_KSTAT_FLAG_ADDRESS) { + mdb_printf("%0?p ", addr); + } + mdb_printf("%-10s %-10d %-20s %-15s\n", mod, + ekstat.e_ks.ks_instance, name, class); + + return (DCMD_OK); +} + +void +kstat_help(void) +{ + mdb_printf("Display kstat_t summaries.\n" + " -a also display an address column for each kstat\n" + " -m search for kstats with the given module (e.g. 'zfs')\n" + " -i search for kstats with the given instance number" + " (e.g. 0t1)\n" + " -n search for kstats with the given name (e.g. 'zfetchstats')\n" + " -c search for kstats with the given class (e.g. 'misc')\n"); +} + +/* + * ::walk kstat + * + * Walk all ekstat_t structures in the kstat AVL tree. This is nothing more than + * a layered avl walk. + */ +static int +kstat_walk_init(mdb_walk_state_t *wsp) +{ + GElf_Sym sym; + + if (wsp->walk_addr != 0) { + mdb_warn("kstat walk only supports global walks\n"); + return (WALK_ERR); + } + + if (mdb_lookup_by_obj("unix", "kstat_avl_byname", &sym) == -1) { + mdb_warn("failed to find symbol 'kstat_avl_byname'"); + return (WALK_ERR); + } + + wsp->walk_addr = (uintptr_t)sym.st_value; + + if (mdb_layered_walk("avl", wsp) == -1) { + mdb_warn("failed to walk 'avl'"); + return (WALK_ERR); + } + + return (WALK_NEXT); +} + +static int +kstat_walk_step(mdb_walk_state_t *wsp) +{ + return (wsp->walk_callback(wsp->walk_addr, NULL, wsp->walk_cbdata)); +} + +static const mdb_dcmd_t dcmds[] = { + { "kstat", "?[-a] [ -m module ] [ -i instance ] [ -n name ]" + " [ -c class ]\n", + "kstat summary", kstat_print, kstat_help }, + { NULL } +}; + +static const mdb_walker_t walkers[] = { + { "kstat", "walk all kstat structures", kstat_walk_init, + kstat_walk_step, NULL }, + { NULL } +}; + +static const mdb_modinfo_t modinfo = { + MDB_API_VERSION, dcmds, walkers +}; + +const mdb_modinfo_t * +_mdb_init(void) +{ + return (&modinfo); +} diff --git a/usr/src/cmd/mdb/intel/amd64/kstat/Makefile b/usr/src/cmd/mdb/intel/amd64/kstat/Makefile new file mode 100644 index 0000000000..06f554aa58 --- /dev/null +++ b/usr/src/cmd/mdb/intel/amd64/kstat/Makefile @@ -0,0 +1,27 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2019 Joyent, Inc. +# + +MODULE = kstat.so +MDBTGT = kvm + +MODSRCS = kstat.c + +include ../../../../Makefile.cmd +include ../../../../Makefile.cmd.64 +include ../../Makefile.amd64 +include ../../../Makefile.module + +CSTD= $(CSTD_GNU99) +C99LMODE= -Xc99=%all diff --git a/usr/src/cmd/mdb/sparc/v9/kstat/Makefile b/usr/src/cmd/mdb/sparc/v9/kstat/Makefile new file mode 100644 index 0000000000..ac851f292e --- /dev/null +++ b/usr/src/cmd/mdb/sparc/v9/kstat/Makefile @@ -0,0 +1,27 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2019 Joyent, Inc. +# + +MODULE = kstat.so +MDBTGT = kvm + +MODSRCS = kstat.c + +include ../../../../Makefile.cmd +include ../../../../Makefile.cmd.64 +include ../../Makefile.sparcv9 +include ../../../Makefile.module + +CSTD= $(CSTD_GNU99) +C99LMODE= -Xc99=%all |