summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKody A Kantor <kody@kkantor.com>2019-06-28 16:24:40 +0000
committerTrent Mick <trentm@gmail.com>2019-06-28 16:24:40 +0000
commit98df7a44da07e453a319dc546a20ef15d1619b7c (patch)
treec0bf635585206b1c359c88c5fd5874dc81ce2726
parent9f27b084492b24583dbcc44e59ce9eaacd78ed68 (diff)
downloadillumos-joyent-98df7a44da07e453a319dc546a20ef15d1619b7c.tar.gz
OS-7869 want kstat mdb modulecr6523-OS-7869
-rw-r--r--manifest1
-rw-r--r--usr/src/cmd/mdb/Makefile.common3
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_argvec.c21
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_argvec.h10
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_modapi.h3
-rw-r--r--usr/src/cmd/mdb/common/modules/kstat/kstat.c191
-rw-r--r--usr/src/cmd/mdb/intel/amd64/kstat/Makefile27
-rw-r--r--usr/src/cmd/mdb/sparc/v9/kstat/Makefile27
8 files changed, 274 insertions, 9 deletions
diff --git a/manifest b/manifest
index 73246a034b..b32f1efcde 100644
--- a/manifest
+++ b/manifest
@@ -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