zfs.c revision 5f5f7a6f9c8e9c1587a54e690556d756ec67558c
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Common Development and Distribution License (the "License").
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens#pragma ident "%Z%%M% %I% %E% SMI"
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include "../genunix/list.h"
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic char *
fa9e4066f08beec538e775443c5be79dd423fcabahrenslocal_strdup(const char *s)
fa9e4066f08beec538e775443c5be79dd423fcabahrensgetmember(uintptr_t addr, const char *type, mdb_ctf_id_t *idp,
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("couldn't find member %s of type %s\n", member, type);
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("member %s of type %s is unsupported bitfield",
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* mdb_warn("read %s from %s at %p+%llx\n", member, type, addr, off); */
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens getmember(addr, #type, NULL, #member, sizeof (dest), &(dest))
fa9e4066f08beec538e775443c5be79dd423fcabahrens getmember(addr, NULL, ctfid, #member, sizeof (dest), &(dest))
fa9e4066f08beec538e775443c5be79dd423fcabahrens static int gotid;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_ctf_lookup_by_name("struct refcount", &rc_id) == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("couldn't find member %s of type %s\n", member, name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (GETMEMBID(addr + off, &rc_id, rc_count, *rc));
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_lookup_by_obj(MDB_TGT_OBJ_EVERY, sym_name, &sym)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_vread(*bufp, sym.st_size, sym.st_value) == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID" };
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_vread(&entry, sizeof (entry), wsp->walk_addr) == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("failed to read freelist entry %p", wsp->walk_addr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_printf("Entry: %3u offsets=%08llx-%08llx type=%c "
fa9e4066f08beec538e775443c5be79dd423fcabahrens static int gotid;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens static int gotid;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (GETMEMBID(addr, &osi_id, os_dsl_dataset, os_dsl_dataset))
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (GETMEMBID(os_dsl_dataset, &ds_id, ds_snapname, ds_snapname) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrensenum_lookup(char *out, size_t size, mdb_ctf_id_t id, int val,
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *prefix)
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *cp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrenszio_pipeline(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_ctf_lookup_by_name("enum zio_stage", &pipe_enum) == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < 32; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ZIO_STAGE_");
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensblkptr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (read_symbol("dmu_ot", (void **)&doti) != DCMD_OK)
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < DMU_OT_NUMTYPES; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_readstr(buf, sizeof (buf), (uintptr_t)doti[i].ot_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (read_symbol("zio_checksum_table", (void **)&zci) != DCMD_OK)
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < ZIO_CHECKSUM_FUNCTIONS; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_readstr(buf, sizeof (buf), (uintptr_t)zci[i].ci_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (read_symbol("zio_compress_table", (void **)&zct) != DCMD_OK)
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < ZIO_COMPRESS_FUNCTIONS; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_readstr(buf, sizeof (buf), (uintptr_t)zct[i].ci_name);
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm * Super-ick warning: This code is also duplicated in
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm * cmd/zdb.c . Yeah, I hate code replication, too.
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm "ASIZE: %llx\n", i, DVA_GET_GANG(dva) ? "TRUE" : "FALSE",
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm DVA_GET_VDEV(dva), DVA_GET_OFFSET(dva), BP_GET_PSIZE(&bp),
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm !DVA_GET_GANG(dva) && BP_GET_LEVEL(&bp) != 0 ? "i" : "",
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_printf("BIRTH: %-16llx LEVEL: %-2d\tFILL: %llx\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensdbuf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_ctf_lookup_by_name("struct dmu_buf_impl", &id) == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) mdb_snprintf(objectname, sizeof (objectname), "%llx",
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) mdb_snprintf(blkidname, sizeof (blkidname), "%llx",
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensdbuf_stats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < HISTOSZ; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (bucket = 0; bucket < ht.hash_table_mask+1; bucket++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (dbp != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_printf("hash table has %llu buckets, %llu dbufs "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "(avg %llu buckets/dbuf)\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < HISTOSZ; i++)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (histo[i] > 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i <= maxidx; i++)
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < HISTOSZ; i++)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (histo2[i] > 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i <= maxidx; i++)
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct dbufs_data {
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensdbufs_cb(uintptr_t addr, const void *unknown, void *arg)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((data->objset == DBUFS_UNSET || data->objset == objset) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens (data->osname == NULL || (objset_name(objset, osname) == 0 &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens (data->object == DBUFS_UNSET || data->object == db.db_object) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens (data->level == DBUFS_UNSET || data->level == level) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens (data->blkid == DBUFS_UNSET || data->blkid == blkid)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensdbufs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens data.objset = data.object = data.level = data.blkid = DBUFS_UNSET;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_ctf_lookup_by_name("struct dmu_buf_impl", &data.id) == -1) {
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens if (mdb_walk("dmu_buf_impl_t", dbufs_cb, &data) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct abuf_find_data {
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensabuf_find_cb(uintptr_t addr, const void *unknown, void *arg)
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensabuf_find(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *syms[] = {
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ARC_mru_top",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ARC_mru_bot",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ARC_mfu_top",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ARC_mfu_bot",
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < 2; i ++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens data.dva.dva_word[i] = mdb_strtoull(argv[i].a_un.a_str);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_ctf_lookup_by_name("struct arc_buf_hdr", &data.id) == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < sizeof (syms) / sizeof (syms[0]); i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_pwalk("list", abuf_find_cb, &data, sym.st_value) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -c Print configuration information as well
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -v Print vdev state
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -e Print vdev error stats
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Print a summarized spa_t. When given no arguments, prints out a table of all
fa9e4066f08beec538e775443c5be79dd423fcabahrens * active pools on the system.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensspa_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *statetab[] = { "ACTIVE", "EXPORTED", "DESTROYED",
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *state;
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_printf("%<u>%-?s %9s %-*s%</u>\n", "ADDR", "STATE",
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_readstr(poolname, sizeof (poolname), (uintptr_t)spa.spa_name)
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("failed to read pool name at %p", spa.spa_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (spa.spa_state < 0 || spa.spa_state > POOL_STATE_UNAVAIL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_call_dcmd("spa_vdevs", addr, flags, errors ? 1 : 0,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ::spa_config
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a spa_t, print the configuration information stored in spa_config.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Since it's just an nvlist, format it as an indented list of name=value pairs.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We simply read the value of spa_config and pass off to ::nvlist.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensspa_print_config(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (mdb_call_dcmd("nvlist", (uintptr_t)spa.spa_config, flags,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t-> -q display vdev_queue parameters\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t-> -r recursive (visit all children)\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Print out a summarized vdev_t, in the following form:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ADDR STATE AUX DESC
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fffffffbcde23df0 HEALTHY - /dev/dsk/c0t0d0
fa9e4066f08beec538e775443c5be79dd423fcabahrens * or with "-q" to print out a vdev_t's vdev_queue parameters:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * vdev_t: c26ae4c0
fa9e4066f08beec538e775443c5be79dd423fcabahrens * c26ae73c min pending 0x2
fa9e4066f08beec538e775443c5be79dd423fcabahrens * c26ae744 max pending 0x23
fa9e4066f08beec538e775443c5be79dd423fcabahrens * c26ae74c agg limit 0x20000
fa9e4066f08beec538e775443c5be79dd423fcabahrens * c26ae754 time shift 0x4
fa9e4066f08beec538e775443c5be79dd423fcabahrens * c26ae75c ramp rate 0x2
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If '-r' is specified, recursively visit all children.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * With '-e', the statistics associated with the vdev are printed as well.
fa9e4066f08beec538e775443c5be79dd423fcabahrensdo_print_vdev(uintptr_t addr, int flags, int depth, int queue, int stats,
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_vread(&vdev, sizeof (vdev), (uintptr_t)addr) == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("failed to read vdev_t at %p\n", (uintptr_t)addr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens "DESCRIPTION");
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_printf("%-9s %-12s %*s%s\n", state, aux, depth, "", desc);
fa9e4066f08beec538e775443c5be79dd423fcabahrens child = mdb_alloc(children * sizeof (void *), UM_SLEEP | UM_GC);
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("failed to read vdev children at %p", vdev.vdev_child);
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < children; c++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (do_print_vdev(child[c], flags, depth + 2, queue, stats,
fa9e4066f08beec538e775443c5be79dd423fcabahrensvdev_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (do_print_vdev(addr, flags, 0, print_queue, stats, recursive));
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrenstypedef struct metaslab_walk_data {
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens GETMEMB(vdevp, struct vdev, vdev_ms_count, mw->mw_nummss)) {
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens mw->mw_mss = mdb_alloc(mw->mw_nummss * sizeof (void*),
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens if (mdb_vread(mw->mw_mss, mw->mw_nummss * sizeof (void*),
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens if (mdb_vread(&ms, sizeof (metaslab_t), msp) == -1) {
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens return (wsp->walk_callback(msp, &ms, wsp->walk_cbdata));
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens/* ARGSUSED */
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens mw = mdb_zalloc(sizeof (metaslab_walk_data_t), UM_SLEEP | UM_GC);
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens if (GETMEMB(wsp->walk_addr, struct spa, spa_root_vdev, root_vdevp) ||
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens GETMEMB(root_vdevp, struct vdev, vdev_children, mw->mw_numvdevs) ||
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens GETMEMB(root_vdevp, struct vdev, vdev_child, childp)) {
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens mw->mw_vdevs = mdb_alloc(mw->mw_numvdevs * sizeof (void *),
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens if (mdb_vread(mw->mw_vdevs, mw->mw_numvdevs * sizeof (void *),
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens mdb_warn("failed to read root vdev children at %p", childp);
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct mdb_spa {
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct mdb_dsl_dir {
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct mdb_dsl_dir_phys {
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct mdb_vdev {
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct mdb_metaslab {
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrenstypedef struct space_data {
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens/* ARGSUSED */
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrensspace_cb(uintptr_t addr, const void *unknown, void *arg)
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens if (GETMEMB(addr, struct metaslab, ms_allocmap, ms.ms_allocmap) ||
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens GETMEMB(addr, struct metaslab, ms_freemap, ms.ms_freemap) ||
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens GETMEMB(addr, struct metaslab, ms_smo_syncing, ms.ms_smo_syncing)) {
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens sd->avail += ms.ms_map.sm_size - ms.ms_smo.smo_alloc;
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens sd->nowavail += ms.ms_map.sm_size - ms.ms_smo_syncing.smo_alloc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ::spa_space [-b]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a spa_t, print out it's on-disk space usage and in-core
fa9e4066f08beec538e775443c5be79dd423fcabahrens * estimates of future usage. If -b is given, print space in bytes.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Otherwise print in megabytes.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensspa_space(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_getopts(argc, argv, 'b', MDB_OPT_SETBITS, TRUE, &bits, NULL) !=
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (GETMEMB(addr, struct spa, spa_dsl_pool, spa.spa_dsl_pool) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens GETMEMB(addr, struct spa, spa_root_vdev, spa.spa_root_vdev) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens GETMEMB(spa.spa_root_vdev, struct vdev, vdev_children, children) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens GETMEMB(spa.spa_root_vdev, struct vdev, vdev_child, childaddr) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens GETMEMB(dp_root_dir, struct dsl_dir, dd_phys, dd.dd_phys) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_printf("dd_space_towrite = %llu%s %llu%s %llu%s %llu%s\n",
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens mdb_printf("dd_phys.dd_uncompressed_bytes = %llu%s\n",
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens if (mdb_pwalk("metaslab", space_cb, &sd, addr) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_printf("ms_allocmap = %llu%s %llu%s %llu%s %llu%s\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_printf("ms_freemap = %llu%s %llu%s %llu%s %llu%s\n",
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens mdb_printf("ms_map = %llu%s\n", sd.ms_map >> shift, suffix);
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens mdb_printf("last synced avail = %llu%s\n", sd.avail >> shift, suffix);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ::spa_verify
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a spa_t, verify that that the pool is self-consistent.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Currently, it only checks to make sure that the vdev tree exists.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensspa_verify(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ::spa_vdevs
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -e Include error stats
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Print out a summarized list of vdevs for the given spa_t.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This is accomplished by invoking "::vdev -re" on the root vdev.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensspa_vdevs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * Unitialized spa_t structures can have a NULL root vdev.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (mdb_call_dcmd("vdev", (uintptr_t)spa.spa_root_vdev,
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct txg_list_walk_data {
fa9e4066f08beec538e775443c5be79dd423fcabahrenstxg_list_walk_init_common(mdb_walk_state_t *wsp, int txg, int maxoff)
fa9e4066f08beec538e775443c5be79dd423fcabahrens lwd = mdb_alloc(sizeof (txg_list_walk_data_t), UM_SLEEP | UM_GC);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_vread(&list, sizeof (txg_list_t), wsp->walk_addr) == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("failed to read txg_list_t at %#lx", wsp->walk_addr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < TXG_SIZE; i++)
fa9e4066f08beec538e775443c5be79dd423fcabahrens lwd->lw_obj = mdb_alloc(lwd->lw_offset + sizeof (txg_node_t),
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (txg_list_walk_init_common(wsp, 0, TXG_SIZE-1));
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (wsp->walk_addr == NULL && lwd->lw_txgoff < lwd->lw_maxoff) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("failed to read list element at %#lx", addr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens status = wsp->walk_callback(addr, lwd->lw_obj, wsp->walk_cbdata);
fa9e4066f08beec538e775443c5be79dd423fcabahrens node = (txg_node_t *)((uintptr_t)lwd->lw_obj + lwd->lw_offset);
fa9e4066f08beec538e775443c5be79dd423fcabahrens wsp->walk_addr = (uintptr_t)node->tn_next[lwd->lw_txgoff];
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ::walk spa
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Walk all named spa_t structures in the namespace. This is nothing more than
fa9e4066f08beec538e775443c5be79dd423fcabahrens * a layered avl walk.
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_lookup_by_obj(ZFS_OBJ_NAME, "spa_namespace_avl", &sym) == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("failed to find symbol 'spa_namespace_avl'");
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mdb_vread(&spa, sizeof (spa), wsp->walk_addr) == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mdb_warn("failed to read spa_t at %p", wsp->walk_addr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (wsp->walk_callback(wsp->walk_addr, &spa, wsp->walk_cbdata));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * MDB module linkage information:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We declare a list of structures describing our dcmds, and a function
fa9e4066f08beec538e775443c5be79dd423fcabahrens * named _mdb_init to return a pointer to our module information.
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t[-O objset_t*] [-n objset_name | \"mos\"] [-o object | \"mdn\"] \n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t[-l level] [-b blkid | \"bonus\"]",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "find dmu_buf_impl_t's that meet criterion", dbufs },
fa9e4066f08beec538e775443c5be79dd423fcabahrens "find arc_buf_hdr_t of a specified DVA",
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "spa_config", ":", "print spa_t configuration", spa_print_config },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "spa_verify", ":", "verify spa_t consistency", spa_verify },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "spa_space", ":[-b]", "print spa_t on-disk space usage", spa_space },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "spa_vdevs", ":", "given a spa_t, print vdev summary", spa_vdevs },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "zio_pipeline", ":", "decode a zio pipeline", zio_pipeline },
fa9e4066f08beec538e775443c5be79dd423fcabahrens * In userland, there is no generic provider of list_t walkers, so we
fa9e4066f08beec538e775443c5be79dd423fcabahrens * need to add it.
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "txg_list", "given any txg_list_t *, walk all entries in all txgs",
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "txg_list0", "given any txg_list_t *, walk all entries in txg 0",
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "txg_list1", "given any txg_list_t *, walk all entries in txg 1",
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "txg_list2", "given any txg_list_t *, walk all entries in txg 2",
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "txg_list3", "given any txg_list_t *, walk all entries in txg 3",
5f5f7a6f9c8e9c1587a54e690556d756ec67558cahrens { "metaslab", "given a spa_t *, walk all metaslab_t structures",