zdb.c revision 0e60744c982adecd0a1f146f5637475d07ab1069
1fa9e406ahrens/*
2fa9e406ahrens * CDDL HEADER START
3fa9e406ahrens *
4fa9e406ahrens * The contents of this file are subject to the terms of the
5ea8dc4beschrock * Common Development and Distribution License (the "License").
6ea8dc4beschrock * You may not use this file except in compliance with the License.
7fa9e406ahrens *
8fa9e406ahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e406ahrens * or http://www.opensolaris.org/os/licensing.
10fa9e406ahrens * See the License for the specific language governing permissions
11fa9e406ahrens * and limitations under the License.
12fa9e406ahrens *
13fa9e406ahrens * When distributing Covered Code, include this CDDL HEADER in each
14fa9e406ahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e406ahrens * If applicable, add the following below this CDDL HEADER, with the
16fa9e406ahrens * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e406ahrens * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e406ahrens *
19fa9e406ahrens * CDDL HEADER END
20fa9e406ahrens */
21ad135b5Christopher Siden
22fa9e406ahrens/*
238f2529dMark Shellenbaum * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2429bdd2fPavel Zakharov * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
25c3d26abMatthew Ahrens * Copyright (c) 2014 Integros [integros.com]
26fa9e406ahrens */
27fa9e406ahrens
28fa9e406ahrens#include <stdio.h>
29490d05bMatthew Ahrens#include <unistd.h>
30004388ecasper#include <stdio_ext.h>
31fa9e406ahrens#include <stdlib.h>
3244cd46cbillm#include <ctype.h>
33fa9e406ahrens#include <sys/zfs_context.h>
34fa9e406ahrens#include <sys/spa.h>
35fa9e406ahrens#include <sys/spa_impl.h>
36fa9e406ahrens#include <sys/dmu.h>
37fa9e406ahrens#include <sys/zap.h>
38fa9e406ahrens#include <sys/fs/zfs.h>
39fa9e406ahrens#include <sys/zfs_znode.h>
400a586ceMark Shellenbaum#include <sys/zfs_sa.h>
410a586ceMark Shellenbaum#include <sys/sa.h>
420a586ceMark Shellenbaum#include <sys/sa_impl.h>
43fa9e406ahrens#include <sys/vdev.h>
44fa9e406ahrens#include <sys/vdev_impl.h>
45fa9e406ahrens#include <sys/metaslab_impl.h>
46fa9e406ahrens#include <sys/dmu_objset.h>
47fa9e406ahrens#include <sys/dsl_dir.h>
48fa9e406ahrens#include <sys/dsl_dataset.h>
49fa9e406ahrens#include <sys/dsl_pool.h>
50fa9e406ahrens#include <sys/dbuf.h>
51fa9e406ahrens#include <sys/zil.h>
52fa9e406ahrens#include <sys/zil_impl.h>
53fa9e406ahrens#include <sys/stat.h>
54fa9e406ahrens#include <sys/resource.h>
55fa9e406ahrens#include <sys/dmu_traverse.h>
56fa9e406ahrens#include <sys/zio_checksum.h>
57fa9e406ahrens#include <sys/zio_compress.h>
58e0d35c4marks#include <sys/zfs_fuid.h>
5988b7b0fMatthew Ahrens#include <sys/arc.h>
60b24ab67Jeff Bonwick#include <sys/ddt.h>
61ad135b5Christopher Siden#include <sys/zfeature.h>
624445fffMatthew Ahrens#include <zfs_comutil.h>
63de6628fck#undef verify
64de6628fck#include <libzfs.h>
65fa9e406ahrens
66e690fb2Christopher Siden#define	ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ?	\
67e690fb2Christopher Siden	zio_compress_table[(idx)].ci_name : "UNKNOWN")
68e690fb2Christopher Siden#define	ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ?	\
69e690fb2Christopher Siden	zio_checksum_table[(idx)].ci_name : "UNKNOWN")
70e690fb2Christopher Siden#define	ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ?	\
71e690fb2Christopher Siden	dmu_ot[(idx)].ot_name : DMU_OT_IS_VALID(idx) ?	\
72e690fb2Christopher Siden	dmu_ot_byteswap[DMU_OT_BYTESWAP(idx)].ob_name : "UNKNOWN")
73e690fb2Christopher Siden#define	ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) :		\
74e690fb2Christopher Siden	(((idx) == DMU_OTN_ZAP_DATA || (idx) == DMU_OTN_ZAP_METADATA) ?	\
75e690fb2Christopher Siden	DMU_OT_ZAP_OTHER : DMU_OT_NUMTYPES))
766de8f41Victor Latushkin
77feef89cVictor Latushkin#ifndef lint
787fd05acMatthew Ahrensextern boolean_t zfs_recover;
7906be980Matthew Ahrensextern uint64_t zfs_arc_max, zfs_arc_meta_limit;
80f7950bfMatthew Ahrensextern int zfs_vdev_async_read_max_active;
81feef89cVictor Latushkin#else
827fd05acMatthew Ahrensboolean_t zfs_recover;
8306be980Matthew Ahrensuint64_t zfs_arc_max, zfs_arc_meta_limit;
84f7950bfMatthew Ahrensint zfs_vdev_async_read_max_active;
85feef89cVictor Latushkin#endif
86feef89cVictor Latushkin
87fa9e406ahrensconst char cmdname[] = "zdb";
88fa9e406ahrensuint8_t dump_opt[256];
89fa9e406ahrens
90fa9e406ahrenstypedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
91fa9e406ahrens
92fa9e406ahrensextern void dump_intent_log(zilog_t *);
93fa9e406ahrensuint64_t *zopt_object = NULL;
94fa9e406ahrensint zopt_objects = 0;
95de6628fcklibzfs_handle_t *g_zfs;
9606be980Matthew Ahrensuint64_t max_inflight = 1000;
97fa9e406ahrens
98732885fMatthew Ahrensstatic void snprintf_blkptr_compact(char *, size_t, const blkptr_t *);
99732885fMatthew Ahrens
100fa9e406ahrens/*
101fa9e406ahrens * These libumem hooks provide a reasonable set of defaults for the allocator's
102fa9e406ahrens * debugging facilities.
103fa9e406ahrens */
104fa9e406ahrensconst char *
105fa9e406ahrens_umem_debug_init()
106fa9e406ahrens{
107fa9e406ahrens	return ("default,verbose"); /* $UMEM_DEBUG setting */
108fa9e406ahrens}
109fa9e406ahrens
110fa9e406ahrensconst char *
111fa9e406ahrens_umem_logging_init(void)
112fa9e406ahrens{
113fa9e406ahrens	return ("fail,contents"); /* $UMEM_LOGGING setting */
114fa9e406ahrens}
115fa9e406ahrens
116fa9e406ahrensstatic void
117fa9e406ahrensusage(void)
118fa9e406ahrens{
119fa9e406ahrens	(void) fprintf(stderr,
12029bdd2fPavel Zakharov	    "Usage: %s [-CumMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] "
1210e60744Pavel Zakharov	    "[-U config] [-I inflight I/Os] [-x dumpdir] [-o var=value] "
1220e60744Pavel Zakharov	    "poolname [object...]\n"
12331d7e8fGeorge Wilson	    "       %s [-divPA] [-e -p path...] [-U config] dataset "
12431d7e8fGeorge Wilson	    "[object...]\n"
1252e4c998George Wilson	    "       %s -mM [-LXFPA] [-t txg] [-e [-p path...]] [-U config] "
12690e894eRichard Lowe	    "poolname [vdev [metaslab...]]\n"
12790e894eRichard Lowe	    "       %s -R [-A] [-e [-p path...]] poolname "
12890e894eRichard Lowe	    "vdev:offset:size[:flags]\n"
12931d7e8fGeorge Wilson	    "       %s -S [-PA] [-e [-p path...]] [-U config] poolname\n"
13090e894eRichard Lowe	    "       %s -l [-uA] device\n"
13190e894eRichard Lowe	    "       %s -C [-A] [-U config]\n\n",
132bbfd46cJeff Bonwick	    cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
1333ad6c7fVictor Latushkin
1343ad6c7fVictor Latushkin	(void) fprintf(stderr, "    Dataset name must include at least one "
1353ad6c7fVictor Latushkin	    "separator character '/' or '@'\n");
1363ad6c7fVictor Latushkin	(void) fprintf(stderr, "    If dataset name is specified, only that "
1373ad6c7fVictor Latushkin	    "dataset is dumped\n");
1383ad6c7fVictor Latushkin	(void) fprintf(stderr, "    If object numbers are specified, only "
1393ad6c7fVictor Latushkin	    "those objects are dumped\n\n");
1403ad6c7fVictor Latushkin	(void) fprintf(stderr, "    Options to control amount of output:\n");
1413ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -u uberblock\n");
1423ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -d dataset(s)\n");
1433ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -i intent logs\n");
14407428bdVictor Latushkin	(void) fprintf(stderr, "        -C config (or cachefile if alone)\n");
1458f18d1fGeorge Wilson	(void) fprintf(stderr, "        -h pool history\n");
1463ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -b block statistics\n");
1473ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -m metaslabs\n");
1482e4c998George Wilson	(void) fprintf(stderr, "        -M metaslab groups\n");
1493ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -c checksum all metadata (twice for "
1506365109Victor Latushkin	    "all data) blocks\n");
1513ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -s report stats on zdb's I/O\n");
152f0ba89bJeff Bonwick	(void) fprintf(stderr, "        -D dedup statistics\n");
153b24ab67Jeff Bonwick	(void) fprintf(stderr, "        -S simulate dedup to measure effect\n");
1543ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -v verbose (applies to all others)\n");
155fa9e406ahrens	(void) fprintf(stderr, "        -l dump label contents\n");
15682a0a98Victor Latushkin	(void) fprintf(stderr, "        -L disable leak tracking (do not "
15782a0a98Victor Latushkin	    "load spacemaps)\n");
158d41e764ek	(void) fprintf(stderr, "        -R read and display block from a "
1593ad6c7fVictor Latushkin	    "device\n\n");
1603ad6c7fVictor Latushkin	(void) fprintf(stderr, "    Below options are intended for use "
161df15e41Matthew Ahrens	    "with other options:\n");
162feef89cVictor Latushkin	(void) fprintf(stderr, "        -A ignore assertions (-A), enable "
163feef89cVictor Latushkin	    "panic recovery (-AA) or both (-AAA)\n");
164c8ee184Victor Latushkin	(void) fprintf(stderr, "        -F attempt automatic rewind within "
165c8ee184Victor Latushkin	    "safe range of transaction groups\n");
1663ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -U <cachefile_path> -- use alternate "
1673ad6c7fVictor Latushkin	    "cachefile\n");
168c8ee184Victor Latushkin	(void) fprintf(stderr, "        -X attempt extreme rewind (does not "
169c8ee184Victor Latushkin	    "work with dataset)\n");
1703ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -e pool is exported/destroyed/"
1713ad6c7fVictor Latushkin	    "has altroot/not in a cachefile\n");
1723ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -p <path> -- use one or more with "
1733ad6c7fVictor Latushkin	    "-e to specify path to vdev dir\n");
174df15e41Matthew Ahrens	(void) fprintf(stderr, "        -x <dumpdir> -- "
175df15e41Matthew Ahrens	    "dump all read blocks into specified directory\n");
17690e894eRichard Lowe	(void) fprintf(stderr, "        -P print numbers in parseable form\n");
1773ad6c7fVictor Latushkin	(void) fprintf(stderr, "        -t <txg> -- highest txg to use when "
1782e55192Victor Latushkin	    "searching for uberblocks\n");
1792e4c998George Wilson	(void) fprintf(stderr, "        -I <number of inflight I/Os> -- "
180df15e41Matthew Ahrens	    "specify the maximum number of "
181df15e41Matthew Ahrens	    "checksumming I/Os [default is 200]\n");
18229bdd2fPavel Zakharov	(void) fprintf(stderr, "        -G dump zfs_dbgmsg buffer before "
18329bdd2fPavel Zakharov	    "exiting\n");
1840e60744Pavel Zakharov	(void) fprintf(stderr, "        -o <variable>=<value> set global "
1850e60744Pavel Zakharov	    "variable to an unsigned 32-bit integer value\n");
186fa9e406ahrens	(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
187fa9e406ahrens	    "to make only that option verbose\n");
188fa9e406ahrens	(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
189fa9e406ahrens	exit(1);
190fa9e406ahrens}
191fa9e406ahrens
19229bdd2fPavel Zakharovstatic void
19329bdd2fPavel Zakharovdump_debug_buffer()
19429bdd2fPavel Zakharov{
19529bdd2fPavel Zakharov	if (dump_opt['G']) {
19629bdd2fPavel Zakharov		(void) printf("\n");
19729bdd2fPavel Zakharov		zfs_dbgmsg_print("zdb");
19829bdd2fPavel Zakharov	}
19929bdd2fPavel Zakharov}
20029bdd2fPavel Zakharov
201ccba080Rich Morris/*
202ccba080Rich Morris * Called for usage errors that are discovered after a call to spa_open(),
203ccba080Rich Morris * dmu_bonus_hold(), or pool_match().  abort() is called for other errors.
204ccba080Rich Morris */
205ccba080Rich Morris
206fa9e406ahrensstatic void
207fa9e406ahrensfatal(const char *fmt, ...)
208fa9e406ahrens{
209fa9e406ahrens	va_list ap;
210fa9e406ahrens
211fa9e406ahrens	va_start(ap, fmt);
212fa9e406ahrens	(void) fprintf(stderr, "%s: ", cmdname);
213fa9e406ahrens	(void) vfprintf(stderr, fmt, ap);
214fa9e406ahrens	va_end(ap);
215fa9e406ahrens	(void) fprintf(stderr, "\n");
216fa9e406ahrens
21729bdd2fPavel Zakharov	dump_debug_buffer();
21829bdd2fPavel Zakharov
219ccba080Rich Morris	exit(1);
220fa9e406ahrens}
221fa9e406ahrens
222fa9e406ahrens/* ARGSUSED */
223fa9e406ahrensstatic void
224fa9e406ahrensdump_packed_nvlist(objset_t *os, uint64_t object, void *data, size_t size)
225fa9e406ahrens{
226fa9e406ahrens	nvlist_t *nv;
227fa9e406ahrens	size_t nvsize = *(uint64_t *)data;
228fa9e406ahrens	char *packed = umem_alloc(nvsize, UMEM_NOFAIL);
229fa9e406ahrens
2307bfdf01Neil Perrin	VERIFY(0 == dmu_read(os, object, 0, nvsize, packed, DMU_READ_PREFETCH));
231fa9e406ahrens
232fa9e406ahrens	VERIFY(nvlist_unpack(packed, nvsize, &nv, 0) == 0);
233fa9e406ahrens
234fa9e406ahrens	umem_free(packed, nvsize);
235fa9e406ahrens
236fa9e406ahrens	dump_nvlist(nv, 8);
237fa9e406ahrens
238fa9e406ahrens	nvlist_free(nv);
239fa9e406ahrens}
240fa9e406ahrens
2414445fffMatthew Ahrens/* ARGSUSED */
2424445fffMatthew Ahrensstatic void
2434445fffMatthew Ahrensdump_history_offsets(objset_t *os, uint64_t object, void *data, size_t size)
2444445fffMatthew Ahrens{
2454445fffMatthew Ahrens	spa_history_phys_t *shp = data;
2464445fffMatthew Ahrens
2474445fffMatthew Ahrens	if (shp == NULL)
2484445fffMatthew Ahrens		return;
2494445fffMatthew Ahrens
2504445fffMatthew Ahrens	(void) printf("\t\tpool_create_len = %llu\n",
2514445fffMatthew Ahrens	    (u_longlong_t)shp->sh_pool_create_len);
2524445fffMatthew Ahrens	(void) printf("\t\tphys_max_off = %llu\n",
2534445fffMatthew Ahrens	    (u_longlong_t)shp->sh_phys_max_off);
2544445fffMatthew Ahrens	(void) printf("\t\tbof = %llu\n",
2554445fffMatthew Ahrens	    (u_longlong_t)shp->sh_bof);
2564445fffMatthew Ahrens	(void) printf("\t\teof = %llu\n",
2574445fffMatthew Ahrens	    (u_longlong_t)shp->sh_eof);
2584445fffMatthew Ahrens	(void) printf("\t\trecords_lost = %llu\n",
2594445fffMatthew Ahrens	    (u_longlong_t)shp->sh_records_lost);
2604445fffMatthew Ahrens}
2614445fffMatthew Ahrens
2623f9d6adLin Lingstatic void
2633f9d6adLin Lingzdb_nicenum(uint64_t num, char *buf)
2643f9d6adLin Ling{
2653f9d6adLin Ling	if (dump_opt['P'])
2663f9d6adLin Ling		(void) sprintf(buf, "%llu", (longlong_t)num);
2673f9d6adLin Ling	else
2683f9d6adLin Ling		nicenum(num, buf);
2693f9d6adLin Ling}
2703f9d6adLin Ling
271490d05bMatthew Ahrensconst char histo_stars[] = "****************************************";
272490d05bMatthew Ahrensconst int histo_width = sizeof (histo_stars) - 1;
273fa9e406ahrens
274fa9e406ahrensstatic void
2750713e23George Wilsondump_histogram(const uint64_t *histo, int size, int offset)
276fa9e406ahrens{
277fa9e406ahrens	int i;
278490d05bMatthew Ahrens	int minidx = size - 1;
279fa9e406ahrens	int maxidx = 0;
280fa9e406ahrens	uint64_t max = 0;
281fa9e406ahrens
282490d05bMatthew Ahrens	for (i = 0; i < size; i++) {
283fa9e406ahrens		if (histo[i] > max)
284fa9e406ahrens			max = histo[i];
285fa9e406ahrens		if (histo[i] > 0 && i > maxidx)
286fa9e406ahrens			maxidx = i;
287fa9e406ahrens		if (histo[i] > 0 && i < minidx)
288fa9e406ahrens			minidx = i;
289fa9e406ahrens	}
290fa9e406ahrens
291490d05bMatthew Ahrens	if (max < histo_width)
292490d05bMatthew Ahrens		max = histo_width;
293fa9e406ahrens
294490d05bMatthew Ahrens	for (i = minidx; i <= maxidx; i++) {
295490d05bMatthew Ahrens		(void) printf("\t\t\t%3u: %6llu %s\n",
2960713e23George Wilson		    i + offset, (u_longlong_t)histo[i],
297490d05bMatthew Ahrens		    &histo_stars[(max - histo[i]) * histo_width / max]);
298490d05bMatthew Ahrens	}
299fa9e406ahrens}
300fa9e406ahrens
301fa9e406ahrensstatic void
302fa9e406ahrensdump_zap_stats(objset_t *os, uint64_t object)
303fa9e406ahrens{
304fa9e406ahrens	int error;
305fa9e406ahrens	zap_stats_t zs;
306fa9e406ahrens
307fa9e406ahrens	error = zap_get_stats(os, object, &zs);
308fa9e406ahrens	if (error)
309fa9e406ahrens		return;
310fa9e406ahrens
311fa9e406ahrens	if (zs.zs_ptrtbl_len == 0) {
312fa9e406ahrens		ASSERT(zs.zs_num_blocks == 1);
313fa9e406ahrens		(void) printf("\tmicrozap: %llu bytes, %llu entries\n",
314fa9e406ahrens		    (u_longlong_t)zs.zs_blocksize,
315fa9e406ahrens		    (u_longlong_t)zs.zs_num_entries);
316fa9e406ahrens		return;
317fa9e406ahrens	}
318fa9e406ahrens
319fa9e406ahrens	(void) printf("\tFat ZAP stats:\n");
3208248818nd
3218248818nd	(void) printf("\t\tPointer table:\n");
3228248818nd	(void) printf("\t\t\t%llu elements\n",
323fa9e406ahrens	    (u_longlong_t)zs.zs_ptrtbl_len);
3248248818nd	(void) printf("\t\t\tzt_blk: %llu\n",
3258248818nd	    (u_longlong_t)zs.zs_ptrtbl_zt_blk);
3268248818nd	(void) printf("\t\t\tzt_numblks: %llu\n",
3278248818nd	    (u_longlong_t)zs.zs_ptrtbl_zt_numblks);
3288248818nd	(void) printf("\t\t\tzt_shift: %llu\n",
3298248818nd	    (u_longlong_t)zs.zs_ptrtbl_zt_shift);
3308248818nd	(void) printf("\t\t\tzt_blks_copied: %llu\n",
3318248818nd	    (u_longlong_t)zs.zs_ptrtbl_blks_copied);
3328248818nd	(void) printf("\t\t\tzt_nextblk: %llu\n",
3338248818nd	    (u_longlong_t)zs.zs_ptrtbl_nextblk);
3348248818nd
335fa9e406ahrens	(void) printf("\t\tZAP entries: %llu\n",
336fa9e406ahrens	    (u_longlong_t)zs.zs_num_entries);
337fa9e406ahrens	(void) printf("\t\tLeaf blocks: %llu\n",
338fa9e406ahrens	    (u_longlong_t)zs.zs_num_leafs);
339fa9e406ahrens	(void) printf("\t\tTotal blocks: %llu\n",
340fa9e406ahrens	    (u_longlong_t)zs.zs_num_blocks);
3418248818nd	(void) printf("\t\tzap_block_type: 0x%llx\n",
3428248818nd	    (u_longlong_t)zs.zs_block_type);
3438248818nd	(void) printf("\t\tzap_magic: 0x%llx\n",
3448248818nd	    (u_longlong_t)zs.zs_magic);
3458248818nd	(void) printf("\t\tzap_salt: 0x%llx\n",
3468248818nd	    (u_longlong_t)zs.zs_salt);
347fa9e406ahrens
348fa9e406ahrens	(void) printf("\t\tLeafs with 2^n pointers:\n");
3490713e23George Wilson	dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE, 0);
350fa9e406ahrens
351fa9e406ahrens	(void) printf("\t\tBlocks with n*5 entries:\n");
3520713e23George Wilson	dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE, 0);
353fa9e406ahrens
354fa9e406ahrens	(void) printf("\t\tBlocks n/10 full:\n");
3550713e23George Wilson	dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE, 0);
356fa9e406ahrens
357fa9e406ahrens	(void) printf("\t\tEntries with n chunks:\n");
3580713e23George Wilson	dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE, 0);
359fa9e406ahrens
360fa9e406ahrens	(void) printf("\t\tBuckets with n entries:\n");
3610713e23George Wilson	dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE, 0);
362fa9e406ahrens}
363fa9e406ahrens
364fa9e406ahrens/*ARGSUSED*/
365fa9e406ahrensstatic void
366fa9e406ahrensdump_none(objset_t *os, uint64_t object, void *data, size_t size)
367fa9e406ahrens{
368fa9e406ahrens}
369fa9e406ahrens
370fa9e406ahrens/*ARGSUSED*/
3716de8f41Victor Latushkinstatic void
3726de8f41Victor Latushkindump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
3736de8f41Victor Latushkin{
3746de8f41Victor Latushkin	(void) printf("\tUNKNOWN OBJECT TYPE\n");
3756de8f41Victor Latushkin}
3766de8f41Victor Latushkin
3776de8f41Victor Latushkin/*ARGSUSED*/
378fa9e406ahrensvoid
379fa9e406ahrensdump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
380fa9e406ahrens{
381fa9e406ahrens}
382fa9e406ahrens
383fa9e406ahrens/*ARGSUSED*/
384fa9e406ahrensstatic void
385fa9e406ahrensdump_uint64(objset_t *os, uint64_t object, void *data, size_t size)
386fa9e406ahrens{
387fa9e406ahrens}
388fa9e406ahrens
389fa9e406ahrens/*ARGSUSED*/
390fa9e406ahrensstatic void
391fa9e406ahrensdump_zap(objset_t *os, uint64_t object, void *data, size_t size)
392fa9e406ahrens{
393fa9e406ahrens	zap_cursor_t zc;
394fa9e406ahrens	zap_attribute_t attr;
395fa9e406ahrens	void *prop;
396fa9e406ahrens	int i;
397fa9e406ahrens
398fa9e406ahrens	dump_zap_stats(os, object);
399fa9e406ahrens	(void) printf("\n");
400fa9e406ahrens
401fa9e406ahrens	for (zap_cursor_init(&zc, os, object);
402fa9e406ahrens	    zap_cursor_retrieve(&zc, &attr) == 0;
403fa9e406ahrens	    zap_cursor_advance(&zc)) {
404fa9e406ahrens		(void) printf("\t\t%s = ", attr.za_name);
405fa9e406ahrens		if (attr.za_num_integers == 0) {
406fa9e406ahrens			(void) printf("\n");
407fa9e406ahrens			continue;
408fa9e406ahrens		}
409fa9e406ahrens		prop = umem_zalloc(attr.za_num_integers *
410fa9e406ahrens		    attr.za_integer_length, UMEM_NOFAIL);
411fa9e406ahrens		(void) zap_lookup(os, object, attr.za_name,
412fa9e406ahrens		    attr.za_integer_length, attr.za_num_integers, prop);
413fa9e406ahrens		if (attr.za_integer_length == 1) {
414fa9e406ahrens			(void) printf("%s", (char *)prop);
415fa9e406ahrens		} else {
416fa9e406ahrens			for (i = 0; i < attr.za_num_integers; i++) {
417fa9e406ahrens				switch (attr.za_integer_length) {
418fa9e406ahrens				case 2:
419fa9e406ahrens					(void) printf("%u ",
420fa9e406ahrens					    ((uint16_t *)prop)[i]);
421fa9e406ahrens					break;
422fa9e406ahrens				case 4:
423fa9e406ahrens					(void) printf("%u ",
424fa9e406ahrens					    ((uint32_t *)prop)[i]);
425fa9e406ahrens					break;
426fa9e406ahrens				case 8:
427fa9e406ahrens					(void) printf("%lld ",
428fa9e406ahrens					    (u_longlong_t)((int64_t *)prop)[i]);
429fa9e406ahrens					break;
430fa9e406ahrens				}
431fa9e406ahrens			}
432fa9e406ahrens		}
433fa9e406ahrens		(void) printf("\n");
434fa9e406ahrens		umem_free(prop, attr.za_num_integers * attr.za_integer_length);
435fa9e406ahrens	}
43687e5029ahrens	zap_cursor_fini(&zc);
437fa9e406ahrens}
438fa9e406ahrens
439732885fMatthew Ahrensstatic void
440732885fMatthew Ahrensdump_bpobj(objset_t *os, uint64_t object, void *data, size_t size)
441732885fMatthew Ahrens{
442732885fMatthew Ahrens	bpobj_phys_t *bpop = data;
443732885fMatthew Ahrens	char bytes[32], comp[32], uncomp[32];
444732885fMatthew Ahrens
445732885fMatthew Ahrens	if (bpop == NULL)
446732885fMatthew Ahrens		return;
447732885fMatthew Ahrens
448732885fMatthew Ahrens	zdb_nicenum(bpop->bpo_bytes, bytes);
449732885fMatthew Ahrens	zdb_nicenum(bpop->bpo_comp, comp);
450732885fMatthew Ahrens	zdb_nicenum(bpop->bpo_uncomp, uncomp);
451732885fMatthew Ahrens
452732885fMatthew Ahrens	(void) printf("\t\tnum_blkptrs = %llu\n",
453732885fMatthew Ahrens	    (u_longlong_t)bpop->bpo_num_blkptrs);
454732885fMatthew Ahrens	(void) printf("\t\tbytes = %s\n", bytes);
455732885fMatthew Ahrens	if (size >= BPOBJ_SIZE_V1) {
456732885fMatthew Ahrens		(void) printf("\t\tcomp = %s\n", comp);
457732885fMatthew Ahrens		(void) printf("\t\tuncomp = %s\n", uncomp);
458732885fMatthew Ahrens	}
459732885fMatthew Ahrens	if (size >= sizeof (*bpop)) {
460732885fMatthew Ahrens		(void) printf("\t\tsubobjs = %llu\n",
461732885fMatthew Ahrens		    (u_longlong_t)bpop->bpo_subobjs);
462732885fMatthew Ahrens		(void) printf("\t\tnum_subobjs = %llu\n",
463732885fMatthew Ahrens		    (u_longlong_t)bpop->bpo_num_subobjs);
464732885fMatthew Ahrens	}
465732885fMatthew Ahrens
466732885fMatthew Ahrens	if (dump_opt['d'] < 5)
467732885fMatthew Ahrens		return;
468732885fMatthew Ahrens
469732885fMatthew Ahrens	for (uint64_t i = 0; i < bpop->bpo_num_blkptrs; i++) {
470732885fMatthew Ahrens		char blkbuf[BP_SPRINTF_LEN];
471732885fMatthew Ahrens		blkptr_t bp;
472732885fMatthew Ahrens
473732885fMatthew Ahrens		int err = dmu_read(os, object,
474732885fMatthew Ahrens		    i * sizeof (bp), sizeof (bp), &bp, 0);
475732885fMatthew Ahrens		if (err != 0) {
476732885fMatthew Ahrens			(void) printf("got error %u from dmu_read\n", err);
477732885fMatthew Ahrens			break;
478732885fMatthew Ahrens		}
479732885fMatthew Ahrens		snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), &bp);
480732885fMatthew Ahrens		(void) printf("\t%s\n", blkbuf);
481732885fMatthew Ahrens	}
482732885fMatthew Ahrens}
483732885fMatthew Ahrens
484732885fMatthew Ahrens/* ARGSUSED */
485732885fMatthew Ahrensstatic void
486732885fMatthew Ahrensdump_bpobj_subobjs(objset_t *os, uint64_t object, void *data, size_t size)
487732885fMatthew Ahrens{
488732885fMatthew Ahrens	dmu_object_info_t doi;
489732885fMatthew Ahrens
490732885fMatthew Ahrens	VERIFY0(dmu_object_info(os, object, &doi));
491732885fMatthew Ahrens	uint64_t *subobjs = kmem_alloc(doi.doi_max_offset, KM_SLEEP);
492732885fMatthew Ahrens
493732885fMatthew Ahrens	int err = dmu_read(os, object, 0, doi.doi_max_offset, subobjs, 0);
494732885fMatthew Ahrens	if (err != 0) {
495732885fMatthew Ahrens		(void) printf("got error %u from dmu_read\n", err);
496732885fMatthew Ahrens		kmem_free(subobjs, doi.doi_max_offset);
497732885fMatthew Ahrens		return;
498732885fMatthew Ahrens	}
499732885fMatthew Ahrens
500732885fMatthew Ahrens	int64_t last_nonzero = -1;
501732885fMatthew Ahrens	for (uint64_t i = 0; i < doi.doi_max_offset / 8; i++) {
502732885fMatthew Ahrens		if (subobjs[i] != 0)
503732885fMatthew Ahrens			last_nonzero = i;
504732885fMatthew Ahrens	}
505732885fMatthew Ahrens
506732885fMatthew Ahrens	for (int64_t i = 0; i <= last_nonzero; i++) {
507732885fMatthew Ahrens		(void) printf("\t%llu\n", (longlong_t)subobjs[i]);
508732885fMatthew Ahrens	}
509732885fMatthew Ahrens	kmem_free(subobjs, doi.doi_max_offset);
510732885fMatthew Ahrens}
511732885fMatthew Ahrens
512e743726ahrens/*ARGSUSED*/
513e743726ahrensstatic void
514486ae71Matthew Ahrensdump_ddt_zap(objset_t *os, uint64_t object, void *data, size_t size)
515486ae71Matthew Ahrens{
516486ae71Matthew Ahrens	dump_zap_stats(os, object);
517486ae71Matthew Ahrens	/* contents are printed elsewhere, properly decoded */
518486ae71Matthew Ahrens}
519486ae71Matthew Ahrens
520486ae71Matthew Ahrens/*ARGSUSED*/
521486ae71Matthew Ahrensstatic void
5220a586ceMark Shellenbaumdump_sa_attrs(objset_t *os, uint64_t object, void *data, size_t size)
5230a586ceMark Shellenbaum{
5240a586ceMark Shellenbaum	zap_cursor_t zc;
5250a586ceMark Shellenbaum	zap_attribute_t attr;
5260a586ceMark Shellenbaum
5270a586ceMark Shellenbaum	dump_zap_stats(os, object);
5280a586ceMark Shellenbaum	(void) printf("\n");
5290a586ceMark Shellenbaum
5300a586ceMark Shellenbaum	for (zap_cursor_init(&zc, os, object);
5310a586ceMark Shellenbaum	    zap_cursor_retrieve(&zc, &attr) == 0;
5320a586ceMark Shellenbaum	    zap_cursor_advance(&zc)) {
5330a586ceMark Shellenbaum		(void) printf("\t\t%s = ", attr.za_name);
5340a586ceMark Shellenbaum		if (attr.za_num_integers == 0) {
5350a586ceMark Shellenbaum			(void) printf("\n");
5360a586ceMark Shellenbaum			continue;
5370a586ceMark Shellenbaum		}
5380a586ceMark Shellenbaum		(void) printf(" %llx : [%d:%d:%d]\n",
5390a586ceMark Shellenbaum		    (u_longlong_t)attr.za_first_integer,
5400a586ceMark Shellenbaum		    (int)ATTR_LENGTH(attr.za_first_integer),
5410a586ceMark Shellenbaum		    (int)ATTR_BSWAP(attr.za_first_integer),
5420a586ceMark Shellenbaum		    (int)ATTR_NUM(attr.za_first_integer));
5430a586ceMark Shellenbaum	}
5440a586ceMark Shellenbaum	zap_cursor_fini(&zc);
5450a586ceMark Shellenbaum}
5460a586ceMark Shellenbaum
5470a586ceMark Shellenbaum/*ARGSUSED*/
5480a586ceMark Shellenbaumstatic void
5490a586ceMark Shellenbaumdump_sa_layouts(objset_t *os, uint64_t object, void *data, size_t size)
5500a586ceMark Shellenbaum{
5510a586ceMark Shellenbaum	zap_cursor_t zc;
5520a586ceMark Shellenbaum	zap_attribute_t attr;
5530a586ceMark Shellenbaum	uint16_t *layout_attrs;
5540a586ceMark Shellenbaum	int i;
5550a586ceMark Shellenbaum
5560a586ceMark Shellenbaum	dump_zap_stats(os, object);
5570a586ceMark Shellenbaum	(void) printf("\n");
5580a586ceMark Shellenbaum
5590a586ceMark Shellenbaum	for (zap_cursor_init(&zc, os, object);
5600a586ceMark Shellenbaum	    zap_cursor_retrieve(&zc, &attr) == 0;
5610a586ceMark Shellenbaum	    zap_cursor_advance(&zc)) {
5620a586ceMark Shellenbaum		(void) printf("\t\t%s = [", attr.za_name);
5630a586ceMark Shellenbaum		if (attr.za_num_integers == 0) {
5640a586ceMark Shellenbaum			(void) printf("\n");
5650a586ceMark Shellenbaum			continue;
5660a586ceMark Shellenbaum		}
5670a586ceMark Shellenbaum
5680a586ceMark Shellenbaum		VERIFY(attr.za_integer_length == 2);
5690a586ceMark Shellenbaum		layout_attrs = umem_zalloc(attr.za_num_integers *
5700a586ceMark Shellenbaum		    attr.za_integer_length, UMEM_NOFAIL);
5710a586ceMark Shellenbaum
5720a586ceMark Shellenbaum		VERIFY(zap_lookup(os, object, attr.za_name,
5730a586ceMark Shellenbaum		    attr.za_integer_length,
5740a586ceMark Shellenbaum		    attr.za_num_integers, layout_attrs) == 0);
5750a586ceMark Shellenbaum
5760a586ceMark Shellenbaum		for (i = 0; i != attr.za_num_integers; i++)
5770a586ceMark Shellenbaum			(void) printf(" %d ", (int)layout_attrs[i]);
5780a586ceMark Shellenbaum		(void) printf("]\n");
5790a586ceMark Shellenbaum		umem_free(layout_attrs,
5800a586ceMark Shellenbaum		    attr.za_num_integers * attr.za_integer_length);
5810a586ceMark Shellenbaum	}
5820a586ceMark Shellenbaum	zap_cursor_fini(&zc);
5830a586ceMark Shellenbaum}
5840a586ceMark Shellenbaum
5850a586ceMark Shellenbaum/*ARGSUSED*/
5860a586ceMark Shellenbaumstatic void
587e743726ahrensdump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
588e743726ahrens{
589e743726ahrens	zap_cursor_t zc;
590e743726ahrens	zap_attribute_t attr;
591e743726ahrens	const char *typenames[] = {
592e743726ahrens		/* 0 */ "not specified",
593e743726ahrens		/* 1 */ "FIFO",
594e743726ahrens		/* 2 */ "Character Device",
595e743726ahrens		/* 3 */ "3 (invalid)",
596e743726ahrens		/* 4 */ "Directory",
597e743726ahrens		/* 5 */ "5 (invalid)",
598e743726ahrens		/* 6 */ "Block Device",
599e743726ahrens		/* 7 */ "7 (invalid)",
600e743726ahrens		/* 8 */ "Regular File",
601e743726ahrens		/* 9 */ "9 (invalid)",
602e743726ahrens		/* 10 */ "Symbolic Link",
603e743726ahrens		/* 11 */ "11 (invalid)",
604e743726ahrens		/* 12 */ "Socket",
605e743726ahrens		/* 13 */ "Door",
606e743726ahrens		/* 14 */ "Event Port",
607e743726ahrens		/* 15 */ "15 (invalid)",
608e743726ahrens	};
609e743726ahrens
610e743726ahrens	dump_zap_stats(os, object);
611e743726ahrens	(void) printf("\n");
612e743726ahrens
613e743726ahrens	for (zap_cursor_init(&zc, os, object);
614e743726ahrens	    zap_cursor_retrieve(&zc, &attr) == 0;
615e743726ahrens	    zap_cursor_advance(&zc)) {
616e743726ahrens		(void) printf("\t\t%s = %lld (type: %s)\n",
617e743726ahrens		    attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
618e743726ahrens		    typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
619e743726ahrens	}
620e743726ahrens	zap_cursor_fini(&zc);
621e743726ahrens}
622e743726ahrens
6230713e23George Wilsonint
6240713e23George Wilsonget_dtl_refcount(vdev_t *vd)
6250713e23George Wilson{
6260713e23George Wilson	int refcount = 0;
6270713e23George Wilson
6280713e23George Wilson	if (vd->vdev_ops->vdev_op_leaf) {
6290713e23George Wilson		space_map_t *sm = vd->vdev_dtl_sm;
6300713e23George Wilson
6310713e23George Wilson		if (sm != NULL &&
6320713e23George Wilson		    sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
6330713e23George Wilson			return (1);
6340713e23George Wilson		return (0);
6350713e23George Wilson	}
6360713e23George Wilson
6370713e23George Wilson	for (int c = 0; c < vd->vdev_children; c++)
6380713e23George Wilson		refcount += get_dtl_refcount(vd->vdev_child[c]);
6390713e23George Wilson	return (refcount);
6400713e23George Wilson}
6410713e23George Wilson
6420713e23George Wilsonint
6430713e23George Wilsonget_metaslab_refcount(vdev_t *vd)
6440713e23George Wilson{
6450713e23George Wilson	int refcount = 0;
6460713e23George Wilson
6472e4c998George Wilson	if (vd->vdev_top == vd && !vd->vdev_removing) {
6480713e23George Wilson		for (int m = 0; m < vd->vdev_ms_count; m++) {
6490713e23George Wilson			space_map_t *sm = vd->vdev_ms[m]->ms_sm;
6500713e23George Wilson
6510713e23George Wilson			if (sm != NULL &&
6520713e23George Wilson			    sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
6530713e23George Wilson				refcount++;
6540713e23George Wilson		}
6550713e23George Wilson	}
6560713e23George Wilson	for (int c = 0; c < vd->vdev_children; c++)
6570713e23George Wilson		refcount += get_metaslab_refcount(vd->vdev_child[c]);
6580713e23George Wilson
6590713e23George Wilson	return (refcount);
6600713e23George Wilson}
6610713e23George Wilson
6620713e23George Wilsonstatic int
6630713e23George Wilsonverify_spacemap_refcounts(spa_t *spa)
6640713e23George Wilson{
6652acef22Matthew Ahrens	uint64_t expected_refcount = 0;
6662acef22Matthew Ahrens	uint64_t actual_refcount;
6670713e23George Wilson
6682acef22Matthew Ahrens	(void) feature_get_refcount(spa,
6692acef22Matthew Ahrens	    &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM],
6702acef22Matthew Ahrens	    &expected_refcount);
6710713e23George Wilson	actual_refcount = get_dtl_refcount(spa->spa_root_vdev);
6720713e23George Wilson	actual_refcount += get_metaslab_refcount(spa->spa_root_vdev);
6730713e23George Wilson
6740713e23George Wilson	if (expected_refcount != actual_refcount) {
6752acef22Matthew Ahrens		(void) printf("space map refcount mismatch: expected %lld != "
6762acef22Matthew Ahrens		    "actual %lld\n",
6772acef22Matthew Ahrens		    (longlong_t)expected_refcount,
6782acef22Matthew Ahrens		    (longlong_t)actual_refcount);
6790713e23George Wilson		return (2);
6800713e23George Wilson	}
6810713e23George Wilson	return (0);
6820713e23George Wilson}
6830713e23George Wilson
684fa9e406ahrensstatic void
6850713e23George Wilsondump_spacemap(objset_t *os, space_map_t *sm)
686fa9e406ahrens{
687fa9e406ahrens	uint64_t alloc, offset, entry;
6888053a26ck	char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
6898053a26ck			    "INVALID", "INVALID", "INVALID", "INVALID" };
690fa9e406ahrens
6910713e23George Wilson	if (sm == NULL)
692fa9e406ahrens		return;
693fa9e406ahrens
694fa9e406ahrens	/*
695fa9e406ahrens	 * Print out the freelist entries in both encoded and decoded form.
696fa9e406ahrens	 */
697fa9e406ahrens	alloc = 0;
6980713e23George Wilson	for (offset = 0; offset < space_map_length(sm);
6990713e23George Wilson	    offset += sizeof (entry)) {
7000713e23George Wilson		uint8_t mapshift = sm->sm_shift;
7010713e23George Wilson
7020713e23George Wilson		VERIFY0(dmu_read(os, space_map_object(sm), offset,
7037bfdf01Neil Perrin		    sizeof (entry), &entry, DMU_READ_PREFETCH));
704fa9e406ahrens		if (SM_DEBUG_DECODE(entry)) {
7050713e23George Wilson
70687219dbVictor Latushkin			(void) printf("\t    [%6llu] %s: txg %llu, pass %llu\n",
707fa9e406ahrens			    (u_longlong_t)(offset / sizeof (entry)),
708fa9e406ahrens			    ddata[SM_DEBUG_ACTION_DECODE(entry)],
7095ad8204nd			    (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
7105ad8204nd			    (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
711fa9e406ahrens		} else {
71287219dbVictor Latushkin			(void) printf("\t    [%6llu]    %c  range:"
71387219dbVictor Latushkin			    " %010llx-%010llx  size: %06llx\n",
714fa9e406ahrens			    (u_longlong_t)(offset / sizeof (entry)),
715fa9e406ahrens			    SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
7165ad8204nd			    (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
7170713e23George Wilson			    mapshift) + sm->sm_start),
7185ad8204nd			    (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
7190713e23George Wilson			    mapshift) + sm->sm_start +
7200713e23George Wilson			    (SM_RUN_DECODE(entry) << mapshift)),
7215ad8204nd			    (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
722fa9e406ahrens			if (SM_TYPE_DECODE(entry) == SM_ALLOC)
723fa9e406ahrens				alloc += SM_RUN_DECODE(entry) << mapshift;
724fa9e406ahrens			else
725fa9e406ahrens				alloc -= SM_RUN_DECODE(entry) << mapshift;
726fa9e406ahrens		}
727fa9e406ahrens	}
7280713e23George Wilson	if (alloc != space_map_allocated(sm)) {
729fa9e406ahrens		(void) printf("space_map_object alloc (%llu) INCONSISTENT "
730fa9e406ahrens		    "with space map summary (%llu)\n",
7310713e23George Wilson		    (u_longlong_t)space_map_allocated(sm), (u_longlong_t)alloc);
732fa9e406ahrens	}
733fa9e406ahrens}
734fa9e406ahrens
735fa9e406ahrensstatic void
736d6e555bGeorge Wilsondump_metaslab_stats(metaslab_t *msp)
737d6e555bGeorge Wilson{
7383f9d6adLin Ling	char maxbuf[32];
7390713e23George Wilson	range_tree_t *rt = msp->ms_tree;
7400713e23George Wilson	avl_tree_t *t = &msp->ms_size_tree;
7410713e23George Wilson	int free_pct = range_tree_space(rt) * 100 / msp->ms_size;
742d6e555bGeorge Wilson
7430713e23George Wilson	zdb_nicenum(metaslab_block_maxsize(msp), maxbuf);
744d6e555bGeorge Wilson
74587219dbVictor Latushkin	(void) printf("\t %25s %10lu   %7s  %6s   %4s %4d%%\n",
746d6e555bGeorge Wilson	    "segments", avl_numnodes(t), "maxsize", maxbuf,
747d6e555bGeorge Wilson	    "freepct", free_pct);
7480713e23George Wilson	(void) printf("\tIn-memory histogram:\n");
7490713e23George Wilson	dump_histogram(rt->rt_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
750d6e555bGeorge Wilson}
751d6e555bGeorge Wilson
752d6e555bGeorge Wilsonstatic void
753fa9e406ahrensdump_metaslab(metaslab_t *msp)
754fa9e406ahrens{
755fa9e406ahrens	vdev_t *vd = msp->ms_group->mg_vd;
756fa9e406ahrens	spa_t *spa = vd->vdev_spa;
7570713e23George Wilson	space_map_t *sm = msp->ms_sm;
7583f9d6adLin Ling	char freebuf[32];
759fa9e406ahrens
7600713e23George Wilson	zdb_nicenum(msp->ms_size - space_map_allocated(sm), freebuf);
761fa9e406ahrens
762fa9e406ahrens	(void) printf(
76387219dbVictor Latushkin	    "\tmetaslab %6llu   offset %12llx   spacemap %6llu   free    %5s\n",
7640713e23George Wilson	    (u_longlong_t)msp->ms_id, (u_longlong_t)msp->ms_start,
7650713e23George Wilson	    (u_longlong_t)space_map_object(sm), freebuf);
766fa9e406ahrens
7670713e23George Wilson	if (dump_opt['m'] > 2 && !dump_opt['L']) {
768d6e555bGeorge Wilson		mutex_enter(&msp->ms_lock);
7690713e23George Wilson		metaslab_load_wait(msp);
7700713e23George Wilson		if (!msp->ms_loaded) {
7710713e23George Wilson			VERIFY0(metaslab_load(msp));
7720713e23George Wilson			range_tree_stat_verify(msp->ms_tree);
7730713e23George Wilson		}
774bc3975bVictor Latushkin		dump_metaslab_stats(msp);
7750713e23George Wilson		metaslab_unload(msp);
776d6e555bGeorge Wilson		mutex_exit(&msp->ms_lock);
777d6e555bGeorge Wilson	}
778d6e555bGeorge Wilson
7790713e23George Wilson	if (dump_opt['m'] > 1 && sm != NULL &&
7802acef22Matthew Ahrens	    spa_feature_is_active(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM)) {
7810713e23George Wilson		/*
7820713e23George Wilson		 * The space map histogram represents free space in chunks
7830713e23George Wilson		 * of sm_shift (i.e. bucket 0 refers to 2^sm_shift).
7840713e23George Wilson		 */
7852e4c998George Wilson		(void) printf("\tOn-disk histogram:\t\tfragmentation %llu\n",
7862e4c998George Wilson		    (u_longlong_t)msp->ms_fragmentation);
7870713e23George Wilson		dump_histogram(sm->sm_phys->smp_histogram,
7882e4c998George Wilson		    SPACE_MAP_HISTOGRAM_SIZE, sm->sm_shift);
7890713e23George Wilson	}
7900713e23George Wilson
7910713e23George Wilson	if (dump_opt['d'] > 5 || dump_opt['m'] > 3) {
7920713e23George Wilson		ASSERT(msp->ms_size == (1ULL << vd->vdev_ms_shift));
793d6e555bGeorge Wilson
794d6e555bGeorge Wilson		mutex_enter(&msp->ms_lock);
7950713e23George Wilson		dump_spacemap(spa->spa_meta_objset, msp->ms_sm);
796d6e555bGeorge Wilson		mutex_exit(&msp->ms_lock);
797d6e555bGeorge Wilson	}
79887219dbVictor Latushkin}
799fa9e406ahrens
80087219dbVictor Latushkinstatic void
80187219dbVictor Latushkinprint_vdev_metaslab_header(vdev_t *vd)
80287219dbVictor Latushkin{
80387219dbVictor Latushkin	(void) printf("\tvdev %10llu\n\t%-10s%5llu   %-19s   %-15s   %-10s\n",
80487219dbVictor Latushkin	    (u_longlong_t)vd->vdev_id,
80587219dbVictor Latushkin	    "metaslabs", (u_longlong_t)vd->vdev_ms_count,
80687219dbVictor Latushkin	    "offset", "spacemap", "free");
80787219dbVictor Latushkin	(void) printf("\t%15s   %19s   %15s   %10s\n",
80887219dbVictor Latushkin	    "---------------", "-------------------",
80987219dbVictor Latushkin	    "---------------", "-------------");
810fa9e406ahrens}
811fa9e406ahrens
812fa9e406ahrensstatic void
8132e4c998George Wilsondump_metaslab_groups(spa_t *spa)
8142e4c998George Wilson{
8152e4c998George Wilson	vdev_t *rvd = spa->spa_root_vdev;
8162e4c998George Wilson	metaslab_class_t *mc = spa_normal_class(spa);
8172e4c998George Wilson	uint64_t fragmentation;
8182e4c998George Wilson
8192e4c998George Wilson	metaslab_class_histogram_verify(mc);
8202e4c998George Wilson
8212e4c998George Wilson	for (int c = 0; c < rvd->vdev_children; c++) {
8222e4c998George Wilson		vdev_t *tvd = rvd->vdev_child[c];
8232e4c998George Wilson		metaslab_group_t *mg = tvd->vdev_mg;
8242e4c998George Wilson
8252e4c998George Wilson		if (mg->mg_class != mc)
8262e4c998George Wilson			continue;
8272e4c998George Wilson
8282e4c998George Wilson		metaslab_group_histogram_verify(mg);
8292e4c998George Wilson		mg->mg_fragmentation = metaslab_group_fragmentation(mg);
8302e4c998George Wilson
8312e4c998George Wilson		(void) printf("\tvdev %10llu\t\tmetaslabs%5llu\t\t"
8322e4c998George Wilson		    "fragmentation",
8332e4c998George Wilson		    (u_longlong_t)tvd->vdev_id,
8342e4c998George Wilson		    (u_longlong_t)tvd->vdev_ms_count);
8352e4c998George Wilson		if (mg->mg_fragmentation == ZFS_FRAG_INVALID) {
8362e4c998George Wilson			(void) printf("%3s\n", "-");
8372e4c998George Wilson		} else {
8382e4c998George Wilson			(void) printf("%3llu%%\n",
8392e4c998George Wilson			    (u_longlong_t)mg->mg_fragmentation);
8402e4c998George Wilson		}
8412e4c998George Wilson		dump_histogram(mg->mg_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
8422e4c998George Wilson	}
8432e4c998George Wilson
8442e4c998George Wilson	(void) printf("\tpool %s\tfragmentation", spa_name(spa));
8452e4c998George Wilson	fragmentation = metaslab_class_fragmentation(mc);
8462e4c998George Wilson	if (fragmentation == ZFS_FRAG_INVALID)
8472e4c998George Wilson		(void) printf("\t%3s\n", "-");
8482e4c998George Wilson	else
8492e4c998George Wilson		(void) printf("\t%3llu%%\n", (u_longlong_t)fragmentation);
8502e4c998George Wilson	dump_histogram(mc->mc_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
8512e4c998George Wilson}
8522e4c998George Wilson
8532e4c998George Wilsonstatic void
854fa9e406ahrensdump_metaslabs(spa_t *spa)
855fa9e406ahrens{
85687219dbVictor Latushkin	vdev_t *vd, *rvd = spa->spa_root_vdev;
85787219dbVictor La