/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
*/
/* Portions Copyright 2010 Robert Milkowski */
#include <sys/zfs_context.h>
#include <sys/mdb_modapi.h>
#include <sys/dmu_objset.h>
#include <sys/dsl_pool.h>
#include <sys/metaslab_impl.h>
#include <sys/space_map.h>
#include <sys/vdev_impl.h>
#include <sys/zap_leaf.h>
#include <sys/zap_impl.h>
#include <ctype.h>
#include <sys/multilist.h>
#ifdef _KERNEL
extern int64_t mdb_gethrtime(void);
#else
#endif
#ifndef _KERNEL
int aok;
#endif
enum spa_flags {
};
/*
* If any of these flags are set, call spa_vdevs in spa_print
*/
#define SPA_FLAG_ALL_VDEV \
static int
{
return (DCMD_ERR);
}
} else {
}
return (DCMD_ERR);
}
if (off % 8 != 0) {
mdb_warn("member %s of type %s is unsupported bitfield",
return (DCMD_ERR);
}
off /= 8;
mdb_warn("failed to read %s from %s at %p",
return (DCMD_ERR);
}
/* mdb_warn("read %s from %s at %p+%llx\n", member, type, addr, off); */
return (0);
}
static boolean_t
{
return (B_FALSE);
}
return (B_TRUE);
}
static int
{
for (i = frac_digits; i; i--)
mul *= 10;
}
static void
{
int index = 0;
char *u;
while (n >= 1024) {
n = (n + (1024 / 2)) / 1024; /* Round up or down */
index++;
}
if (index == 0) {
(u_longlong_t)n);
} else {
(u_longlong_t)n, u);
}
}
static int verbose;
static int
{
mdb_warn("must supply starting address\n");
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
"INVALID", "INVALID", "INVALID", "INVALID" };
return (WALK_DONE);
}
if (SM_DEBUG_DECODE(entry)) {
mdb_printf("DEBUG: %3u %10s: txg=%llu pass=%llu\n",
} else {
mdb_printf("Entry: %3u offsets=%08llx-%08llx type=%c "
"size=%06llx", number,
if (verbose)
mdb_printf("\n");
}
return (WALK_NEXT);
}
static int
{
static int gotid;
if (!gotid) {
&dd_id) == -1) {
mdb_warn("couldn't find struct dsl_dir");
return (DCMD_ERR);
}
}
return (DCMD_ERR);
}
if (dd_parent) {
return (DCMD_ERR);
}
if (dd_myname[0])
else
return (0);
}
static int
{
static int gotid;
buf[0] = '\0';
if (!gotid) {
&os_id) == -1) {
mdb_warn("couldn't find struct objset");
return (DCMD_ERR);
}
&ds_id) == -1) {
mdb_warn("couldn't find struct dsl_dataset");
return (DCMD_ERR);
}
}
return (DCMD_ERR);
if (os_dsl_dataset == 0) {
return (0);
}
return (DCMD_ERR);
}
return (DCMD_ERR);
if (ds_snapname[0]) {
}
return (0);
}
static int
{
const char *cp;
return (-1);
}
} else {
}
return (0);
}
/* ARGSUSED */
static int
{
/*
* This table can be approximately generated by running:
* egrep "^[a-z0-9_]+ [a-z0-9_]+( =.*)?;" *.c | cut -d ' ' -f 2
*/
static const char *params[] = {
"arc_reduce_dnlc_percent",
"arc_lotsfree_percent",
"zfs_dirty_data_max",
"zfs_dirty_data_sync",
"zfs_delay_max_ns",
"zfs_delay_min_dirty_percent",
"zfs_delay_scale",
"zfs_vdev_max_active",
"zfs_vdev_sync_read_min_active",
"zfs_vdev_sync_read_max_active",
"zfs_vdev_sync_write_min_active",
"zfs_vdev_sync_write_max_active",
"zfs_vdev_async_read_min_active",
"zfs_vdev_async_read_max_active",
"zfs_vdev_async_write_min_active",
"zfs_vdev_async_write_max_active",
"zfs_vdev_scrub_min_active",
"zfs_vdev_scrub_max_active",
"zfs_vdev_async_write_active_min_dirty_percent",
"zfs_vdev_async_write_active_max_dirty_percent",
"spa_asize_inflation",
"zfs_arc_max",
"zfs_arc_min",
"arc_shrink_shift",
"zfs_mdcomp_disable",
"zfs_prefetch_disable",
"zfetch_max_streams",
"zfetch_min_sec_reap",
"zfetch_block_cap",
"zfetch_array_rd_sz",
"zfs_default_bs",
"zfs_default_ibs",
"metaslab_aliquot",
"reference_tracking_enable",
"reference_history",
"spa_max_replication_override",
"spa_mode_global",
"zfs_flags",
"zfs_txg_timeout",
"zfs_vdev_cache_max",
"zfs_vdev_cache_size",
"zfs_vdev_cache_bshift",
"vdev_mirror_shift",
"zfs_scrub_limit",
"zfs_no_scrub_io",
"zfs_no_scrub_prefetch",
"zfs_vdev_aggregation_limit",
"fzap_default_block_shift",
"zfs_immediate_write_sz",
"zfs_read_chunk_size",
"zfs_nocacheflush",
"zil_replay_disable",
"metaslab_gang_bang",
"metaslab_df_alloc_threshold",
"metaslab_df_free_pct",
"zio_injection_enabled",
"zvol_immediate_write_sz",
};
int sz;
if (sz == 4) {
} else if (sz == 8) {
} else {
}
}
return (DCMD_OK);
}
/* ARGSUSED */
static int
{
mdb_warn("failed to read blkptr_t");
return (DCMD_ERR);
}
mdb_warn("Could not find blkptr enumerated types");
return (DCMD_ERR);
}
return (DCMD_OK);
}
typedef struct mdb_dmu_buf_impl {
struct {
} db;
struct {
} db_holds;
/* ARGSUSED */
static int
{
if (DCMD_HDRSPEC(flags))
mdb_printf("%*s %8s %3s %9s %5s %s\n",
addr, 0) == -1)
return (DCMD_ERR);
else
else
return (DCMD_ERR);
}
return (DCMD_OK);
}
/* ARGSUSED */
static int
{
int i, maxidx;
mdb_warn("failed to read 'dbuf_hash_table'");
return (DCMD_ERR);
}
for (i = 0; i < HISTOSZ; i++) {
histo[i] = 0;
histo2[i] = 0;
}
ndbufs = 0;
int len;
mdb_warn("failed to read hash bucket %u at %p",
return (DCMD_ERR);
}
len = 0;
while (dbp != 0) {
dbp) == -1) {
return (DCMD_ERR);
}
histo2[i]++;
len++;
ndbufs++;
}
}
mdb_printf("hash table has %llu buckets, %llu dbufs "
mdb_printf("\n");
maxidx = 0;
for (i = 0; i < HISTOSZ; i++)
if (histo[i] > 0)
maxidx = i;
mdb_printf("hash chain length number of buckets\n");
for (i = 0; i <= maxidx; i++)
mdb_printf("\n");
maxidx = 0;
for (i = 0; i < HISTOSZ; i++)
if (histo2[i] > 0)
maxidx = i;
mdb_printf("hash chain depth number of dbufs\n");
for (i = 0; i <= maxidx; i++)
mdb_printf("%u or more %llu %llu%%\n",
return (DCMD_OK);
}
/*
* ::zap_leaf [-v]
*
* Print a zap_leaf_phys_t, assumed to be 16k
*/
/* ARGSUSED */
static int
{
zap_leaf_t l;
int i;
return (DCMD_USAGE);
if (four)
l.l_bs = 12;
if (!(flags & DCMD_ADDRSPEC)) {
return (DCMD_USAGE);
}
return (DCMD_ERR);
}
mdb_warn("This does not appear to be a zap_leaf_phys_t");
return (DCMD_ERR);
}
"ENTRIES_CDSORTED" : "");
if (verbose) {
mdb_printf(" hash table:\n");
for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(&l); i++) {
}
}
mdb_printf(" chunks:\n");
for (i = 0; i < ZAP_LEAF_NUMCHUNKS(&l); i++) {
/* LINTED: alignment */
case ZAP_CHUNK_FREE:
if (verbose) {
mdb_printf(" %u: free; lf_next = %u\n",
}
break;
case ZAP_CHUNK_ENTRY:
mdb_printf(" %u: entry\n", i);
if (verbose) {
mdb_printf(" le_next = %u\n",
}
mdb_printf(" le_name_chunk = %u\n",
mdb_printf(" le_name_numints = %u\n",
mdb_printf(" le_value_chunk = %u\n",
mdb_printf(" le_value_intlen = %u\n",
mdb_printf(" le_value_numints = %u\n",
mdb_printf(" le_cd = %u\n",
mdb_printf(" le_hash = %llx\n",
break;
case ZAP_CHUNK_ARRAY:
mdb_printf(" %u: array", i);
mdb_printf("\n");
if (verbose) {
int j;
mdb_printf(" ");
for (j = 0; j < ZAP_LEAF_ARRAY_BYTES; j++) {
mdb_printf("%02x ",
}
mdb_printf("\n");
}
mdb_printf(" lf_next = %u\n",
}
break;
default:
mdb_printf(" %u: undefined type %u\n",
}
}
return (DCMD_OK);
}
typedef struct dbufs_data {
char *osname;
} dbufs_data_t;
/* ARGSUSED */
static int
{
return (WALK_ERR);
}
}
return (WALK_NEXT);
}
/* ARGSUSED */
static int
{
return (DCMD_USAGE);
}
if (object) {
} else {
}
}
if (blkid) {
} else {
}
}
mdb_warn("couldn't find struct dmu_buf_impl_t");
return (DCMD_ERR);
}
mdb_warn("can't walk dbufs");
return (DCMD_ERR);
}
return (DCMD_OK);
}
typedef struct abuf_find_data {
/* ARGSUSED */
static int
{
return (WALK_ERR);
}
}
return (WALK_NEXT);
}
/* ARGSUSED */
static int
{
int i;
const char *syms[] = {
"ARC_mru",
"ARC_mru_ghost",
"ARC_mfu",
"ARC_mfu_ghost",
};
if (argc != 2)
return (DCMD_USAGE);
for (i = 0; i < 2; i ++) {
case MDB_TYPE_STRING:
break;
case MDB_TYPE_IMMEDIATE:
break;
default:
return (DCMD_USAGE);
}
}
mdb_warn("couldn't find struct arc_buf_hdr");
return (DCMD_ERR);
}
return (DCMD_ERR);
}
return (DCMD_ERR);
}
}
return (DCMD_OK);
}
typedef struct dbgmsg_arg {
} dbgmsg_arg_t;
/* ARGSUSED */
static int
{
if (!gotid) {
-1) {
mdb_warn("couldn't find struct zfs_dbgmsg");
return (WALK_ERR);
}
mdb_warn("couldn't find zdm_msg");
return (WALK_ERR);
}
off /= 8;
}
return (WALK_ERR);
}
return (DCMD_ERR);
}
if (da->da_address)
if (da->da_verbose)
if (da->da_verbose)
return (WALK_NEXT);
}
/* ARGSUSED */
static int
{
return (DCMD_USAGE);
mdb_warn("can't find zfs_dbgmsgs");
return (DCMD_ERR);
}
mdb_warn("can't walk zfs_dbgmsgs");
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*ARGSUSED*/
static int
{
int nstats, i;
const char *suffix;
static const char *bytestats[] = {
"p", "c", "c_min", "c_max", "size", "duplicate_buffers_size",
"arc_meta_used", "arc_meta_limit", "arc_meta_max",
"arc_meta_min", "hdr_size", "data_size", "metadata_size",
"other_size", "anon_size", "anon_evictable_data",
"anon_evictable_metadata", "mru_size", "mru_evictable_data",
"mru_evictable_metadata", "mru_ghost_size",
"mru_ghost_evictable_data", "mru_ghost_evictable_metadata",
"mfu_size", "mfu_evictable_data", "mfu_evictable_metadata",
"mfu_ghost_size", "mfu_ghost_evictable_data",
"mfu_ghost_evictable_metadata", "evict_l2_cached",
"evict_l2_eligible", "evict_l2_ineligible", "l2_read_bytes",
"l2_write_bytes", "l2_size", "l2_asize", "l2_hdr_size",
"compressed_size", "uncompressed_size", "overhead_size",
};
static const char *extras[] = {
"arc_no_grow", "arc_tempreserve",
};
mdb_warn("failed to find 'arc_stats'");
return (DCMD_ERR);
}
return (DCMD_ERR);
}
/* NB: -a / opt_a are ignored for backwards compatability */
return (DCMD_USAGE);
shift = 20;
switch (shift) {
case 0:
suffix = "B";
break;
case 10:
suffix = "KB";
break;
case 20:
suffix = "MB";
break;
case 30:
suffix = "GB";
break;
default:
suffix = "XX";
}
for (i = 0; i < nstats; i++) {
int j;
for (j = 0; bytestats[j]; j++) {
break;
}
}
if (bytes) {
} else {
}
}
for (i = 0; extras[i]; i++) {
return (DCMD_ERR);
}
mdb_warn("expected scalar for variable '%s'\n",
extras[i]);
return (DCMD_ERR);
}
return (DCMD_ERR);
}
/* NB: all the 64-bit extras happen to be byte counts */
}
return (DCMD_OK);
}
typedef struct mdb_spa_print {
static void
{
int i;
int maxidx = 0;
for (i = 0; i < size; i++) {
maxidx = i;
minidx = i;
}
if (max < histo_width)
max = histo_width;
mdb_printf("%3u: %6llu %s\n",
}
}
typedef struct mdb_metaslab_class {
/*
* spa_class_histogram(uintptr_t class_addr)
*
* Prints free space histogram for a device class
*
* Returns DCMD_OK, or DCMD_ERR.
*/
static int
{
return (DCMD_ERR);
mdb_inc_indent(4);
mdb_dec_indent(4);
return (DCMD_OK);
}
/*
* ::spa
*
* -c Print configuration information as well
* -v Print vdev state
* -e Print vdev error stats
* -m Print vdev metaslab info
* -M print vdev metaslab group info
* -h Print histogram info (must be combined with -m or -M)
*
* Print a summarized spa_t. When given no arguments, prints out a table of all
* active pools on the system.
*/
/* ARGSUSED */
static int
{
"SPARE", "L2CACHE", "UNINIT", "UNAVAIL", "POTENTIAL" };
const char *state;
int spa_flags = 0;
return (DCMD_USAGE);
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("can't walk spa");
return (DCMD_ERR);
}
return (DCMD_OK);
}
if (flags & DCMD_PIPE_OUT) {
return (DCMD_OK);
}
if (DCMD_HDRSPEC(flags))
return (DCMD_ERR);
state = "UNKNOWN";
else
if (spa_flags & SPA_FLAG_HISTOGRAMS)
if (spa_flags & SPA_FLAG_CONFIG) {
mdb_printf("\n");
mdb_inc_indent(4);
return (DCMD_ERR);
mdb_dec_indent(4);
}
if (spa_flags & SPA_FLAG_ALL_VDEV) {
mdb_arg_t v;
int args =
if (spa_flags & SPA_FLAG_ERRORS)
if (spa_flags & SPA_FLAG_METASLABS)
if (spa_flags & SPA_FLAG_HISTOGRAMS)
v.a_type = MDB_TYPE_STRING;
mdb_printf("\n");
mdb_inc_indent(4);
&v) != DCMD_OK)
return (DCMD_ERR);
mdb_dec_indent(4);
}
return (DCMD_OK);
}
typedef struct mdb_spa_config_spa {
/*
* ::spa_config
*
* Given a spa_t, print the configuration information stored in spa_config.
* Since it's just an nvlist, format it as an indented list of name=value pairs.
* We simply read the value of spa_config and pass off to ::nvlist.
*/
/* ARGSUSED */
static int
{
return (DCMD_USAGE);
addr, 0) == -1)
return (DCMD_ERR);
if (spa.spa_config == 0) {
mdb_printf("(none)\n");
return (DCMD_OK);
}
0, NULL));
}
typedef struct mdb_range_tree {
typedef struct mdb_metaslab_group {
typedef struct mdb_metaslab {
typedef struct mdb_space_map_phys_t {
typedef struct mdb_space_map {
typedef struct mdb_vdev {
} mdb_vdev_t;
typedef struct mdb_vdev_ops {
static int
{
return (DCMD_ERR);
}
mdb_inc_indent(4);
"OFFSET", "FREE", "FRAGMENTATION");
return (DCMD_ERR);
}
for (int m = 0; m < vdev.vdev_ms_count; m++) {
return (DCMD_ERR);
return (DCMD_ERR);
else
continue;
}
}
mdb_dec_indent(4);
return (DCMD_OK);
}
static int
{
return (DCMD_ERR);
}
mdb_inc_indent(4);
else
if (spa_flags & SPA_FLAG_HISTOGRAMS)
mdb_dec_indent(4);
return (DCMD_OK);
}
/*
* ::vdev
*
* Print out a summarized vdev_t, in the following form:
*
* ADDR STATE AUX DESC
*
* If '-r' is specified, recursively visit all children.
*
* With '-e', the statistics associated with the vdev are printed as well.
*/
static int
int spa_flags)
{
int c, children;
return (DCMD_ERR);
}
if (flags & DCMD_PIPE_OUT) {
} else {
mdb_warn("failed to read vdev_path at %p\n",
return (DCMD_ERR);
}
mdb_warn("failed to read vdev_ops at %p\n",
return (DCMD_ERR);
}
} else {
}
mdb_printf("%<u>%-?s %-9s %-12s %-*s%</u>\n",
"ADDR", "STATE", "AUX",
"DESCRIPTION");
switch (vdev.vdev_state) {
case VDEV_STATE_CLOSED:
state = "CLOSED";
break;
case VDEV_STATE_OFFLINE:
state = "OFFLINE";
break;
case VDEV_STATE_CANT_OPEN:
state = "CANT_OPEN";
break;
case VDEV_STATE_DEGRADED:
state = "DEGRADED";
break;
case VDEV_STATE_HEALTHY:
state = "HEALTHY";
break;
case VDEV_STATE_REMOVED:
state = "REMOVED";
break;
case VDEV_STATE_FAULTED:
state = "FAULTED";
break;
default:
state = "UNKNOWN";
break;
}
case VDEV_AUX_NONE:
aux = "-";
break;
case VDEV_AUX_OPEN_FAILED:
aux = "OPEN_FAILED";
break;
case VDEV_AUX_CORRUPT_DATA:
aux = "CORRUPT_DATA";
break;
case VDEV_AUX_NO_REPLICAS:
aux = "NO_REPLICAS";
break;
case VDEV_AUX_BAD_GUID_SUM:
aux = "BAD_GUID_SUM";
break;
case VDEV_AUX_TOO_SMALL:
aux = "TOO_SMALL";
break;
case VDEV_AUX_BAD_LABEL:
aux = "BAD_LABEL";
break;
case VDEV_AUX_VERSION_NEWER:
aux = "VERS_NEWER";
break;
case VDEV_AUX_VERSION_OLDER:
aux = "VERS_OLDER";
break;
case VDEV_AUX_UNSUP_FEAT:
aux = "UNSUP_FEAT";
break;
case VDEV_AUX_SPARED:
aux = "SPARED";
break;
case VDEV_AUX_ERR_EXCEEDED:
aux = "ERR_EXCEEDED";
break;
case VDEV_AUX_IO_FAILURE:
aux = "IO_FAILURE";
break;
case VDEV_AUX_BAD_LOG:
aux = "BAD_LOG";
break;
case VDEV_AUX_EXTERNAL:
aux = "EXTERNAL";
break;
case VDEV_AUX_SPLIT_POOL:
aux = "SPLIT_POOL";
break;
default:
aux = "UNKNOWN";
break;
}
if (spa_flags & SPA_FLAG_ERRORS) {
int i;
mdb_inc_indent(4);
mdb_printf("\n");
mdb_printf("%<u> %12s %12s %12s %12s "
"%12s%</u>\n", "READ", "WRITE", "FREE", "CLAIM",
"IOCTL");
mdb_printf("OPS ");
for (i = 1; i < ZIO_TYPES; i++)
mdb_printf("\n");
mdb_printf("BYTES ");
for (i = 1; i < ZIO_TYPES; i++)
mdb_printf("\n");
mdb_printf("ECKSUM %10#llx\n",
mdb_dec_indent(4);
mdb_printf("\n");
}
if (spa_flags & SPA_FLAG_METASLAB_GROUPS &&
}
}
}
return (DCMD_OK);
return (DCMD_ERR);
}
for (c = 0; c < children; c++) {
spa_flags)) {
return (DCMD_ERR);
}
}
return (DCMD_OK);
}
static int
{
int spa_flags = 0;
return (DCMD_USAGE);
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("no vdev_t address given\n");
return (DCMD_ERR);
}
}
typedef struct mdb_metaslab_alloc_trace {
static void
{
if (WEIGHT_IS_SPACEBASED(weight)) {
buf);
} else {
}
}
/* ARGSUSED */
static int
{
char active;
return (DCMD_ERR);
}
} else {
return (DCMD_USAGE);
}
if (DCMD_HDRSPEC(flags)) {
mdb_printf("%<u>%-6s %9s %9s%</u>\n",
"ACTIVE", "ALGORITHM", "WEIGHT");
}
if (weight & METASLAB_WEIGHT_PRIMARY)
active = 'P';
else if (weight & METASLAB_WEIGHT_SECONDARY)
active = 'S';
else
active = '-';
mdb_printf("\n");
return (DCMD_OK);
}
/* ARGSUSED */
static int
{
return (DCMD_ERR);
}
mdb_printf("%<u>%6s %6s %8s %11s %18s %18s%</u>\n",
"MSID", "DVA", "ASIZE", "WEIGHT", "RESULT", "VDEV");
}
return (DCMD_ERR);
}
} else {
}
mdb_warn("Could not find enum for trace_alloc_type");
return (DCMD_ERR);
}
} else {
}
return (DCMD_ERR);
}
return (DCMD_ERR);
}
mdb_warn("failed to read vdev_path at %p\n",
return (DCMD_ERR);
}
char *slash;
} else {
}
mdb_warn("failed to read vdev_ops at %p\n",
return (DCMD_ERR);
}
} else {
}
}
return (DCMD_OK);
}
typedef struct metaslab_walk_data {
int mw_curvdev;
int mw_curms;
static int
{
return (WALK_DONE);
return (WALK_ERR);
}
mssp) == -1) {
return (WALK_ERR);
}
}
mw->mw_curvdev++;
return (WALK_NEXT);
}
return (WALK_ERR);
}
}
static int
{
mdb_warn("must supply address of spa_t\n");
return (WALK_ERR);
}
return (DCMD_ERR);
}
childp) == -1) {
return (DCMD_ERR);
}
return (WALK_NEXT);
}
typedef struct mdb_spa {
} mdb_spa_t;
typedef struct mdb_dsl_pool {
typedef struct mdb_dsl_dir {
typedef struct mdb_dsl_dir_phys {
typedef struct space_data {
} space_data_t;
/* ARGSUSED */
static int
{
int i;
addr, 0) == -1)
return (WALK_ERR);
for (i = 0; i < TXG_SIZE; i++) {
return (WALK_ERR);
return (WALK_ERR);
}
return (WALK_ERR);
return (WALK_ERR);
}
return (WALK_NEXT);
}
/*
* ::spa_space [-b]
*
* Given a spa_t, print out it's on-disk space usage and in-core
* estimates of future usage. If -b is given, print space in bytes.
* Otherwise print in megabytes.
*/
/* ARGSUSED */
static int
{
argc)
return (DCMD_USAGE);
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
if (bytes) {
shift = 0;
suffix = "";
}
addr, 0) == -1 ||
return (DCMD_ERR);
}
mdb_printf("dd_space_towrite = %llu%s %llu%s %llu%s %llu%s\n",
mdb_printf("dd_phys.dd_used_bytes = %llu%s\n",
mdb_printf("dd_phys.dd_compressed_bytes = %llu%s\n",
mdb_printf("dd_phys.dd_uncompressed_bytes = %llu%s\n",
mdb_warn("can't walk metaslabs");
return (DCMD_ERR);
}
mdb_printf("ms_allocmap = %llu%s %llu%s %llu%s %llu%s\n",
mdb_printf("ms_freemap = %llu%s %llu%s %llu%s %llu%s\n",
mdb_printf("ms_deferspace = %llu%s\n",
mdb_printf("current syncing avail = %llu%s\n",
return (DCMD_OK);
}
typedef struct mdb_spa_aux_vdev {
int sav_count;
typedef struct mdb_spa_vdevs {
static int
const char *name)
{
int ret, i;
/*
* Iterate over aux vdevs and print those out as well. This is a
* little annoying because we don't have a root vdev to pass to ::vdev.
* Instead, we print a single line and then call it for each child
* vdev.
*/
mdb_warn("failed to read l2cache vdevs at %p",
return (DCMD_ERR);
}
return (ret);
}
}
}
return (0);
}
/*
* ::spa_vdevs
*
* -e Include error stats
* -m Include metaslab information
* -M Include metaslab group information
* -h Include histogram information (requires -m or -M)
*
* Print out a summarized list of vdevs for the given spa_t.
* This is accomplished by invoking "::vdev -re" on the root vdev, as well as
* iterating over the cache devices.
*/
/* ARGSUSED */
static int
{
mdb_arg_t v[3];
int ret;
int spa_flags = 0;
return (DCMD_USAGE);
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
return (DCMD_ERR);
/*
* Unitialized spa_t structures can have a NULL root vdev.
*/
mdb_printf("no associated vdevs\n");
return (DCMD_OK);
}
if (spa_flags & SPA_FLAG_ERRORS)
if (spa_flags & SPA_FLAG_METASLABS)
if (spa_flags & SPA_FLAG_HISTOGRAMS)
v[0].a_type = MDB_TYPE_STRING;
flags, 1, v);
return (ret);
return (DCMD_ERR);
return (DCMD_OK);
}
/*
* ::zio
*
* Print a summary of zio_t and all its children. This is intended to display a
* zio tree, and hence we only pick the most important pieces of information for
* the main summary. More detailed information can always be found by doing a
* '::print zio' on the underlying zio_t. The columns we display are:
*
* ADDRESS TYPE STAGE WAITER TIME_ELAPSED
*
* The 'address' column is indented by one space for each depth level as we
* descend down the tree.
*/
#define ZIO_WALK_SELF 0
typedef struct zio_print_args {
int zpa_current_depth;
int zpa_min_depth;
int zpa_max_depth;
int zpa_type;
typedef struct mdb_zio {
struct {
struct {
} list_head;
int io_error;
} mdb_zio_t;
typedef struct mdb_zio_timestamp {
static int
{
return (WALK_ERR);
if (indent > ZIO_MAXINDENT)
mdb_warn("failed to lookup zio enums");
return (WALK_ERR);
}
else
type = "?";
else
stage = "?";
} else {
stage = "FAILED";
}
} else {
else
#ifdef _KERNEL
if (zio_timestamp.io_timestamp != 0) {
1000000);
} else {
}
#else
#endif
mdb_printf("\n");
}
}
return (WALK_NEXT);
"io_parent_list");
else
"io_child_list");
zpa->zpa_current_depth++;
return (WALK_ERR);
}
zpa->zpa_current_depth--;
return (WALK_NEXT);
}
/* ARGSUSED */
static int
{
return (WALK_ERR);
}
else
}
/* ARGSUSED */
static int
{
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
return (DCMD_USAGE);
if (zpa.zpa_max_depth != 0) {
}
mdb_printf("%<u>%-*s %-5s %-16s %-16s %-12s%</u>\n",
"TIME_ELAPSED");
}
return (DCMD_ERR);
return (DCMD_OK);
}
/*
* [addr]::zio_state
*
* Print a summary of all zio_t structures on the system, or for a particular
* pool. This is equivalent to '::walk zio_root | ::zio'.
*/
/*ARGSUSED*/
static int
{
/*
* MDB will remember the last address of the pipeline, so if we don't
* zero this we'll end up trying to walk zio structures for a
* non-existent spa_t.
*/
if (!(flags & DCMD_ADDRSPEC))
addr = 0;
}
typedef struct mdb_multilist {
typedef struct multilist_walk_data {
/* ARGSUSED */
static int
{
return (WALK_NEXT);
}
static int
{
return (WALK_DONE);
return (WALK_NEXT);
}
static int
{
mdb_warn("must supply address of multilist_t\n");
return (WALK_ERR);
}
return (WALK_ERR);
}
mdb_warn("invalid or uninitialized multilist at %#lx\n",
return (WALK_ERR);
}
return (WALK_NEXT);
}
typedef struct txg_list_walk_data {
int lw_txgoff;
int lw_maxoff;
void *lw_obj;
static int
{
int i;
return (WALK_ERR);
}
for (i = 0; i < TXG_SIZE; i++)
return (WALK_NEXT);
}
static int
{
}
static int
{
return (txg_list_walk_init_common(wsp, 0, 0));
}
static int
{
}
static int
{
}
static int
{
}
static int
{
int status;
}
return (WALK_DONE);
return (WALK_ERR);
}
return (status);
}
/*
* ::walk spa
*
* Walk all named spa_t structures in the namespace. This is nothing more than
* a layered avl walk.
*/
static int
{
mdb_warn("spa walk only supports global walks\n");
return (WALK_ERR);
}
mdb_warn("failed to find symbol 'spa_namespace_avl'");
return (WALK_ERR);
}
mdb_warn("failed to walk 'avl'\n");
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
}
/*
* [addr]::walk zio
*
* Walk all active zio_t structures on the system. This is simply a layered
* walk on top of ::walk zio_cache, with the optional ability to limit the
* structures to a particular pool.
*/
static int
{
mdb_warn("failed to walk 'zio_cache'\n");
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
return (WALK_ERR);
return (WALK_NEXT);
}
/*
* [addr]::walk zio_root
*
* Walk only root zio_t structures, optionally for a particular spa_t.
*/
static int
{
return (WALK_ERR);
return (WALK_NEXT);
/* If the parent list is not empty, ignore */
return (WALK_NEXT);
}
/*
* ::zfs_blkstats
*
* -v print verbose per-level information
*
*/
static int
{
/* +10 in case it grew */
mdb_warn("failed to read 'dmu_ot'");
return (DCMD_ERR);
}
return (DCMD_USAGE);
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
mdb_printf("maybe no stats? run \"zpool scrub\" first.");
return (DCMD_ERR);
}
mdb_printf("Ganged blocks: %llu\n",
}
if (ditto != 0) {
mdb_printf("Dittoed blocks on same vdev: %llu\n",
(longlong_t)ditto);
}
mdb_printf("\nBlocks\tLSIZE\tPSIZE\tASIZE"
"\t avg\t comp\t%%Total\tType\n");
for (t = 0; t <= DMU_OT_TOTAL; t++) {
int l;
if (t == DMU_OT_DEFERRED)
else if (t == DMU_OT_OTHER)
else if (t == DMU_OT_TOTAL)
mdb_warn("failed to read type name");
return (DCMD_ERR);
}
continue;
for (l = -1; l < DN_MAX_LEVELS; l++) {
continue;
/*
* Don't print each level unless requested.
*/
continue;
/*
* If all the space is level 0, don't print the
* level 0 separately.
*/
continue;
mdb_printf("%6s\t%5s\t%5s\t%5s\t%5s"
"\t%5s\t%6s\t",
if (level == DN_MAX_LEVELS)
else
mdb_printf(" L%d %s\n",
}
}
return (DCMD_OK);
}
typedef struct mdb_reference {
/* ARGSUSED */
static int
{
0) == -1)
return (DCMD_ERR);
if (removed)
mdb_printf("removed ");
mdb_printf("reference ");
if (holder_is_str)
mdb_printf(", held at:\n");
if (removed) {
mdb_printf("removed at:\n");
DCMD_ADDRSPEC, 0, NULL);
}
mdb_printf("\n");
return (WALK_NEXT);
}
typedef struct mdb_refcount {
typedef struct mdb_refcount_removed {
typedef struct mdb_refcount_tracked {
/* ARGSUSED */
static int
{
int off;
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
return (DCMD_USAGE);
0) == -1)
return (DCMD_ERR);
MDB_CTF_VREAD_QUIET) == -1) {
mdb_printf("refcount_t at %p has %llu holds (untracked)\n",
return (DCMD_OK);
}
MDB_CTF_VREAD_QUIET) == -1) {
/* If this is an old target, it might be tracked. */
}
mdb_printf("refcount_t at %p has %llu current holds, "
"%llu recently released holds\n",
mdb_printf("current holds:\n");
if (off == -1)
return (DCMD_ERR);
mdb_printf("released holds:\n");
if (off == -1)
return (DCMD_ERR);
}
return (DCMD_OK);
}
/* ARGSUSED */
static int
{
char *name;
int i;
return (DCMD_ERR);
}
return (DCMD_ERR);
}
mdb_printf("%<u>%-10s %-10s %-10s %-10s %s%</u>\n",
"ATTR ID", "REGISTERED", "LENGTH", "BSWAP", "NAME");
for (i = 0; i != sa_os.sa_num_attrs; i++) {
mdb_printf("%5x %8x %8x %8x %-s\n",
}
return (DCMD_OK);
}
static int
{
mdb_printf("can't find offset table in sa_idx_tab\n");
return (-1);
}
return (-1);
}
return (DCMD_OK);
}
/*ARGSUSED*/
static int
{
int attr_count;
if (argc != 1)
return (DCMD_USAGE);
else
return (DCMD_USAGE);
mdb_printf("Can't find necessary information in sa_handle "
"in sa_handle\n");
return (DCMD_ERR);
}
mdb_printf("Can't find os_sa in objset\n");
return (DCMD_ERR);
}
mdb_printf("Can't find sa_num_attrs\n");
return (DCMD_ERR);
}
if (attr_id > attr_count) {
mdb_printf("attribute id number is out of range\n");
return (DCMD_ERR);
}
if (bonus_tab) {
attr_count) == -1) {
return (DCMD_ERR);
}
mdb_printf("can't find db_data in bonus dbuf\n");
return (DCMD_ERR);
}
}
mdb_printf("Attribute does not exist\n");
return (DCMD_ERR);
attr_count) == -1) {
return (DCMD_ERR);
}
mdb_printf("can't find db_data in spill dbuf\n");
return (DCMD_ERR);
}
mdb_printf("Attribute does not exist\n");
return (DCMD_ERR);
}
}
return (DCMD_OK);
}
/* ARGSUSED */
static int
{
mdb_printf("%<u>%-?s %-8s %-8s %-8s %s%</u>\n",
"ADDR", "FLAGS", "MASK", "TYPE", "ID");
if (!verbose) {
return (DCMD_OK);
}
switch (ace_flags & ACE_TYPE_FLAGS) {
case ACE_OWNER:
mdb_printf("owner@:");
break;
case (ACE_IDENTIFIER_GROUP | ACE_GROUP):
mdb_printf("group@:");
break;
case ACE_EVERYONE:
mdb_printf("everyone@:");
break;
case ACE_IDENTIFIER_GROUP:
break;
case 0: /* User entry */
break;
}
/* print out permission mask */
if (access_mask & ACE_READ_DATA)
mdb_printf("r");
else
mdb_printf("-");
if (access_mask & ACE_WRITE_DATA)
mdb_printf("w");
else
mdb_printf("-");
if (access_mask & ACE_EXECUTE)
mdb_printf("x");
else
mdb_printf("-");
if (access_mask & ACE_APPEND_DATA)
mdb_printf("p");
else
mdb_printf("-");
if (access_mask & ACE_DELETE)
mdb_printf("d");
else
mdb_printf("-");
if (access_mask & ACE_DELETE_CHILD)
mdb_printf("D");
else
mdb_printf("-");
if (access_mask & ACE_READ_ATTRIBUTES)
mdb_printf("a");
else
mdb_printf("-");
if (access_mask & ACE_WRITE_ATTRIBUTES)
mdb_printf("A");
else
mdb_printf("-");
if (access_mask & ACE_READ_NAMED_ATTRS)
mdb_printf("R");
else
mdb_printf("-");
if (access_mask & ACE_WRITE_NAMED_ATTRS)
mdb_printf("W");
else
mdb_printf("-");
if (access_mask & ACE_READ_ACL)
mdb_printf("c");
else
mdb_printf("-");
if (access_mask & ACE_WRITE_ACL)
mdb_printf("C");
else
mdb_printf("-");
if (access_mask & ACE_WRITE_OWNER)
mdb_printf("o");
else
mdb_printf("-");
if (access_mask & ACE_SYNCHRONIZE)
mdb_printf("s");
else
mdb_printf("-");
mdb_printf(":");
/* Print out inheritance flags */
if (ace_flags & ACE_FILE_INHERIT_ACE)
mdb_printf("f");
else
mdb_printf("-");
mdb_printf("d");
else
mdb_printf("-");
if (ace_flags & ACE_INHERIT_ONLY_ACE)
mdb_printf("i");
else
mdb_printf("-");
mdb_printf("n");
else
mdb_printf("-");
mdb_printf("S");
else
mdb_printf("-");
mdb_printf("F");
else
mdb_printf("-");
if (ace_flags & ACE_INHERITED_ACE)
mdb_printf("I");
else
mdb_printf("-");
switch (ace_type) {
mdb_printf(":allow\n");
break;
mdb_printf(":deny\n");
break;
mdb_printf(":audit\n");
break;
mdb_printf(":alarm\n");
break;
default:
mdb_printf(":?\n");
}
return (DCMD_OK);
}
/* ARGSUSED */
static int
{
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
return (DCMD_USAGE);
mdb_warn("failed to read zfs_ace_t");
return (DCMD_ERR);
}
else
id = -1;
}
/* ARGSUSED */
static int
{
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
return (DCMD_USAGE);
mdb_warn("failed to read ace_t");
return (DCMD_ERR);
}
else
id = -1;
}
typedef struct acl_dump_args {
int a_argc;
int a_flags;
/* ARGSUSED */
static int
{
return (WALK_ERR);
}
} else {
return (WALK_ERR);
}
}
return (WALK_NEXT);
}
/* ARGSUSED */
static int
{
mdb_warn("can't walk ACEs");
return (DCMD_ERR);
}
} else {
mdb_warn("can't walk ACEs");
return (DCMD_ERR);
}
}
return (WALK_NEXT);
}
/* ARGSUSED */
static int
{
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
return (DCMD_USAGE);
mdb_warn("failed to read zfs_acl_t");
return (DCMD_ERR);
}
mdb_warn("can't walk ACL");
return (DCMD_ERR);
}
return (DCMD_OK);
}
/* ARGSUSED */
static int
{
mdb_warn("must supply address of zfs_acl_node_t\n");
return (WALK_ERR);
}
mdb_warn("failed to walk 'list'\n");
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
return (WALK_ERR);
}
}
typedef struct ace_walk_data {
int ace_count;
int ace_version;
static int
{
mdb_warn("must supply address of zfs_acl_node_t\n");
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
static int gotid;
int z_ace_count;
if (!gotid) {
if (mdb_ctf_lookup_by_name("struct zfs_acl_node",
&acl_id) == -1) {
mdb_warn("couldn't find struct zfs_acl_node");
return (DCMD_ERR);
}
}
return (DCMD_ERR);
}
return (DCMD_ERR);
}
z_ace_count, z_acldata));
}
/* ARGSUSED */
static int
{
}
/* ARGSUSED */
static int
{
return (zfs_acl_node_aces_walk_init_common(wsp, 0));
}
static int
{
int status;
int entry_type;
int allow_type;
return (WALK_DONE);
mdb_warn("failed to read zfs_ace_t at %#lx",
return (WALK_ERR);
}
switch (ace_data->ace_version) {
case 0:
break;
case 1:
break;
default:
return (WALK_ERR);
}
switch (entry_type) {
case ACE_OWNER:
case ACE_EVERYONE:
case (ACE_IDENTIFIER_GROUP | ACE_GROUP):
sizeof (ace_t) : sizeof (zfs_ace_hdr_t);
break;
case ACE_IDENTIFIER_GROUP:
default:
switch (allow_type) {
sizeof (ace_t) : sizeof (zfs_object_ace_t);
break;
default:
break;
}
}
return (status);
}
typedef struct mdb_zfs_rrwlock {
/* ARGSUSED */
static int
{
if (rrw_key == 0) {
return (DCMD_ERR);
}
0) == -1)
return (DCMD_ERR);
return (DCMD_OK);
}
if (rrw.rr_writer_wanted) {
mdb_printf("writer wanted\n");
}
mdb_printf("anonymous references:\n");
DCMD_ADDRSPEC, 0, NULL);
mdb_printf("linked references:\n");
DCMD_ADDRSPEC, 0, NULL);
/*
* XXX This should find references from
* "::walk thread | ::tsd -v <rrw_key>", but there is no support
* for programmatic consumption of dcmds, so this would be
* difficult, potentially requiring reimplementing ::tsd (both
* user and kernel versions) in this MDB module.
*/
return (DCMD_OK);
}
typedef struct mdb_arc_buf_hdr_t {
struct {
} b_l1hdr;
enum arc_cflags {
};
typedef struct arc_compression_stats_data {
int
{
int h = 1;
if (i == 0)
return (0);
if (i & 0xffffffff00000000ULL) {
h += 32; i >>= 32;
}
if (i & 0xffff0000) {
h += 16; i >>= 16;
}
if (i & 0xff00) {
h += 8; i >>= 8;
}
if (i & 0xf0) {
h += 4; i >>= 4;
}
if (i & 0xc) {
h += 2; i >>= 2;
}
if (i & 0x2) {
h += 1;
}
return (h);
}
/* ARGSUSED */
static int
{
addr, 0) == -1) {
return (WALK_ERR);
}
/*
* Headers in the ghost states, or the l2c_only state don't have
* arc buffers linked off of them. Thus, their compressed size
* is meaningless, so we skip these from the stats.
*/
return (WALK_NEXT);
}
/*
* The physical size (compressed) and logical size
* (uncompressed) are in units of SPA_MINBLOCKSIZE. By default,
* we use the log2 of this value (rounded down to the nearest
* integer) to determine the bucket to assign this header to.
* Thus, the histogram is logarithmic with respect to the size
* of the header. For example, the following is a mapping of the
* bucket numbers and the range of header sizes they correspond to:
*
* 0: 0 byte headers
* 1: 512 byte headers
* 2: [1024 - 2048) byte headers
* 3: [2048 - 4096) byte headers
* 4: [4096 - 8192) byte headers
* 5: [8192 - 16394) byte headers
* 6: [16384 - 32768) byte headers
* 7: [32768 - 65536) byte headers
* 8: [65536 - 131072) byte headers
* 9: 131072 byte headers
*
* If the ARC_CFLAG_VERBOSE flag was specified, we use the
* physical and logical sizes directly. Thus, the histogram will
* no longer be logarithmic; instead it will be linear with
* respect to the size of the header. The following is a mapping
* of the first many bucket numbers and the header size they
* correspond to:
*
* 0: 0 byte headers
* 1: 512 byte headers
* 2: 1024 byte headers
* 3: 1536 byte headers
* 4: 2048 byte headers
* 5: 2560 byte headers
* 6: 3072 byte headers
*
* And so on. Keep in mind that a range of sizes isn't used in
* the case of linear scale because the headers can only
* increment or decrement in sizes of 512 bytes. So, it's not
* possible for a header to be sized in between whats listed
* above.
*
* Also, the above mapping values were calculated assuming a
* SPA_MINBLOCKSHIFT of 512 bytes and a SPA_MAXBLOCKSIZE of 128K.
*/
} else {
}
/* Ensure we stay within the bounds of the histogram array */
}
return (WALK_NEXT);
}
/* ARGSUSED */
static int
{
unsigned int hist_size;
return (DCMD_USAGE);
mdb_warn("can't find arc state symbol");
return (DCMD_ERR);
}
/*
* Determine the maximum expected size for any header, and use
* this to determine the number of buckets needed for each
* histogram. If ARC_CFLAG_VERBOSE is specified, this value is
* used directly; otherwise the log2 of the maximum size is
* used. Thus, if using a log2 scale there's a maximum of 10
* possible buckets, while the linear scale (when using
* ARC_CFLAG_VERBOSE) has a maximum of 257 buckets.
*/
else
&data) != 0) {
mdb_warn("can't walk arc_buf_hdr's");
goto out;
}
"[n*%llu, (n+1)*%llu)", SPA_MINBLOCKSIZE,
} else {
"[2^(n-1)*%llu, 2^n*%llu)", SPA_MINBLOCKSIZE,
}
if (rc < 0) {
/* snprintf failed, abort the dcmd */
goto out;
} else {
/* snprintf succeeded above, reset return code */
}
mdb_printf("Histogram of the number of anon buffers "
"that are associated with an arc hdr.\n");
mdb_printf("\n");
}
mdb_printf("Histogram of compressed anon buffers.\n"
"Each bucket represents buffers of size: %s.\n", range);
mdb_printf("\n");
mdb_printf("Histogram of uncompressed anon buffers.\n"
"Each bucket represents buffers of size: %s.\n", range);
mdb_printf("\n");
}
mdb_printf("Histogram of the number of mru buffers "
"that are associated with an arc hdr.\n");
mdb_printf("\n");
}
mdb_printf("Histogram of compressed mru buffers.\n"
"Each bucket represents buffers of size: %s.\n", range);
mdb_printf("\n");
mdb_printf("Histogram of uncompressed mru buffers.\n"
"Each bucket represents buffers of size: %s.\n", range);
mdb_printf("\n");
}
mdb_printf("Histogram of the number of mfu buffers "
"that are associated with an arc hdr.\n");
mdb_printf("\n");
}
mdb_printf("Histogram of compressed mfu buffers.\n"
"Each bucket represents buffers of size: %s.\n", range);
mdb_printf("\n");
mdb_printf("Histogram of uncompressed mfu buffers.\n"
"Each bucket represents buffers of size: %s.\n", range);
mdb_printf("\n");
}
mdb_printf("Histogram of all buffers that "
"are associated with an arc hdr.\n");
mdb_printf("\n");
}
mdb_printf("Histogram of all compressed buffers.\n"
"Each bucket represents buffers of size: %s.\n", range);
mdb_printf("\n");
mdb_printf("Histogram of all uncompressed buffers.\n"
"Each bucket represents buffers of size: %s.\n", range);
out:
return (rc);
}
/*
* MDB module linkage information:
*
* We declare a list of structures describing our dcmds, and a function
* named _mdb_init to return a pointer to our module information.
*/
{ "dbufs",
"\t[-O objset_t*] [-n objset_name | \"mos\"] "
"[-o object | \"mdn\"] \n"
"\t[-l level] [-b blkid | \"bonus\"]",
"find dmu_buf_impl_t's that match specified criteria", dbufs },
{ "abuf_find", "dva_word[0] dva_word[1]",
"find arc_buf_hdr_t of a specified DVA",
abuf_find },
{ "spa", "?[-cevmMh]\n"
"\t-c display spa config\n"
"\t-e display vdev statistics\n"
"\t-v display vdev information\n"
"\t-m display metaslab statistics\n"
"\t-M display metaslab group statistics\n"
"\t-h display histogram (requires -m or -M)\n",
"spa_t summary", spa_print },
{ "spa_vdevs", ":[-emMh]\n"
"\t-e display vdev statistics\n"
"\t-m dispaly metaslab statistics\n"
"\t-M display metaslab group statistic\n"
"\t-h display histogram (requires -m or -M)\n",
"given a spa_t, print vdev summary", spa_vdevs },
{ "vdev", ":[-remMh]\n"
"\t-r display recursively\n"
"\t-e display statistics\n"
"\t-m display metaslab statistics (top level vdev only)\n"
"\t-M display metaslab group statistics (top level vdev only)\n"
"\t-h display histogram (requires -m or -M)\n",
"vdev_t summary", vdev_print },
{ "zio", ":[-cpr]\n"
"\t-c display children\n"
"\t-p display parents\n"
"\t-r display recursively",
"zio_t summary", zio_print },
{ "zio_state", "?", "print out all zio_t structures on system or "
"for a particular pool", zio_state },
{ "zfs_blkstats", ":[-v]",
"given a spa_t, print block type stats from last scrub",
zfs_blkstats },
{ "refcount", ":[-r]\n"
"\t-r display recently removed references",
"print refcount_t holders", refcount },
{ "zfs_aces", ":[-v]", "print all ACEs from a zfs_acl_t",
zfs_acl_dump },
{ "sa_attr_table", ":", "print SA attribute table from sa_os_t",
{ "sa_attr", ": attr_id",
"print SA attribute address when given sa_handle_t", sa_attr_print},
{ "zfs_dbgmsg", ":[-va]",
"print zfs debug log", dbgmsg},
{ "rrwlock", ":",
"print rrwlock_t, including readers", rrwlock},
{ "metaslab_weight", "weight",
"print metaslab weight", metaslab_weight},
{ "metaslab_trace", ":",
"print metaslab allocation trace records", metaslab_trace},
{ "arc_compression_stats", ":[-vabrf]\n"
"\t-v verbose, display a linearly scaled histogram\n"
"\t-a display ARC_anon state statistics individually\n"
"\t-r display ARC_mru state statistics individually\n"
"\t-f display ARC_mfu state statistics individually\n"
"\t-b display histogram of buffer counts\n",
"print a histogram of compressed arc buffer sizes",
{ NULL }
};
{ "zms_freelist", "walk ZFS metaslab freelist",
{ "txg_list", "given any txg_list_t *, walk all entries in all txgs",
{ "txg_list0", "given any txg_list_t *, walk all entries in txg 0",
{ "txg_list1", "given any txg_list_t *, walk all entries in txg 1",
{ "txg_list2", "given any txg_list_t *, walk all entries in txg 2",
{ "txg_list3", "given any txg_list_t *, walk all entries in txg 3",
{ "zio", "walk all zio structures, optionally for a particular spa_t",
{ "zio_root",
"walk all root zio_t structures, optionally for a particular spa_t",
{ "spa", "walk all spa_t entries in the namespace",
{ "metaslab", "given a spa_t *, walk all metaslab_t structures",
{ "multilist", "given a multilist_t *, walk all list_t structures",
{ "zfs_acl_node", "given a zfs_acl_t, walk all zfs_acl_nodes",
{ "zfs_acl_node_aces", "given a zfs_acl_node_t, walk all ACEs",
{ "zfs_acl_node_aces0",
"given a zfs_acl_node_t, walk all ACEs as ace_t",
{ NULL }
};
};
const mdb_modinfo_t *
_mdb_init(void)
{
return (&modinfo);
}