xref: /illumos-gate/usr/src/cmd/zdb/zdb.c (revision 3ad6c7f96bc462dcbd2a112df698038f6764eabc)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <stdio.h>
27 #include <stdio_ext.h>
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <sys/zfs_context.h>
31 #include <sys/spa.h>
32 #include <sys/spa_impl.h>
33 #include <sys/dmu.h>
34 #include <sys/zap.h>
35 #include <sys/fs/zfs.h>
36 #include <sys/zfs_znode.h>
37 #include <sys/vdev.h>
38 #include <sys/vdev_impl.h>
39 #include <sys/metaslab_impl.h>
40 #include <sys/dmu_objset.h>
41 #include <sys/dsl_dir.h>
42 #include <sys/dsl_dataset.h>
43 #include <sys/dsl_pool.h>
44 #include <sys/dbuf.h>
45 #include <sys/zil.h>
46 #include <sys/zil_impl.h>
47 #include <sys/stat.h>
48 #include <sys/resource.h>
49 #include <sys/dmu_traverse.h>
50 #include <sys/zio_checksum.h>
51 #include <sys/zio_compress.h>
52 #include <sys/zfs_fuid.h>
53 #include <sys/arc.h>
54 #undef ZFS_MAXNAMELEN
55 #undef verify
56 #include <libzfs.h>
57 
58 const char cmdname[] = "zdb";
59 uint8_t dump_opt[256];
60 
61 typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
62 
63 extern void dump_intent_log(zilog_t *);
64 uint64_t *zopt_object = NULL;
65 int zopt_objects = 0;
66 libzfs_handle_t *g_zfs;
67 boolean_t zdb_sig_user_data = B_TRUE;
68 int zdb_sig_cksumalg = ZIO_CHECKSUM_SHA256;
69 
70 /*
71  * These libumem hooks provide a reasonable set of defaults for the allocator's
72  * debugging facilities.
73  */
74 const char *
75 _umem_debug_init()
76 {
77 	return ("default,verbose"); /* $UMEM_DEBUG setting */
78 }
79 
80 const char *
81 _umem_logging_init(void)
82 {
83 	return ("fail,contents"); /* $UMEM_LOGGING setting */
84 }
85 
86 static void
87 usage(void)
88 {
89 	(void) fprintf(stderr,
90 	    "Usage: %s [-CumdibcsvhL] [-S user:cksumalg] "
91 	    "poolname [object...]\n"
92 	    "       %s [-div] dataset [object...]\n"
93 	    "       %s -C [pool]\n"
94 	    "       %s -l dev\n"
95 	    "       %s -R pool:vdev:offset:size:flags\n\n",
96 	    cmdname, cmdname, cmdname, cmdname, cmdname);
97 
98 	(void) fprintf(stderr, "    Dataset name must include at least one "
99 	    "separator character '/' or '@'\n");
100 	(void) fprintf(stderr, "    If dataset name is specified, only that "
101 	    "dataset is dumped\n");
102 	(void) fprintf(stderr, "    If object numbers are specified, only "
103 	    "those objects are dumped\n\n");
104 	(void) fprintf(stderr, "    Options to control amount of output:\n");
105 	(void) fprintf(stderr, "        -u uberblock\n");
106 	(void) fprintf(stderr, "        -d dataset(s)\n");
107 	(void) fprintf(stderr, "        -i intent logs\n");
108 	(void) fprintf(stderr, "        -C cached pool configuration\n");
109 	(void) fprintf(stderr, "        -h pool history\n");
110 	(void) fprintf(stderr, "        -b block statistics\n");
111 	(void) fprintf(stderr, "        -m metaslabs\n");
112 	(void) fprintf(stderr, "        -c checksum all metadata (twice for "
113 	    "all data) blocks\n");
114 	(void) fprintf(stderr, "        -s report stats on zdb's I/O\n");
115 	(void) fprintf(stderr, "        -S <user|all>:<cksum_alg|all> -- "
116 	    "dump blkptr signatures\n");
117 	(void) fprintf(stderr, "        -v verbose (applies to all others)\n");
118 	(void) fprintf(stderr, "        -l dump label contents\n");
119 	(void) fprintf(stderr, "        -L disable leak tracking (do not "
120 	    "load spacemaps)\n");
121 	(void) fprintf(stderr, "        -R read and display block from a "
122 	    "device\n\n");
123 	(void) fprintf(stderr, "    Below options are intended for use "
124 	    "with other options (except -l):\n");
125 	(void) fprintf(stderr, "        -U <cachefile_path> -- use alternate "
126 	    "cachefile\n");
127 	(void) fprintf(stderr, "        -e pool is exported/destroyed/"
128 	    "has altroot/not in a cachefile\n");
129 	(void) fprintf(stderr, "        -p <path> -- use one or more with "
130 	    "-e to specify path to vdev dir\n");
131 	(void) fprintf(stderr, "        -t <txg> -- highest txg to use when "
132 	    "searching for uberblocks\n");
133 	(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
134 	    "to make only that option verbose\n");
135 	(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
136 	exit(1);
137 }
138 
139 /*
140  * Called for usage errors that are discovered after a call to spa_open(),
141  * dmu_bonus_hold(), or pool_match().  abort() is called for other errors.
142  */
143 
144 static void
145 fatal(const char *fmt, ...)
146 {
147 	va_list ap;
148 
149 	va_start(ap, fmt);
150 	(void) fprintf(stderr, "%s: ", cmdname);
151 	(void) vfprintf(stderr, fmt, ap);
152 	va_end(ap);
153 	(void) fprintf(stderr, "\n");
154 
155 	exit(1);
156 }
157 
158 /* ARGSUSED */
159 static void
160 dump_packed_nvlist(objset_t *os, uint64_t object, void *data, size_t size)
161 {
162 	nvlist_t *nv;
163 	size_t nvsize = *(uint64_t *)data;
164 	char *packed = umem_alloc(nvsize, UMEM_NOFAIL);
165 
166 	VERIFY(0 == dmu_read(os, object, 0, nvsize, packed, DMU_READ_PREFETCH));
167 
168 	VERIFY(nvlist_unpack(packed, nvsize, &nv, 0) == 0);
169 
170 	umem_free(packed, nvsize);
171 
172 	dump_nvlist(nv, 8);
173 
174 	nvlist_free(nv);
175 }
176 
177 const char dump_zap_stars[] = "****************************************";
178 const int dump_zap_width = sizeof (dump_zap_stars) - 1;
179 
180 static void
181 dump_zap_histogram(uint64_t histo[ZAP_HISTOGRAM_SIZE])
182 {
183 	int i;
184 	int minidx = ZAP_HISTOGRAM_SIZE - 1;
185 	int maxidx = 0;
186 	uint64_t max = 0;
187 
188 	for (i = 0; i < ZAP_HISTOGRAM_SIZE; i++) {
189 		if (histo[i] > max)
190 			max = histo[i];
191 		if (histo[i] > 0 && i > maxidx)
192 			maxidx = i;
193 		if (histo[i] > 0 && i < minidx)
194 			minidx = i;
195 	}
196 
197 	if (max < dump_zap_width)
198 		max = dump_zap_width;
199 
200 	for (i = minidx; i <= maxidx; i++)
201 		(void) printf("\t\t\t%u: %6llu %s\n", i, (u_longlong_t)histo[i],
202 		    &dump_zap_stars[(max - histo[i]) * dump_zap_width / max]);
203 }
204 
205 static void
206 dump_zap_stats(objset_t *os, uint64_t object)
207 {
208 	int error;
209 	zap_stats_t zs;
210 
211 	error = zap_get_stats(os, object, &zs);
212 	if (error)
213 		return;
214 
215 	if (zs.zs_ptrtbl_len == 0) {
216 		ASSERT(zs.zs_num_blocks == 1);
217 		(void) printf("\tmicrozap: %llu bytes, %llu entries\n",
218 		    (u_longlong_t)zs.zs_blocksize,
219 		    (u_longlong_t)zs.zs_num_entries);
220 		return;
221 	}
222 
223 	(void) printf("\tFat ZAP stats:\n");
224 
225 	(void) printf("\t\tPointer table:\n");
226 	(void) printf("\t\t\t%llu elements\n",
227 	    (u_longlong_t)zs.zs_ptrtbl_len);
228 	(void) printf("\t\t\tzt_blk: %llu\n",
229 	    (u_longlong_t)zs.zs_ptrtbl_zt_blk);
230 	(void) printf("\t\t\tzt_numblks: %llu\n",
231 	    (u_longlong_t)zs.zs_ptrtbl_zt_numblks);
232 	(void) printf("\t\t\tzt_shift: %llu\n",
233 	    (u_longlong_t)zs.zs_ptrtbl_zt_shift);
234 	(void) printf("\t\t\tzt_blks_copied: %llu\n",
235 	    (u_longlong_t)zs.zs_ptrtbl_blks_copied);
236 	(void) printf("\t\t\tzt_nextblk: %llu\n",
237 	    (u_longlong_t)zs.zs_ptrtbl_nextblk);
238 
239 	(void) printf("\t\tZAP entries: %llu\n",
240 	    (u_longlong_t)zs.zs_num_entries);
241 	(void) printf("\t\tLeaf blocks: %llu\n",
242 	    (u_longlong_t)zs.zs_num_leafs);
243 	(void) printf("\t\tTotal blocks: %llu\n",
244 	    (u_longlong_t)zs.zs_num_blocks);
245 	(void) printf("\t\tzap_block_type: 0x%llx\n",
246 	    (u_longlong_t)zs.zs_block_type);
247 	(void) printf("\t\tzap_magic: 0x%llx\n",
248 	    (u_longlong_t)zs.zs_magic);
249 	(void) printf("\t\tzap_salt: 0x%llx\n",
250 	    (u_longlong_t)zs.zs_salt);
251 
252 	(void) printf("\t\tLeafs with 2^n pointers:\n");
253 	dump_zap_histogram(zs.zs_leafs_with_2n_pointers);
254 
255 	(void) printf("\t\tBlocks with n*5 entries:\n");
256 	dump_zap_histogram(zs.zs_blocks_with_n5_entries);
257 
258 	(void) printf("\t\tBlocks n/10 full:\n");
259 	dump_zap_histogram(zs.zs_blocks_n_tenths_full);
260 
261 	(void) printf("\t\tEntries with n chunks:\n");
262 	dump_zap_histogram(zs.zs_entries_using_n_chunks);
263 
264 	(void) printf("\t\tBuckets with n entries:\n");
265 	dump_zap_histogram(zs.zs_buckets_with_n_entries);
266 }
267 
268 /*ARGSUSED*/
269 static void
270 dump_none(objset_t *os, uint64_t object, void *data, size_t size)
271 {
272 }
273 
274 /*ARGSUSED*/
275 void
276 dump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
277 {
278 }
279 
280 /*ARGSUSED*/
281 static void
282 dump_uint64(objset_t *os, uint64_t object, void *data, size_t size)
283 {
284 }
285 
286 /*ARGSUSED*/
287 static void
288 dump_zap(objset_t *os, uint64_t object, void *data, size_t size)
289 {
290 	zap_cursor_t zc;
291 	zap_attribute_t attr;
292 	void *prop;
293 	int i;
294 
295 	dump_zap_stats(os, object);
296 	(void) printf("\n");
297 
298 	for (zap_cursor_init(&zc, os, object);
299 	    zap_cursor_retrieve(&zc, &attr) == 0;
300 	    zap_cursor_advance(&zc)) {
301 		(void) printf("\t\t%s = ", attr.za_name);
302 		if (attr.za_num_integers == 0) {
303 			(void) printf("\n");
304 			continue;
305 		}
306 		prop = umem_zalloc(attr.za_num_integers *
307 		    attr.za_integer_length, UMEM_NOFAIL);
308 		(void) zap_lookup(os, object, attr.za_name,
309 		    attr.za_integer_length, attr.za_num_integers, prop);
310 		if (attr.za_integer_length == 1) {
311 			(void) printf("%s", (char *)prop);
312 		} else {
313 			for (i = 0; i < attr.za_num_integers; i++) {
314 				switch (attr.za_integer_length) {
315 				case 2:
316 					(void) printf("%u ",
317 					    ((uint16_t *)prop)[i]);
318 					break;
319 				case 4:
320 					(void) printf("%u ",
321 					    ((uint32_t *)prop)[i]);
322 					break;
323 				case 8:
324 					(void) printf("%lld ",
325 					    (u_longlong_t)((int64_t *)prop)[i]);
326 					break;
327 				}
328 			}
329 		}
330 		(void) printf("\n");
331 		umem_free(prop, attr.za_num_integers * attr.za_integer_length);
332 	}
333 	zap_cursor_fini(&zc);
334 }
335 
336 /*ARGSUSED*/
337 static void
338 dump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
339 {
340 	zap_cursor_t zc;
341 	zap_attribute_t attr;
342 	const char *typenames[] = {
343 		/* 0 */ "not specified",
344 		/* 1 */ "FIFO",
345 		/* 2 */ "Character Device",
346 		/* 3 */ "3 (invalid)",
347 		/* 4 */ "Directory",
348 		/* 5 */ "5 (invalid)",
349 		/* 6 */ "Block Device",
350 		/* 7 */ "7 (invalid)",
351 		/* 8 */ "Regular File",
352 		/* 9 */ "9 (invalid)",
353 		/* 10 */ "Symbolic Link",
354 		/* 11 */ "11 (invalid)",
355 		/* 12 */ "Socket",
356 		/* 13 */ "Door",
357 		/* 14 */ "Event Port",
358 		/* 15 */ "15 (invalid)",
359 	};
360 
361 	dump_zap_stats(os, object);
362 	(void) printf("\n");
363 
364 	for (zap_cursor_init(&zc, os, object);
365 	    zap_cursor_retrieve(&zc, &attr) == 0;
366 	    zap_cursor_advance(&zc)) {
367 		(void) printf("\t\t%s = %lld (type: %s)\n",
368 		    attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
369 		    typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
370 	}
371 	zap_cursor_fini(&zc);
372 }
373 
374 static void
375 dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
376 {
377 	uint64_t alloc, offset, entry;
378 	uint8_t mapshift = sm->sm_shift;
379 	uint64_t mapstart = sm->sm_start;
380 	char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
381 			    "INVALID", "INVALID", "INVALID", "INVALID" };
382 
383 	if (smo->smo_object == 0)
384 		return;
385 
386 	/*
387 	 * Print out the freelist entries in both encoded and decoded form.
388 	 */
389 	alloc = 0;
390 	for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) {
391 		VERIFY(0 == dmu_read(os, smo->smo_object, offset,
392 		    sizeof (entry), &entry, DMU_READ_PREFETCH));
393 		if (SM_DEBUG_DECODE(entry)) {
394 			(void) printf("\t\t[%4llu] %s: txg %llu, pass %llu\n",
395 			    (u_longlong_t)(offset / sizeof (entry)),
396 			    ddata[SM_DEBUG_ACTION_DECODE(entry)],
397 			    (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
398 			    (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
399 		} else {
400 			(void) printf("\t\t[%4llu]    %c  range:"
401 			    " %08llx-%08llx  size: %06llx\n",
402 			    (u_longlong_t)(offset / sizeof (entry)),
403 			    SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
404 			    (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
405 			    mapshift) + mapstart),
406 			    (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
407 			    mapshift) + mapstart + (SM_RUN_DECODE(entry) <<
408 			    mapshift)),
409 			    (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
410 			if (SM_TYPE_DECODE(entry) == SM_ALLOC)
411 				alloc += SM_RUN_DECODE(entry) << mapshift;
412 			else
413 				alloc -= SM_RUN_DECODE(entry) << mapshift;
414 		}
415 	}
416 	if (alloc != smo->smo_alloc) {
417 		(void) printf("space_map_object alloc (%llu) INCONSISTENT "
418 		    "with space map summary (%llu)\n",
419 		    (u_longlong_t)smo->smo_alloc, (u_longlong_t)alloc);
420 	}
421 }
422 
423 static void
424 dump_metaslab_stats(metaslab_t *msp)
425 {
426 	char maxbuf[5];
427 	space_map_t *sm = &msp->ms_map;
428 	avl_tree_t *t = sm->sm_pp_root;
429 	int free_pct = sm->sm_space * 100 / sm->sm_size;
430 
431 	nicenum(space_map_maxsize(sm), maxbuf);
432 
433 	(void) printf("\t %20s %10lu   %7s  %6s   %4s %4d%%\n",
434 	    "segments", avl_numnodes(t), "maxsize", maxbuf,
435 	    "freepct", free_pct);
436 }
437 
438 static void
439 dump_metaslab(metaslab_t *msp)
440 {
441 	char freebuf[5];
442 	space_map_obj_t *smo = &msp->ms_smo;
443 	vdev_t *vd = msp->ms_group->mg_vd;
444 	spa_t *spa = vd->vdev_spa;
445 
446 	nicenum(msp->ms_map.sm_size - smo->smo_alloc, freebuf);
447 
448 	(void) printf(
449 	    "\tvdev %5llu   offset %12llx   spacemap %6llu   free    %5s\n",
450 	    (u_longlong_t)vd->vdev_id, (u_longlong_t)msp->ms_map.sm_start,
451 	    (u_longlong_t)smo->smo_object, freebuf);
452 
453 	if (dump_opt['m'] > 1) {
454 		mutex_enter(&msp->ms_lock);
455 		VERIFY(space_map_load(&msp->ms_map, zfs_metaslab_ops,
456 		    SM_FREE, &msp->ms_smo, spa->spa_meta_objset) == 0);
457 		dump_metaslab_stats(msp);
458 		space_map_unload(&msp->ms_map);
459 		mutex_exit(&msp->ms_lock);
460 	}
461 
462 	if (dump_opt['d'] > 5 || dump_opt['m'] > 2) {
463 		ASSERT(msp->ms_map.sm_size == (1ULL << vd->vdev_ms_shift));
464 
465 		mutex_enter(&msp->ms_lock);
466 		dump_spacemap(spa->spa_meta_objset, smo, &msp->ms_map);
467 		mutex_exit(&msp->ms_lock);
468 	}
469 
470 }
471 
472 static void
473 dump_metaslabs(spa_t *spa)
474 {
475 	vdev_t *rvd = spa->spa_root_vdev;
476 	vdev_t *vd;
477 	int c, m;
478 
479 	(void) printf("\nMetaslabs:\n");
480 
481 	for (c = 0; c < rvd->vdev_children; c++) {
482 		vd = rvd->vdev_child[c];
483 
484 		(void) printf("\t%-10s   %-19s   %-15s   %-10s\n",
485 		    "vdev", "offset", "spacemap", "free");
486 		(void) printf("\t%10s   %19s   %15s   %10s\n",
487 		    "----------", "-------------------",
488 		    "---------------", "-------------");
489 
490 		for (m = 0; m < vd->vdev_ms_count; m++)
491 			dump_metaslab(vd->vdev_ms[m]);
492 		(void) printf("\n");
493 	}
494 }
495 
496 static void
497 dump_dtl_seg(space_map_t *sm, uint64_t start, uint64_t size)
498 {
499 	char *prefix = (void *)sm;
500 
501 	(void) printf("%s [%llu,%llu) length %llu\n",
502 	    prefix,
503 	    (u_longlong_t)start,
504 	    (u_longlong_t)(start + size),
505 	    (u_longlong_t)(size));
506 }
507 
508 static void
509 dump_dtl(vdev_t *vd, int indent)
510 {
511 	spa_t *spa = vd->vdev_spa;
512 	boolean_t required;
513 	char *name[DTL_TYPES] = { "missing", "partial", "scrub", "outage" };
514 	char prefix[256];
515 
516 	spa_vdev_state_enter(spa, SCL_NONE);
517 	required = vdev_dtl_required(vd);
518 	(void) spa_vdev_state_exit(spa, NULL, 0);
519 
520 	if (indent == 0)
521 		(void) printf("\nDirty time logs:\n\n");
522 
523 	(void) printf("\t%*s%s [%s]\n", indent, "",
524 	    vd->vdev_path ? vd->vdev_path :
525 	    vd->vdev_parent ? vd->vdev_ops->vdev_op_type : spa_name(spa),
526 	    required ? "DTL-required" : "DTL-expendable");
527 
528 	for (int t = 0; t < DTL_TYPES; t++) {
529 		space_map_t *sm = &vd->vdev_dtl[t];
530 		if (sm->sm_space == 0)
531 			continue;
532 		(void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
533 		    indent + 2, "", name[t]);
534 		mutex_enter(sm->sm_lock);
535 		space_map_walk(sm, dump_dtl_seg, (void *)prefix);
536 		mutex_exit(sm->sm_lock);
537 		if (dump_opt['d'] > 5 && vd->vdev_children == 0)
538 			dump_spacemap(spa->spa_meta_objset,
539 			    &vd->vdev_dtl_smo, sm);
540 	}
541 
542 	for (int c = 0; c < vd->vdev_children; c++)
543 		dump_dtl(vd->vdev_child[c], indent + 4);
544 }
545 
546 static void
547 dump_history(spa_t *spa)
548 {
549 	nvlist_t **events = NULL;
550 	char buf[SPA_MAXBLOCKSIZE];
551 	uint64_t resid, len, off = 0;
552 	uint_t num = 0;
553 	int error;
554 	time_t tsec;
555 	struct tm t;
556 	char tbuf[30];
557 	char internalstr[MAXPATHLEN];
558 
559 	do {
560 		len = sizeof (buf);
561 
562 		if ((error = spa_history_get(spa, &off, &len, buf)) != 0) {
563 			(void) fprintf(stderr, "Unable to read history: "
564 			    "error %d\n", error);
565 			return;
566 		}
567 
568 		if (zpool_history_unpack(buf, len, &resid, &events, &num) != 0)
569 			break;
570 
571 		off -= resid;
572 	} while (len != 0);
573 
574 	(void) printf("\nHistory:\n");
575 	for (int i = 0; i < num; i++) {
576 		uint64_t time, txg, ievent;
577 		char *cmd, *intstr;
578 
579 		if (nvlist_lookup_uint64(events[i], ZPOOL_HIST_TIME,
580 		    &time) != 0)
581 			continue;
582 		if (nvlist_lookup_string(events[i], ZPOOL_HIST_CMD,
583 		    &cmd) != 0) {
584 			if (nvlist_lookup_uint64(events[i],
585 			    ZPOOL_HIST_INT_EVENT, &ievent) != 0)
586 				continue;
587 			verify(nvlist_lookup_uint64(events[i],
588 			    ZPOOL_HIST_TXG, &txg) == 0);
589 			verify(nvlist_lookup_string(events[i],
590 			    ZPOOL_HIST_INT_STR, &intstr) == 0);
591 			if (ievent >= LOG_END)
592 				continue;
593 
594 			(void) snprintf(internalstr,
595 			    sizeof (internalstr),
596 			    "[internal %s txg:%lld] %s",
597 			    hist_event_table[ievent], txg,
598 			    intstr);
599 			cmd = internalstr;
600 		}
601 		tsec = time;
602 		(void) localtime_r(&tsec, &t);
603 		(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
604 		(void) printf("%s %s\n", tbuf, cmd);
605 	}
606 }
607 
608 /*ARGSUSED*/
609 static void
610 dump_dnode(objset_t *os, uint64_t object, void *data, size_t size)
611 {
612 }
613 
614 static uint64_t
615 blkid2offset(const dnode_phys_t *dnp, int level, uint64_t blkid)
616 {
617 	if (level < 0)
618 		return (blkid);
619 
620 	return ((blkid << (level * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT))) *
621 	    dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
622 }
623 
624 static void
625 sprintf_blkptr_compact(char *blkbuf, blkptr_t *bp, int alldvas)
626 {
627 	dva_t *dva = bp->blk_dva;
628 	int ndvas = alldvas ? BP_GET_NDVAS(bp) : 1;
629 	int i;
630 
631 	blkbuf[0] = '\0';
632 
633 	for (i = 0; i < ndvas; i++)
634 		(void) sprintf(blkbuf + strlen(blkbuf), "%llu:%llx:%llx ",
635 		    (u_longlong_t)DVA_GET_VDEV(&dva[i]),
636 		    (u_longlong_t)DVA_GET_OFFSET(&dva[i]),
637 		    (u_longlong_t)DVA_GET_ASIZE(&dva[i]));
638 
639 	(void) sprintf(blkbuf + strlen(blkbuf), "%llxL/%llxP F=%llu B=%llu",
640 	    (u_longlong_t)BP_GET_LSIZE(bp),
641 	    (u_longlong_t)BP_GET_PSIZE(bp),
642 	    (u_longlong_t)bp->blk_fill,
643 	    (u_longlong_t)bp->blk_birth);
644 }
645 
646 static void
647 print_indirect(blkptr_t *bp, const zbookmark_t *zb,
648     const dnode_phys_t *dnp)
649 {
650 	char blkbuf[BP_SPRINTF_LEN];
651 	int l;
652 
653 	ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type);
654 	ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level);
655 
656 	(void) printf("%16llx ",
657 	    (u_longlong_t)blkid2offset(dnp, zb->zb_level, zb->zb_blkid));
658 
659 	ASSERT(zb->zb_level >= 0);
660 
661 	for (l = dnp->dn_nlevels - 1; l >= -1; l--) {
662 		if (l == zb->zb_level) {
663 			(void) printf("L%llx", (u_longlong_t)zb->zb_level);
664 		} else {
665 			(void) printf(" ");
666 		}
667 	}
668 
669 	sprintf_blkptr_compact(blkbuf, bp, dump_opt['d'] > 5 ? 1 : 0);
670 	(void) printf("%s\n", blkbuf);
671 }
672 
673 #define	SET_BOOKMARK(zb, objset, object, level, blkid)  \
674 {                                                       \
675 	(zb)->zb_objset = objset;                       \
676 	(zb)->zb_object = object;                       \
677 	(zb)->zb_level = level;                         \
678 	(zb)->zb_blkid = blkid;                         \
679 }
680 
681 static int
682 visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
683     blkptr_t *bp, const zbookmark_t *zb)
684 {
685 	int err = 0;
686 
687 	if (bp->blk_birth == 0)
688 		return (0);
689 
690 	print_indirect(bp, zb, dnp);
691 
692 	if (BP_GET_LEVEL(bp) > 0) {
693 		uint32_t flags = ARC_WAIT;
694 		int i;
695 		blkptr_t *cbp;
696 		int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT;
697 		arc_buf_t *buf;
698 		uint64_t fill = 0;
699 
700 		err = arc_read_nolock(NULL, spa, bp, arc_getbuf_func, &buf,
701 		    ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
702 		if (err)
703 			return (err);
704 
705 		/* recursively visit blocks below this */
706 		cbp = buf->b_data;
707 		for (i = 0; i < epb; i++, cbp++) {
708 			zbookmark_t czb;
709 
710 			SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object,
711 			    zb->zb_level - 1,
712 			    zb->zb_blkid * epb + i);
713 			err = visit_indirect(spa, dnp, cbp, &czb);
714 			if (err)
715 				break;
716 			fill += cbp->blk_fill;
717 		}
718 		if (!err)
719 			ASSERT3U(fill, ==, bp->blk_fill);
720 		(void) arc_buf_remove_ref(buf, &buf);
721 	}
722 
723 	return (err);
724 }
725 
726 /*ARGSUSED*/
727 static void
728 dump_indirect(dnode_t *dn)
729 {
730 	dnode_phys_t *dnp = dn->dn_phys;
731 	int j;
732 	zbookmark_t czb;
733 
734 	(void) printf("Indirect blocks:\n");
735 
736 	SET_BOOKMARK(&czb, dmu_objset_id(dn->dn_objset),
737 	    dn->dn_object, dnp->dn_nlevels - 1, 0);
738 	for (j = 0; j < dnp->dn_nblkptr; j++) {
739 		czb.zb_blkid = j;
740 		(void) visit_indirect(dmu_objset_spa(dn->dn_objset), dnp,
741 		    &dnp->dn_blkptr[j], &czb);
742 	}
743 
744 	(void) printf("\n");
745 }
746 
747 /*ARGSUSED*/
748 static void
749 dump_dsl_dir(objset_t *os, uint64_t object, void *data, size_t size)
750 {
751 	dsl_dir_phys_t *dd = data;
752 	time_t crtime;
753 	char nice[6];
754 
755 	if (dd == NULL)
756 		return;
757 
758 	ASSERT3U(size, >=, sizeof (dsl_dir_phys_t));
759 
760 	crtime = dd->dd_creation_time;
761 	(void) printf("\t\tcreation_time = %s", ctime(&crtime));
762 	(void) printf("\t\thead_dataset_obj = %llu\n",
763 	    (u_longlong_t)dd->dd_head_dataset_obj);
764 	(void) printf("\t\tparent_dir_obj = %llu\n",
765 	    (u_longlong_t)dd->dd_parent_obj);
766 	(void) printf("\t\torigin_obj = %llu\n",
767 	    (u_longlong_t)dd->dd_origin_obj);
768 	(void) printf("\t\tchild_dir_zapobj = %llu\n",
769 	    (u_longlong_t)dd->dd_child_dir_zapobj);
770 	nicenum(dd->dd_used_bytes, nice);
771 	(void) printf("\t\tused_bytes = %s\n", nice);
772 	nicenum(dd->dd_compressed_bytes, nice);
773 	(void) printf("\t\tcompressed_bytes = %s\n", nice);
774 	nicenum(dd->dd_uncompressed_bytes, nice);
775 	(void) printf("\t\tuncompressed_bytes = %s\n", nice);
776 	nicenum(dd->dd_quota, nice);
777 	(void) printf("\t\tquota = %s\n", nice);
778 	nicenum(dd->dd_reserved, nice);
779 	(void) printf("\t\treserved = %s\n", nice);
780 	(void) printf("\t\tprops_zapobj = %llu\n",
781 	    (u_longlong_t)dd->dd_props_zapobj);
782 	(void) printf("\t\tdeleg_zapobj = %llu\n",
783 	    (u_longlong_t)dd->dd_deleg_zapobj);
784 	(void) printf("\t\tflags = %llx\n",
785 	    (u_longlong_t)dd->dd_flags);
786 
787 #define	DO(which) \
788 	nicenum(dd->dd_used_breakdown[DD_USED_ ## which], nice); \
789 	(void) printf("\t\tused_breakdown[" #which "] = %s\n", nice)
790 	DO(HEAD);
791 	DO(SNAP);
792 	DO(CHILD);
793 	DO(CHILD_RSRV);
794 	DO(REFRSRV);
795 #undef DO
796 }
797 
798 /*ARGSUSED*/
799 static void
800 dump_dsl_dataset(objset_t *os, uint64_t object, void *data, size_t size)
801 {
802 	dsl_dataset_phys_t *ds = data;
803 	time_t crtime;
804 	char used[6], compressed[6], uncompressed[6], unique[6];
805 	char blkbuf[BP_SPRINTF_LEN];
806 
807 	if (ds == NULL)
808 		return;
809 
810 	ASSERT(size == sizeof (*ds));
811 	crtime = ds->ds_creation_time;
812 	nicenum(ds->ds_used_bytes, used);
813 	nicenum(ds->ds_compressed_bytes, compressed);
814 	nicenum(ds->ds_uncompressed_bytes, uncompressed);
815 	nicenum(ds->ds_unique_bytes, unique);
816 	sprintf_blkptr(blkbuf, BP_SPRINTF_LEN, &ds->ds_bp);
817 
818 	(void) printf("\t\tdir_obj = %llu\n",
819 	    (u_longlong_t)ds->ds_dir_obj);
820 	(void) printf("\t\tprev_snap_obj = %llu\n",
821 	    (u_longlong_t)ds->ds_prev_snap_obj);
822 	(void) printf("\t\tprev_snap_txg = %llu\n",
823 	    (u_longlong_t)ds->ds_prev_snap_txg);
824 	(void) printf("\t\tnext_snap_obj = %llu\n",
825 	    (u_longlong_t)ds->ds_next_snap_obj);
826 	(void) printf("\t\tsnapnames_zapobj = %llu\n",
827 	    (u_longlong_t)ds->ds_snapnames_zapobj);
828 	(void) printf("\t\tnum_children = %llu\n",
829 	    (u_longlong_t)ds->ds_num_children);
830 	(void) printf("\t\tuserrefs_obj = %llu\n",
831 	    (u_longlong_t)ds->ds_userrefs_obj);
832 	(void) printf("\t\tcreation_time = %s", ctime(&crtime));
833 	(void) printf("\t\tcreation_txg = %llu\n",
834 	    (u_longlong_t)ds->ds_creation_txg);
835 	(void) printf("\t\tdeadlist_obj = %llu\n",
836 	    (u_longlong_t)ds->ds_deadlist_obj);
837 	(void) printf("\t\tused_bytes = %s\n", used);
838 	(void) printf("\t\tcompressed_bytes = %s\n", compressed);
839 	(void) printf("\t\tuncompressed_bytes = %s\n", uncompressed);
840 	(void) printf("\t\tunique = %s\n", unique);
841 	(void) printf("\t\tfsid_guid = %llu\n",
842 	    (u_longlong_t)ds->ds_fsid_guid);
843 	(void) printf("\t\tguid = %llu\n",
844 	    (u_longlong_t)ds->ds_guid);
845 	(void) printf("\t\tflags = %llx\n",
846 	    (u_longlong_t)ds->ds_flags);
847 	(void) printf("\t\tnext_clones_obj = %llu\n",
848 	    (u_longlong_t)ds->ds_next_clones_obj);
849 	(void) printf("\t\tprops_obj = %llu\n",
850 	    (u_longlong_t)ds->ds_props_obj);
851 	(void) printf("\t\tbp = %s\n", blkbuf);
852 }
853 
854 static void
855 dump_bplist(objset_t *mos, uint64_t object, char *name)
856 {
857 	bplist_t bpl = { 0 };
858 	blkptr_t blk, *bp = &blk;
859 	uint64_t itor = 0;
860 	char bytes[6];
861 	char comp[6];
862 	char uncomp[6];
863 
864 	if (dump_opt['d'] < 3)
865 		return;
866 
867 	mutex_init(&bpl.bpl_lock, NULL, MUTEX_DEFAULT, NULL);
868 	VERIFY(0 == bplist_open(&bpl, mos, object));
869 	if (bplist_empty(&bpl)) {
870 		bplist_close(&bpl);
871 		mutex_destroy(&bpl.bpl_lock);
872 		return;
873 	}
874 
875 	nicenum(bpl.bpl_phys->bpl_bytes, bytes);
876 	if (bpl.bpl_dbuf->db_size == sizeof (bplist_phys_t)) {
877 		nicenum(bpl.bpl_phys->bpl_comp, comp);
878 		nicenum(bpl.bpl_phys->bpl_uncomp, uncomp);
879 		(void) printf("\n    %s: %llu entries, %s (%s/%s comp)\n",
880 		    name, (u_longlong_t)bpl.bpl_phys->bpl_entries,
881 		    bytes, comp, uncomp);
882 	} else {
883 		(void) printf("\n    %s: %llu entries, %s\n",
884 		    name, (u_longlong_t)bpl.bpl_phys->bpl_entries, bytes);
885 	}
886 
887 	if (dump_opt['d'] < 5) {
888 		bplist_close(&bpl);
889 		mutex_destroy(&bpl.bpl_lock);
890 		return;
891 	}
892 
893 	(void) printf("\n");
894 
895 	while (bplist_iterate(&bpl, &itor, bp) == 0) {
896 		char blkbuf[BP_SPRINTF_LEN];
897 
898 		ASSERT(bp->blk_birth != 0);
899 		sprintf_blkptr_compact(blkbuf, bp, dump_opt['d'] > 5 ? 1 : 0);
900 		(void) printf("\tItem %3llu: %s\n",
901 		    (u_longlong_t)itor - 1, blkbuf);
902 	}
903 
904 	bplist_close(&bpl);
905 	mutex_destroy(&bpl.bpl_lock);
906 }
907 
908 static avl_tree_t idx_tree;
909 static avl_tree_t domain_tree;
910 static boolean_t fuid_table_loaded;
911 
912 static void
913 fuid_table_destroy()
914 {
915 	if (fuid_table_loaded) {
916 		zfs_fuid_table_destroy(&idx_tree, &domain_tree);
917 		fuid_table_loaded = B_FALSE;
918 	}
919 }
920 
921 /*
922  * print uid or gid information.
923  * For normal POSIX id just the id is printed in decimal format.
924  * For CIFS files with FUID the fuid is printed in hex followed by
925  * the doman-rid string.
926  */
927 static void
928 print_idstr(uint64_t id, const char *id_type)
929 {
930 	if (FUID_INDEX(id)) {
931 		char *domain;
932 
933 		domain = zfs_fuid_idx_domain(&idx_tree, FUID_INDEX(id));
934 		(void) printf("\t%s     %llx [%s-%d]\n", id_type,
935 		    (u_longlong_t)id, domain, (int)FUID_RID(id));
936 	} else {
937 		(void) printf("\t%s     %llu\n", id_type, (u_longlong_t)id);
938 	}
939 
940 }
941 
942 static void
943 dump_uidgid(objset_t *os, znode_phys_t *zp)
944 {
945 	uint32_t uid_idx, gid_idx;
946 
947 	uid_idx = FUID_INDEX(zp->zp_uid);
948 	gid_idx = FUID_INDEX(zp->zp_gid);
949 
950 	/* Load domain table, if not already loaded */
951 	if (!fuid_table_loaded && (uid_idx || gid_idx)) {
952 		uint64_t fuid_obj;
953 
954 		/* first find the fuid object.  It lives in the master node */
955 		VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES,
956 		    8, 1, &fuid_obj) == 0);
957 		zfs_fuid_avl_tree_create(&idx_tree, &domain_tree);
958 		(void) zfs_fuid_table_load(os, fuid_obj,
959 		    &idx_tree, &domain_tree);
960 		fuid_table_loaded = B_TRUE;
961 	}
962 
963 	print_idstr(zp->zp_uid, "uid");
964 	print_idstr(zp->zp_gid, "gid");
965 }
966 
967 /*ARGSUSED*/
968 static void
969 dump_znode(objset_t *os, uint64_t object, void *data, size_t size)
970 {
971 	znode_phys_t *zp = data;
972 	time_t z_crtime, z_atime, z_mtime, z_ctime;
973 	char path[MAXPATHLEN * 2];	/* allow for xattr and failure prefix */
974 	int error;
975 
976 	ASSERT(size >= sizeof (znode_phys_t));
977 
978 	error = zfs_obj_to_path(os, object, path, sizeof (path));
979 	if (error != 0) {
980 		(void) snprintf(path, sizeof (path), "\?\?\?<object#%llu>",
981 		    (u_longlong_t)object);
982 	}
983 
984 	if (dump_opt['d'] < 3) {
985 		(void) printf("\t%s\n", path);
986 		return;
987 	}
988 
989 	z_crtime = (time_t)zp->zp_crtime[0];
990 	z_atime = (time_t)zp->zp_atime[0];
991 	z_mtime = (time_t)zp->zp_mtime[0];
992 	z_ctime = (time_t)zp->zp_ctime[0];
993 
994 	(void) printf("\tpath	%s\n", path);
995 	dump_uidgid(os, zp);
996 	(void) printf("\tatime	%s", ctime(&z_atime));
997 	(void) printf("\tmtime	%s", ctime(&z_mtime));
998 	(void) printf("\tctime	%s", ctime(&z_ctime));
999 	(void) printf("\tcrtime	%s", ctime(&z_crtime));
1000 	(void) printf("\tgen	%llu\n", (u_longlong_t)zp->zp_gen);
1001 	(void) printf("\tmode	%llo\n", (u_longlong_t)zp->zp_mode);
1002 	(void) printf("\tsize	%llu\n", (u_longlong_t)zp->zp_size);
1003 	(void) printf("\tparent	%llu\n", (u_longlong_t)zp->zp_parent);
1004 	(void) printf("\tlinks	%llu\n", (u_longlong_t)zp->zp_links);
1005 	(void) printf("\txattr	%llu\n", (u_longlong_t)zp->zp_xattr);
1006 	(void) printf("\trdev	0x%016llx\n", (u_longlong_t)zp->zp_rdev);
1007 }
1008 
1009 /*ARGSUSED*/
1010 static void
1011 dump_acl(objset_t *os, uint64_t object, void *data, size_t size)
1012 {
1013 }
1014 
1015 /*ARGSUSED*/
1016 static void
1017 dump_dmu_objset(objset_t *os, uint64_t object, void *data, size_t size)
1018 {
1019 }
1020 
1021 static object_viewer_t *object_viewer[DMU_OT_NUMTYPES] = {
1022 	dump_none,		/* unallocated			*/
1023 	dump_zap,		/* object directory		*/
1024 	dump_uint64,		/* object array			*/
1025 	dump_none,		/* packed nvlist		*/
1026 	dump_packed_nvlist,	/* packed nvlist size		*/
1027 	dump_none,		/* bplist			*/
1028 	dump_none,		/* bplist header		*/
1029 	dump_none,		/* SPA space map header		*/
1030 	dump_none,		/* SPA space map		*/
1031 	dump_none,		/* ZIL intent log		*/
1032 	dump_dnode,		/* DMU dnode			*/
1033 	dump_dmu_objset,	/* DMU objset			*/
1034 	dump_dsl_dir,		/* DSL directory		*/
1035 	dump_zap,		/* DSL directory child map	*/
1036 	dump_zap,		/* DSL dataset snap map		*/
1037 	dump_zap,		/* DSL props			*/
1038 	dump_dsl_dataset,	/* DSL dataset			*/
1039 	dump_znode,		/* ZFS znode			*/
1040 	dump_acl,		/* ZFS V0 ACL			*/
1041 	dump_uint8,		/* ZFS plain file		*/
1042 	dump_zpldir,		/* ZFS directory		*/
1043 	dump_zap,		/* ZFS master node		*/
1044 	dump_zap,		/* ZFS delete queue		*/
1045 	dump_uint8,		/* zvol object			*/
1046 	dump_zap,		/* zvol prop			*/
1047 	dump_uint8,		/* other uint8[]		*/
1048 	dump_uint64,		/* other uint64[]		*/
1049 	dump_zap,		/* other ZAP			*/
1050 	dump_zap,		/* persistent error log		*/
1051 	dump_uint8,		/* SPA history			*/
1052 	dump_uint64,		/* SPA history offsets		*/
1053 	dump_zap,		/* Pool properties		*/
1054 	dump_zap,		/* DSL permissions		*/
1055 	dump_acl,		/* ZFS ACL			*/
1056 	dump_uint8,		/* ZFS SYSACL			*/
1057 	dump_none,		/* FUID nvlist			*/
1058 	dump_packed_nvlist,	/* FUID nvlist size		*/
1059 	dump_zap,		/* DSL dataset next clones	*/
1060 	dump_zap,		/* DSL scrub queue		*/
1061 	dump_zap,		/* ZFS user/group used		*/
1062 	dump_zap,		/* ZFS user/group quota		*/
1063 	dump_zap,		/* snapshot refcount tags	*/
1064 };
1065 
1066 static void
1067 dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header)
1068 {
1069 	dmu_buf_t *db = NULL;
1070 	dmu_object_info_t doi;
1071 	dnode_t *dn;
1072 	void *bonus = NULL;
1073 	size_t bsize = 0;
1074 	char iblk[6], dblk[6], lsize[6], asize[6], bonus_size[6], segsize[6];
1075 	char aux[50];
1076 	int error;
1077 
1078 	if (*print_header) {
1079 		(void) printf("\n    Object  lvl   iblk   dblk  lsize"
1080 		    "  asize  type\n");
1081 		*print_header = 0;
1082 	}
1083 
1084 	if (object == 0) {
1085 		dn = os->os_meta_dnode;
1086 	} else {
1087 		error = dmu_bonus_hold(os, object, FTAG, &db);
1088 		if (error)
1089 			fatal("dmu_bonus_hold(%llu) failed, errno %u",
1090 			    object, error);
1091 		bonus = db->db_data;
1092 		bsize = db->db_size;
1093 		dn = ((dmu_buf_impl_t *)db)->db_dnode;
1094 	}
1095 	dmu_object_info_from_dnode(dn, &doi);
1096 
1097 	nicenum(doi.doi_metadata_block_size, iblk);
1098 	nicenum(doi.doi_data_block_size, dblk);
1099 	nicenum(doi.doi_data_block_size * (doi.doi_max_block_offset + 1),
1100 	    lsize);
1101 	nicenum(doi.doi_physical_blks << 9, asize);
1102 	nicenum(doi.doi_bonus_size, bonus_size);
1103 
1104 	aux[0] = '\0';
1105 
1106 	if (doi.doi_checksum != ZIO_CHECKSUM_INHERIT || verbosity >= 6) {
1107 		(void) snprintf(aux + strlen(aux), sizeof (aux), " (K=%s)",
1108 		    zio_checksum_table[doi.doi_checksum].ci_name);
1109 	}
1110 
1111 	if (doi.doi_compress != ZIO_COMPRESS_INHERIT || verbosity >= 6) {
1112 		(void) snprintf(aux + strlen(aux), sizeof (aux), " (Z=%s)",
1113 		    zio_compress_table[doi.doi_compress].ci_name);
1114 	}
1115 
1116 	(void) printf("%10lld  %3u  %5s  %5s  %5s  %5s  %s%s\n",
1117 	    (u_longlong_t)object, doi.doi_indirection, iblk, dblk, lsize,
1118 	    asize, dmu_ot[doi.doi_type].ot_name, aux);
1119 
1120 	if (doi.doi_bonus_type != DMU_OT_NONE && verbosity > 3) {
1121 		(void) printf("%10s  %3s  %5s  %5s  %5s  %5s  %s\n",
1122 		    "", "", "", "", bonus_size, "bonus",
1123 		    dmu_ot[doi.doi_bonus_type].ot_name);
1124 	}
1125 
1126 	if (verbosity >= 4) {
1127 		(void) printf("\tdnode flags: %s%s\n",
1128 		    (dn->dn_phys->dn_flags & DNODE_FLAG_USED_BYTES) ?
1129 		    "USED_BYTES " : "",
1130 		    (dn->dn_phys->dn_flags & DNODE_FLAG_USERUSED_ACCOUNTED) ?
1131 		    "USERUSED_ACCOUNTED " : "");
1132 		(void) printf("\tdnode maxblkid: %llu\n",
1133 		    (longlong_t)dn->dn_phys->dn_maxblkid);
1134 
1135 		object_viewer[doi.doi_bonus_type](os, object, bonus, bsize);
1136 		object_viewer[doi.doi_type](os, object, NULL, 0);
1137 		*print_header = 1;
1138 	}
1139 
1140 	if (verbosity >= 5)
1141 		dump_indirect(dn);
1142 
1143 	if (verbosity >= 5) {
1144 		/*
1145 		 * Report the list of segments that comprise the object.
1146 		 */
1147 		uint64_t start = 0;
1148 		uint64_t end;
1149 		uint64_t blkfill = 1;
1150 		int minlvl = 1;
1151 
1152 		if (dn->dn_type == DMU_OT_DNODE) {
1153 			minlvl = 0;
1154 			blkfill = DNODES_PER_BLOCK;
1155 		}
1156 
1157 		for (;;) {
1158 			error = dnode_next_offset(dn,
1159 			    0, &start, minlvl, blkfill, 0);
1160 			if (error)
1161 				break;
1162 			end = start;
1163 			error = dnode_next_offset(dn,
1164 			    DNODE_FIND_HOLE, &end, minlvl, blkfill, 0);
1165 			nicenum(end - start, segsize);
1166 			(void) printf("\t\tsegment [%016llx, %016llx)"
1167 			    " size %5s\n", (u_longlong_t)start,
1168 			    (u_longlong_t)end, segsize);
1169 			if (error)
1170 				break;
1171 			start = end;
1172 		}
1173 	}
1174 
1175 	if (db != NULL)
1176 		dmu_buf_rele(db, FTAG);
1177 }
1178 
1179 static char *objset_types[DMU_OST_NUMTYPES] = {
1180 	"NONE", "META", "ZPL", "ZVOL", "OTHER", "ANY" };
1181 
1182 static void
1183 dump_dir(objset_t *os)
1184 {
1185 	dmu_objset_stats_t dds;
1186 	uint64_t object, object_count;
1187 	uint64_t refdbytes, usedobjs, scratch;
1188 	char numbuf[8];
1189 	char blkbuf[BP_SPRINTF_LEN + 20];
1190 	char osname[MAXNAMELEN];
1191 	char *type = "UNKNOWN";
1192 	int verbosity = dump_opt['d'];
1193 	int print_header = 1;
1194 	int i, error;
1195 
1196 	dmu_objset_fast_stat(os, &dds);
1197 
1198 	if (dds.dds_type < DMU_OST_NUMTYPES)
1199 		type = objset_types[dds.dds_type];
1200 
1201 	if (dds.dds_type == DMU_OST_META) {
1202 		dds.dds_creation_txg = TXG_INITIAL;
1203 		usedobjs = os->os_rootbp->blk_fill;
1204 		refdbytes = os->os_spa->spa_dsl_pool->
1205 		    dp_mos_dir->dd_phys->dd_used_bytes;
1206 	} else {
1207 		dmu_objset_space(os, &refdbytes, &scratch, &usedobjs, &scratch);
1208 	}
1209 
1210 	ASSERT3U(usedobjs, ==, os->os_rootbp->blk_fill);
1211 
1212 	nicenum(refdbytes, numbuf);
1213 
1214 	if (verbosity >= 4) {
1215 		(void) sprintf(blkbuf, ", rootbp ");
1216 		(void) sprintf_blkptr(blkbuf + strlen(blkbuf),
1217 		    BP_SPRINTF_LEN - strlen(blkbuf), os->os_rootbp);
1218 	} else {
1219 		blkbuf[0] = '\0';
1220 	}
1221 
1222 	dmu_objset_name(os, osname);
1223 
1224 	(void) printf("Dataset %s [%s], ID %llu, cr_txg %llu, "
1225 	    "%s, %llu objects%s\n",
1226 	    osname, type, (u_longlong_t)dmu_objset_id(os),
1227 	    (u_longlong_t)dds.dds_creation_txg,
1228 	    numbuf, (u_longlong_t)usedobjs, blkbuf);
1229 
1230 	dump_intent_log(dmu_objset_zil(os));
1231 
1232 	if (dmu_objset_ds(os) != NULL)
1233 		dump_bplist(dmu_objset_pool(os)->dp_meta_objset,
1234 		    dmu_objset_ds(os)->ds_phys->ds_deadlist_obj, "Deadlist");
1235 
1236 	if (verbosity < 2)
1237 		return;
1238 
1239 	if (os->os_rootbp->blk_birth == 0)
1240 		return;
1241 
1242 	if (zopt_objects != 0) {
1243 		for (i = 0; i < zopt_objects; i++)
1244 			dump_object(os, zopt_object[i], verbosity,
1245 			    &print_header);
1246 		(void) printf("\n");
1247 		return;
1248 	}
1249 
1250 	dump_object(os, 0, verbosity, &print_header);
1251 	object_count = 0;
1252 	if (os->os_userused_dnode &&
1253 	    os->os_userused_dnode->dn_type != 0) {
1254 		dump_object(os, DMU_USERUSED_OBJECT, verbosity, &print_header);
1255 		dump_object(os, DMU_GROUPUSED_OBJECT, verbosity, &print_header);
1256 	}
1257 
1258 	object = 0;
1259 	while ((error = dmu_object_next(os, &object, B_FALSE, 0)) == 0) {
1260 		dump_object(os, object, verbosity, &print_header);
1261 		object_count++;
1262 	}
1263 
1264 	ASSERT3U(object_count, ==, usedobjs);
1265 
1266 	(void) printf("\n");
1267 
1268 	if (error != ESRCH) {
1269 		(void) fprintf(stderr, "dmu_object_next() = %d\n", error);
1270 		abort();
1271 	}
1272 }
1273 
1274 static void
1275 dump_uberblock(uberblock_t *ub)
1276 {
1277 	time_t timestamp = ub->ub_timestamp;
1278 
1279 	(void) printf("Uberblock\n\n");
1280 	(void) printf("\tmagic = %016llx\n", (u_longlong_t)ub->ub_magic);
1281 	(void) printf("\tversion = %llu\n", (u_longlong_t)ub->ub_version);
1282 	(void) printf("\ttxg = %llu\n", (u_longlong_t)ub->ub_txg);
1283 	(void) printf("\tguid_sum = %llu\n", (u_longlong_t)ub->ub_guid_sum);
1284 	(void) printf("\ttimestamp = %llu UTC = %s",
1285 	    (u_longlong_t)ub->ub_timestamp, asctime(localtime(&timestamp)));
1286 	if (dump_opt['u'] >= 3) {
1287 		char blkbuf[BP_SPRINTF_LEN];
1288 		sprintf_blkptr(blkbuf, BP_SPRINTF_LEN, &ub->ub_rootbp);
1289 		(void) printf("\trootbp = %s\n", blkbuf);
1290 	}
1291 	(void) printf("\n");
1292 }
1293 
1294 static void
1295 dump_config(const char *pool)
1296 {
1297 	spa_t *spa = NULL;
1298 
1299 	mutex_enter(&spa_namespace_lock);
1300 	while ((spa = spa_next(spa)) != NULL) {
1301 		if (pool == NULL)
1302 			(void) printf("%s\n", spa_name(spa));
1303 		if (pool == NULL || strcmp(pool, spa_name(spa)) == 0)
1304 			dump_nvlist(spa->spa_config, 4);
1305 	}
1306 	mutex_exit(&spa_namespace_lock);
1307 }
1308 
1309 static void
1310 dump_cachefile(const char *cachefile)
1311 {
1312 	int fd;
1313 	struct stat64 statbuf;
1314 	char *buf;
1315 	nvlist_t *config;
1316 
1317 	if ((fd = open64(cachefile, O_RDONLY)) < 0) {
1318 		(void) printf("cannot open '%s': %s\n", cachefile,
1319 		    strerror(errno));
1320 		exit(1);
1321 	}
1322 
1323 	if (fstat64(fd, &statbuf) != 0) {
1324 		(void) printf("failed to stat '%s': %s\n", cachefile,
1325 		    strerror(errno));
1326 		exit(1);
1327 	}
1328 
1329 	if ((buf = malloc(statbuf.st_size)) == NULL) {
1330 		(void) fprintf(stderr, "failed to allocate %llu bytes\n",
1331 		    (u_longlong_t)statbuf.st_size);
1332 		exit(1);
1333 	}
1334 
1335 	if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
1336 		(void) fprintf(stderr, "failed to read %llu bytes\n",
1337 		    (u_longlong_t)statbuf.st_size);
1338 		exit(1);
1339 	}
1340 
1341 	(void) close(fd);
1342 
1343 	if (nvlist_unpack(buf, statbuf.st_size, &config, 0) != 0) {
1344 		(void) fprintf(stderr, "failed to unpack nvlist\n");
1345 		exit(1);
1346 	}
1347 
1348 	free(buf);
1349 
1350 	dump_nvlist(config, 0);
1351 
1352 	nvlist_free(config);
1353 }
1354 
1355 static void
1356 dump_label(const char *dev)
1357 {
1358 	int fd;
1359 	vdev_label_t label;
1360 	char *buf = label.vl_vdev_phys.vp_nvlist;
1361 	size_t buflen = sizeof (label.vl_vdev_phys.vp_nvlist);
1362 	struct stat64 statbuf;
1363 	uint64_t psize;
1364 	int l;
1365 
1366 	if ((fd = open64(dev, O_RDONLY)) < 0) {
1367 		(void) printf("cannot open '%s': %s\n", dev, strerror(errno));
1368 		exit(1);
1369 	}
1370 
1371 	if (fstat64(fd, &statbuf) != 0) {
1372 		(void) printf("failed to stat '%s': %s\n", dev,
1373 		    strerror(errno));
1374 		exit(1);
1375 	}
1376 
1377 	psize = statbuf.st_size;
1378 	psize = P2ALIGN(psize, (uint64_t)sizeof (vdev_label_t));
1379 
1380 	for (l = 0; l < VDEV_LABELS; l++) {
1381 
1382 		nvlist_t *config = NULL;
1383 
1384 		(void) printf("--------------------------------------------\n");
1385 		(void) printf("LABEL %d\n", l);
1386 		(void) printf("--------------------------------------------\n");
1387 
1388 		if (pread64(fd, &label, sizeof (label),
1389 		    vdev_label_offset(psize, l, 0)) != sizeof (label)) {
1390 			(void) printf("failed to read label %d\n", l);
1391 			continue;
1392 		}
1393 
1394 		if (nvlist_unpack(buf, buflen, &config, 0) != 0) {
1395 			(void) printf("failed to unpack label %d\n", l);
1396 			continue;
1397 		}
1398 		dump_nvlist(config, 4);
1399 		nvlist_free(config);
1400 	}
1401 }
1402 
1403 /*ARGSUSED*/
1404 static int
1405 dump_one_dir(char *dsname, void *arg)
1406 {
1407 	int error;
1408 	objset_t *os;
1409 
1410 	error = dmu_objset_own(dsname, DMU_OST_ANY, B_TRUE, FTAG, &os);
1411 	if (error) {
1412 		(void) printf("Could not open %s\n", dsname);
1413 		return (0);
1414 	}
1415 	dump_dir(os);
1416 	dmu_objset_disown(os, FTAG);
1417 	fuid_table_destroy();
1418 	return (0);
1419 }
1420 
1421 static void
1422 zdb_leak(space_map_t *sm, uint64_t start, uint64_t size)
1423 {
1424 	vdev_t *vd = sm->sm_ppd;
1425 
1426 	(void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
1427 	    (u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size);
1428 }
1429 
1430 /* ARGSUSED */
1431 static void
1432 zdb_space_map_load(space_map_t *sm)
1433 {
1434 }
1435 
1436 static void
1437 zdb_space_map_unload(space_map_t *sm)
1438 {
1439 	space_map_vacate(sm, zdb_leak, sm);
1440 }
1441 
1442 /* ARGSUSED */
1443 static void
1444 zdb_space_map_claim(space_map_t *sm, uint64_t start, uint64_t size)
1445 {
1446 }
1447 
1448 static space_map_ops_t zdb_space_map_ops = {
1449 	zdb_space_map_load,
1450 	zdb_space_map_unload,
1451 	NULL,	/* alloc */
1452 	zdb_space_map_claim,
1453 	NULL,	/* free */
1454 	NULL	/* maxsize */
1455 };
1456 
1457 static void
1458 zdb_leak_init(spa_t *spa)
1459 {
1460 	vdev_t *rvd = spa->spa_root_vdev;
1461 
1462 	for (int c = 0; c < rvd->vdev_children; c++) {
1463 		vdev_t *vd = rvd->vdev_child[c];
1464 		for (int m = 0; m < vd->vdev_ms_count; m++) {
1465 			metaslab_t *msp = vd->vdev_ms[m];
1466 			mutex_enter(&msp->ms_lock);
1467 			VERIFY(space_map_load(&msp->ms_map, &zdb_space_map_ops,
1468 			    SM_ALLOC, &msp->ms_smo, spa->spa_meta_objset) == 0);
1469 			msp->ms_map.sm_ppd = vd;
1470 			mutex_exit(&msp->ms_lock);
1471 		}
1472 	}
1473 }
1474 
1475 static void
1476 zdb_leak_fini(spa_t *spa)
1477 {
1478 	vdev_t *rvd = spa->spa_root_vdev;
1479 
1480 	for (int c = 0; c < rvd->vdev_children; c++) {
1481 		vdev_t *vd = rvd->vdev_child[c];
1482 		for (int m = 0; m < vd->vdev_ms_count; m++) {
1483 			metaslab_t *msp = vd->vdev_ms[m];
1484 			mutex_enter(&msp->ms_lock);
1485 			space_map_unload(&msp->ms_map);
1486 			mutex_exit(&msp->ms_lock);
1487 		}
1488 	}
1489 }
1490 
1491 /*
1492  * Verify that the sum of the sizes of all blocks in the pool adds up
1493  * to the SPA's sa_alloc total.
1494  */
1495 typedef struct zdb_blkstats {
1496 	uint64_t	zb_asize;
1497 	uint64_t	zb_lsize;
1498 	uint64_t	zb_psize;
1499 	uint64_t	zb_count;
1500 } zdb_blkstats_t;
1501 
1502 #define	DMU_OT_DEFERRED	DMU_OT_NONE
1503 #define	DMU_OT_TOTAL	DMU_OT_NUMTYPES
1504 
1505 #define	ZB_TOTAL	DN_MAX_LEVELS
1506 
1507 typedef struct zdb_cb {
1508 	zdb_blkstats_t	zcb_type[ZB_TOTAL + 1][DMU_OT_TOTAL + 1];
1509 	uint64_t	zcb_errors[256];
1510 	int		zcb_readfails;
1511 	int		zcb_haderrors;
1512 } zdb_cb_t;
1513 
1514 static void
1515 zdb_count_block(spa_t *spa, zdb_cb_t *zcb, blkptr_t *bp, dmu_object_type_t type)
1516 {
1517 	for (int i = 0; i < 4; i++) {
1518 		int l = (i < 2) ? BP_GET_LEVEL(bp) : ZB_TOTAL;
1519 		int t = (i & 1) ? type : DMU_OT_TOTAL;
1520 		zdb_blkstats_t *zb = &zcb->zcb_type[l][t];
1521 
1522 		zb->zb_asize += BP_GET_ASIZE(bp);
1523 		zb->zb_lsize += BP_GET_LSIZE(bp);
1524 		zb->zb_psize += BP_GET_PSIZE(bp);
1525 		zb->zb_count++;
1526 	}
1527 
1528 	if (dump_opt['S']) {
1529 		boolean_t print_sig;
1530 
1531 		print_sig = !zdb_sig_user_data || (BP_GET_LEVEL(bp) == 0 &&
1532 		    BP_GET_TYPE(bp) == DMU_OT_PLAIN_FILE_CONTENTS);
1533 
1534 		if (BP_GET_CHECKSUM(bp) < zdb_sig_cksumalg)
1535 			print_sig = B_FALSE;
1536 
1537 		if (print_sig) {
1538 			(void) printf("%llu\t%lld\t%lld\t%s\t%s\t%s\t"
1539 			    "%llx:%llx:%llx:%llx\n",
1540 			    (u_longlong_t)BP_GET_LEVEL(bp),
1541 			    (longlong_t)BP_GET_PSIZE(bp),
1542 			    (longlong_t)BP_GET_NDVAS(bp),
1543 			    dmu_ot[BP_GET_TYPE(bp)].ot_name,
1544 			    zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name,
1545 			    zio_compress_table[BP_GET_COMPRESS(bp)].ci_name,
1546 			    (u_longlong_t)bp->blk_cksum.zc_word[0],
1547 			    (u_longlong_t)bp->blk_cksum.zc_word[1],
1548 			    (u_longlong_t)bp->blk_cksum.zc_word[2],
1549 			    (u_longlong_t)bp->blk_cksum.zc_word[3]);
1550 		}
1551 	}
1552 
1553 	if (!dump_opt['L'])
1554 		VERIFY(zio_wait(zio_claim(NULL, spa, spa_first_txg(spa), bp,
1555 		    NULL, NULL, ZIO_FLAG_MUSTSUCCEED)) == 0);
1556 }
1557 
1558 static int
1559 zdb_blkptr_cb(spa_t *spa, blkptr_t *bp, const zbookmark_t *zb,
1560     const dnode_phys_t *dnp, void *arg)
1561 {
1562 	zdb_cb_t *zcb = arg;
1563 	char blkbuf[BP_SPRINTF_LEN];
1564 	dmu_object_type_t type;
1565 	boolean_t is_l0_metadata;
1566 
1567 	if (bp == NULL)
1568 		return (0);
1569 
1570 	type = BP_GET_TYPE(bp);
1571 
1572 	zdb_count_block(spa, zcb, bp, type);
1573 
1574 	/*
1575 	 * if we do metadata-only checksumming there's no need to checksum
1576 	 * indirect blocks here because it is done during traverse
1577 	 */
1578 	is_l0_metadata = (BP_GET_LEVEL(bp) == 0 && type < DMU_OT_NUMTYPES &&
1579 	    dmu_ot[type].ot_metadata);
1580 
1581 	if (dump_opt['c'] > 1 || dump_opt['S'] ||
1582 	    (dump_opt['c'] && is_l0_metadata)) {
1583 		int ioerr, size;
1584 		void *data;
1585 
1586 		size = BP_GET_LSIZE(bp);
1587 		data = malloc(size);
1588 		ioerr = zio_wait(zio_read(NULL, spa, bp, data, size,
1589 		    NULL, NULL, ZIO_PRIORITY_ASYNC_READ,
1590 		    ZIO_FLAG_CANFAIL | ZIO_FLAG_SCRUB, zb));
1591 		free(data);
1592 
1593 		/* We expect io errors on intent log */
1594 		if (ioerr && type != DMU_OT_INTENT_LOG) {
1595 			zcb->zcb_haderrors = 1;
1596 			zcb->zcb_errors[ioerr]++;
1597 
1598 			if (dump_opt['b'] >= 2)
1599 				sprintf_blkptr(blkbuf, BP_SPRINTF_LEN, bp);
1600 			else
1601 				blkbuf[0] = '\0';
1602 
1603 			if (!dump_opt['S']) {
1604 				(void) printf("zdb_blkptr_cb: "
1605 				    "Got error %d reading "
1606 				    "<%llu, %llu, %lld, %llx> %s -- skipping\n",
1607 				    ioerr,
1608 				    (u_longlong_t)zb->zb_objset,
1609 				    (u_longlong_t)zb->zb_object,
1610 				    (u_longlong_t)zb->zb_level,
1611 				    (u_longlong_t)zb->zb_blkid,
1612 				    blkbuf);
1613 			}
1614 		}
1615 	}
1616 
1617 	zcb->zcb_readfails = 0;
1618 
1619 	if (dump_opt['b'] >= 4) {
1620 		sprintf_blkptr(blkbuf, BP_SPRINTF_LEN, bp);
1621 		(void) printf("objset %llu object %llu offset 0x%llx %s\n",
1622 		    (u_longlong_t)zb->zb_objset,
1623 		    (u_longlong_t)zb->zb_object,
1624 		    (u_longlong_t)blkid2offset(dnp, zb->zb_level, zb->zb_blkid),
1625 		    blkbuf);
1626 	}
1627 
1628 	return (0);
1629 }
1630 
1631 static int
1632 dump_block_stats(spa_t *spa)
1633 {
1634 	zdb_cb_t zcb = { 0 };
1635 	zdb_blkstats_t *zb, *tzb;
1636 	uint64_t alloc, space, logalloc;
1637 	vdev_t *rvd = spa->spa_root_vdev;
1638 	int leaks = 0;
1639 	int c, e;
1640 
1641 	if (!dump_opt['S']) {
1642 		(void) printf("\nTraversing all blocks %s%s%s%s%s...\n",
1643 		    (dump_opt['c'] || !dump_opt['L']) ? "to verify " : "",
1644 		    (dump_opt['c'] == 1) ? "metadata " : "",
1645 		    dump_opt['c'] ? "checksums " : "",
1646 		    (dump_opt['c'] && !dump_opt['L']) ? "and verify " : "",
1647 		    !dump_opt['L'] ? "nothing leaked " : "");
1648 	}
1649 
1650 	/*
1651 	 * Load all space maps as SM_ALLOC maps, then traverse the pool
1652 	 * claiming each block we discover.  If the pool is perfectly
1653 	 * consistent, the space maps will be empty when we're done.
1654 	 * Anything left over is a leak; any block we can't claim (because
1655 	 * it's not part of any space map) is a double allocation,
1656 	 * reference to a freed block, or an unclaimed log block.
1657 	 */
1658 	if (!dump_opt['L'])
1659 		zdb_leak_init(spa);
1660 
1661 	/*
1662 	 * If there's a deferred-free bplist, process that first.
1663 	 */
1664 	if (spa->spa_sync_bplist_obj != 0) {
1665 		bplist_t *bpl = &spa->spa_sync_bplist;
1666 		blkptr_t blk;
1667 		uint64_t itor = 0;
1668 
1669 		VERIFY(0 == bplist_open(bpl, spa->spa_meta_objset,
1670 		    spa->spa_sync_bplist_obj));
1671 
1672 		while (bplist_iterate(bpl, &itor, &blk) == 0) {
1673 			if (dump_opt['b'] >= 4) {
1674 				char blkbuf[BP_SPRINTF_LEN];
1675 				sprintf_blkptr(blkbuf, BP_SPRINTF_LEN, &blk);
1676 				(void) printf("[%s] %s\n",
1677 				    "deferred free", blkbuf);
1678 			}
1679 			zdb_count_block(spa, &zcb, &blk, DMU_OT_DEFERRED);
1680 		}
1681 
1682 		bplist_close(bpl);
1683 	}
1684 
1685 	zcb.zcb_haderrors |= traverse_pool(spa, zdb_blkptr_cb, &zcb);
1686 
1687 	if (zcb.zcb_haderrors && !dump_opt['S']) {
1688 		(void) printf("\nError counts:\n\n");
1689 		(void) printf("\t%5s  %s\n", "errno", "count");
1690 		for (e = 0; e < 256; e++) {
1691 			if (zcb.zcb_errors[e] != 0) {
1692 				(void) printf("\t%5d  %llu\n",
1693 				    e, (u_longlong_t)zcb.zcb_errors[e]);
1694 			}
1695 		}
1696 	}
1697 
1698 	/*
1699 	 * Report any leaked segments.
1700 	 */
1701 	if (!dump_opt['L'])
1702 		zdb_leak_fini(spa);
1703 
1704 	/*
1705 	 * If we're interested in printing out the blkptr signatures,
1706 	 * return now as we don't print out anything else (including
1707 	 * errors and leaks).
1708 	 */
1709 	if (dump_opt['S'])
1710 		return (zcb.zcb_haderrors ? 3 : 0);
1711 
1712 	alloc = spa_get_alloc(spa);
1713 	space = spa_get_space(spa);
1714 
1715 	/*
1716 	 * Log blocks allocated from a separate log device don't count
1717 	 * as part of the normal pool space; factor them in here.
1718 	 */
1719 	logalloc = 0;
1720 
1721 	for (c = 0; c < rvd->vdev_children; c++)
1722 		if (rvd->vdev_child[c]->vdev_islog)
1723 			logalloc += rvd->vdev_child[c]->vdev_stat.vs_alloc;
1724 
1725 	tzb = &zcb.zcb_type[ZB_TOTAL][DMU_OT_TOTAL];
1726 
1727 	if (tzb->zb_asize == alloc + logalloc) {
1728 		if (!dump_opt['L'])
1729 			(void) printf("\n\tNo leaks (block sum matches space"
1730 			    " maps exactly)\n");
1731 	} else {
1732 		(void) printf("block traversal size %llu != alloc %llu "
1733 		    "(%s %lld)\n",
1734 		    (u_longlong_t)tzb->zb_asize,
1735 		    (u_longlong_t)alloc + logalloc,
1736 		    (dump_opt['L']) ? "unreachable" : "leaked",
1737 		    (longlong_t)(alloc + logalloc - tzb->zb_asize));
1738 		leaks = 1;
1739 	}
1740 
1741 	if (tzb->zb_count == 0)
1742 		return (2);
1743 
1744 	(void) printf("\n");
1745 	(void) printf("\tbp count:      %10llu\n",
1746 	    (u_longlong_t)tzb->zb_count);
1747 	(void) printf("\tbp logical:    %10llu\t avg: %6llu\n",
1748 	    (u_longlong_t)tzb->zb_lsize,
1749 	    (u_longlong_t)(tzb->zb_lsize / tzb->zb_count));
1750 	(void) printf("\tbp physical:   %10llu\t avg:"
1751 	    " %6llu\tcompression: %6.2f\n",
1752 	    (u_longlong_t)tzb->zb_psize,
1753 	    (u_longlong_t)(tzb->zb_psize / tzb->zb_count),
1754 	    (double)tzb->zb_lsize / tzb->zb_psize);
1755 	(void) printf("\tbp allocated:  %10llu\t avg:"
1756 	    " %6llu\tcompression: %6.2f\n",
1757 	    (u_longlong_t)tzb->zb_asize,
1758 	    (u_longlong_t)(tzb->zb_asize / tzb->zb_count),
1759 	    (double)tzb->zb_lsize / tzb->zb_asize);
1760 	(void) printf("\tSPA allocated: %10llu\tused: %5.2f%%\n",
1761 	    (u_longlong_t)alloc, 100.0 * alloc / space);
1762 
1763 	if (dump_opt['b'] >= 2) {
1764 		int l, t, level;
1765 		(void) printf("\nBlocks\tLSIZE\tPSIZE\tASIZE"
1766 		    "\t  avg\t comp\t%%Total\tType\n");
1767 
1768 		for (t = 0; t <= DMU_OT_NUMTYPES; t++) {
1769 			char csize[6], lsize[6], psize[6], asize[6], avg[6];
1770 			char *typename;
1771 
1772 			typename = t == DMU_OT_DEFERRED ? "deferred free" :
1773 			    t == DMU_OT_TOTAL ? "Total" : dmu_ot[t].ot_name;
1774 
1775 			if (zcb.zcb_type[ZB_TOTAL][t].zb_asize == 0) {
1776 				(void) printf("%6s\t%5s\t%5s\t%5s"
1777 				    "\t%5s\t%5s\t%6s\t%s\n",
1778 				    "-",
1779 				    "-",
1780 				    "-",
1781 				    "-",
1782 				    "-",
1783 				    "-",
1784 				    "-",
1785 				    typename);
1786 				continue;
1787 			}
1788 
1789 			for (l = ZB_TOTAL - 1; l >= -1; l--) {
1790 				level = (l == -1 ? ZB_TOTAL : l);
1791 				zb = &zcb.zcb_type[level][t];
1792 
1793 				if (zb->zb_asize == 0)
1794 					continue;
1795 
1796 				if (dump_opt['b'] < 3 && level != ZB_TOTAL)
1797 					continue;
1798 
1799 				if (level == 0 && zb->zb_asize ==
1800 				    zcb.zcb_type[ZB_TOTAL][t].zb_asize)
1801 					continue;
1802 
1803 				nicenum(zb->zb_count, csize);
1804 				nicenum(zb->zb_lsize, lsize);
1805 				nicenum(zb->zb_psize, psize);
1806 				nicenum(zb->zb_asize, asize);
1807 				nicenum(zb->zb_asize / zb->zb_count, avg);
1808 
1809 				(void) printf("%6s\t%5s\t%5s\t%5s\t%5s"
1810 				    "\t%5.2f\t%6.2f\t",
1811 				    csize, lsize, psize, asize, avg,
1812 				    (double)zb->zb_lsize / zb->zb_psize,
1813 				    100.0 * zb->zb_asize / tzb->zb_asize);
1814 
1815 				if (level == ZB_TOTAL)
1816 					(void) printf("%s\n", typename);
1817 				else
1818 					(void) printf("    L%d %s\n",
1819 					    level, typename);
1820 			}
1821 		}
1822 	}
1823 
1824 	(void) printf("\n");
1825 
1826 	if (leaks)
1827 		return (2);
1828 
1829 	if (zcb.zcb_haderrors)
1830 		return (3);
1831 
1832 	return (0);
1833 }
1834 
1835 static void
1836 dump_zpool(spa_t *spa)
1837 {
1838 	dsl_pool_t *dp = spa_get_dsl(spa);
1839 	int rc = 0;
1840 
1841 	if (dump_opt['u'])
1842 		dump_uberblock(&spa->spa_uberblock);
1843 
1844 	if (dump_opt['d'] || dump_opt['i'] || dump_opt['m']) {
1845 		dump_dir(dp->dp_meta_objset);
1846 		if (dump_opt['d'] >= 3) {
1847 			dump_bplist(dp->dp_meta_objset,
1848 			    spa->spa_sync_bplist_obj, "Deferred frees");
1849 			dump_dtl(spa->spa_root_vdev, 0);
1850 		}
1851 
1852 		if (dump_opt['d'] >= 3 || dump_opt['m'])
1853 			dump_metaslabs(spa);
1854 
1855 		(void) dmu_objset_find(spa_name(spa), dump_one_dir, NULL,
1856 		    DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
1857 	}
1858 
1859 	if (dump_opt['b'] || dump_opt['c'] || dump_opt['S'])
1860 		rc = dump_block_stats(spa);
1861 
1862 	if (dump_opt['s'])
1863 		show_pool_stats(spa);
1864 
1865 	if (dump_opt['h'])
1866 		dump_history(spa);
1867 
1868 	if (rc != 0)
1869 		exit(rc);
1870 }
1871 
1872 #define	ZDB_FLAG_CHECKSUM	0x0001
1873 #define	ZDB_FLAG_DECOMPRESS	0x0002
1874 #define	ZDB_FLAG_BSWAP		0x0004
1875 #define	ZDB_FLAG_GBH		0x0008
1876 #define	ZDB_FLAG_INDIRECT	0x0010
1877 #define	ZDB_FLAG_PHYS		0x0020
1878 #define	ZDB_FLAG_RAW		0x0040
1879 #define	ZDB_FLAG_PRINT_BLKPTR	0x0080
1880 
1881 int flagbits[256];
1882 
1883 static void
1884 zdb_print_blkptr(blkptr_t *bp, int flags)
1885 {
1886 	dva_t *dva = bp->blk_dva;
1887 	int d;
1888 
1889 	if (flags & ZDB_FLAG_BSWAP)
1890 		byteswap_uint64_array((void *)bp, sizeof (blkptr_t));
1891 	/*
1892 	 * Super-ick warning:  This code is also duplicated in
1893 	 * cmd/mdb/common/modules/zfs/zfs.c .  Yeah, I hate code
1894 	 * replication, too.
1895 	 */
1896 	for (d = 0; d < BP_GET_NDVAS(bp); d++) {
1897 		(void) printf("\tDVA[%d]: vdev_id %lld / %llx\n", d,
1898 		    (longlong_t)DVA_GET_VDEV(&dva[d]),
1899 		    (longlong_t)DVA_GET_OFFSET(&dva[d]));
1900 		(void) printf("\tDVA[%d]:       GANG: %-5s  GRID:  %04llx\t"
1901 		    "ASIZE: %llx\n", d,
1902 		    DVA_GET_GANG(&dva[d]) ? "TRUE" : "FALSE",
1903 		    (longlong_t)DVA_GET_GRID(&dva[d]),
1904 		    (longlong_t)DVA_GET_ASIZE(&dva[d]));
1905 		(void) printf("\tDVA[%d]: :%llu:%llx:%llx:%s%s%s%s\n", d,
1906 		    (u_longlong_t)DVA_GET_VDEV(&dva[d]),
1907 		    (longlong_t)DVA_GET_OFFSET(&dva[d]),
1908 		    (longlong_t)BP_GET_PSIZE(bp),
1909 		    BP_SHOULD_BYTESWAP(bp) ? "e" : "",
1910 		    !DVA_GET_GANG(&dva[d]) && BP_GET_LEVEL(bp) != 0 ?
1911 		    "d" : "",
1912 		    DVA_GET_GANG(&dva[d]) ? "g" : "",
1913 		    BP_GET_COMPRESS(bp) != 0 ? "d" : "");
1914 	}
1915 	(void) printf("\tLSIZE:  %-16llx\t\tPSIZE: %llx\n",
1916 	    (longlong_t)BP_GET_LSIZE(bp), (longlong_t)BP_GET_PSIZE(bp));
1917 	(void) printf("\tENDIAN: %6s\t\t\t\t\tTYPE:  %s\n",
1918 	    BP_GET_BYTEORDER(bp) ? "LITTLE" : "BIG",
1919 	    dmu_ot[BP_GET_TYPE(bp)].ot_name);
1920 	(void) printf("\tBIRTH:  %-16llx   LEVEL: %-2llu\tFILL:  %llx\n",
1921 	    (u_longlong_t)bp->blk_birth, (u_longlong_t)BP_GET_LEVEL(bp),
1922 	    (u_longlong_t)bp->blk_fill);
1923 	(void) printf("\tCKFUNC: %-16s\t\tCOMP:  %s\n",
1924 	    zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name,
1925 	    zio_compress_table[BP_GET_COMPRESS(bp)].ci_name);
1926 	(void) printf("\tCKSUM:  %llx:%llx:%llx:%llx\n",
1927 	    (u_longlong_t)bp->blk_cksum.zc_word[0],
1928 	    (u_longlong_t)bp->blk_cksum.zc_word[1],
1929 	    (u_longlong_t)bp->blk_cksum.zc_word[2],
1930 	    (u_longlong_t)bp->blk_cksum.zc_word[3]);
1931 }
1932 
1933 static void
1934 zdb_dump_indirect(blkptr_t *bp, int nbps, int flags)
1935 {
1936 	int i;
1937 
1938 	for (i = 0; i < nbps; i++)
1939 		zdb_print_blkptr(&bp[i], flags);
1940 }
1941 
1942 static void
1943 zdb_dump_gbh(void *buf, int flags)
1944 {
1945 	zdb_dump_indirect((blkptr_t *)buf, SPA_GBH_NBLKPTRS, flags);
1946 }
1947 
1948 static void
1949 zdb_dump_block_raw(void *buf, uint64_t size, int flags)
1950 {
1951 	if (flags & ZDB_FLAG_BSWAP)
1952 		byteswap_uint64_array(buf, size);
1953 	(void) write(2, buf, size);
1954 }
1955 
1956 static void
1957 zdb_dump_block(char *label, void *buf, uint64_t size, int flags)
1958 {
1959 	uint64_t *d = (uint64_t *)buf;
1960 	int nwords = size / sizeof (uint64_t);
1961 	int do_bswap = !!(flags & ZDB_FLAG_BSWAP);
1962 	int i, j;
1963 	char *hdr, *c;
1964 
1965 
1966 	if (do_bswap)
1967 		hdr = " 7 6 5 4 3 2 1 0   f e d c b a 9 8";
1968 	else
1969 		hdr = " 0 1 2 3 4 5 6 7   8 9 a b c d e f";
1970 
1971 	(void) printf("\n%s\n%6s   %s  0123456789abcdef\n", label, "", hdr);
1972 
1973 	for (i = 0; i < nwords; i += 2) {
1974 		(void) printf("%06llx:  %016llx  %016llx  ",
1975 		    (u_longlong_t)(i * sizeof (uint64_t)),
1976 		    (u_longlong_t)(do_bswap ? BSWAP_64(d[i]) : d[i]),
1977 		    (u_longlong_t)(do_bswap ? BSWAP_64(d[i + 1]) : d[i + 1]));
1978 
1979 		c = (char *)&d[i];
1980 		for (j = 0; j < 2 * sizeof (uint64_t); j++)
1981 			(void) printf("%c", isprint(c[j]) ? c[j] : '.');
1982 		(void) printf("\n");
1983 	}
1984 }
1985 
1986 /*
1987  * There are two acceptable formats:
1988  *	leaf_name	  - For example: c1t0d0 or /tmp/ztest.0a
1989  *	child[.child]*    - For example: 0.1.1
1990  *
1991  * The second form can be used to specify arbitrary vdevs anywhere
1992  * in the heirarchy.  For example, in a pool with a mirror of
1993  * RAID-Zs, you can specify either RAID-Z vdev with 0.0 or 0.1 .
1994  */
1995 static vdev_t *
1996 zdb_vdev_lookup(vdev_t *vdev, char *path)
1997 {
1998 	char *s, *p, *q;
1999 	int i;
2000 
2001 	if (vdev == NULL)
2002 		return (NULL);
2003 
2004 	/* First, assume the x.x.x.x format */
2005 	i = (int)strtoul(path, &s, 10);
2006 	if (s == path || (s && *s != '.' && *s != '\0'))
2007 		goto name;
2008 	if (i < 0 || i >= vdev->vdev_children)
2009 		return (NULL);
2010 
2011 	vdev = vdev->vdev_child[i];
2012 	if (*s == '\0')
2013 		return (vdev);
2014 	return (zdb_vdev_lookup(vdev, s+1));
2015 
2016 name:
2017 	for (i = 0; i < vdev->vdev_children; i++) {
2018 		vdev_t *vc = vdev->vdev_child[i];
2019 
2020 		if (vc->vdev_path == NULL) {
2021 			vc = zdb_vdev_lookup(vc, path);
2022 			if (vc == NULL)
2023 				continue;
2024 			else
2025 				return (vc);
2026 		}
2027 
2028 		p = strrchr(vc->vdev_path, '/');
2029 		p = p ? p + 1 : vc->vdev_path;
2030 		q = &vc->vdev_path[strlen(vc->vdev_path) - 2];
2031 
2032 		if (strcmp(vc->vdev_path, path) == 0)
2033 			return (vc);
2034 		if (strcmp(p, path) == 0)
2035 			return (vc);
2036 		if (strcmp(q, "s0") == 0 && strncmp(p, path, q - p) == 0)
2037 			return (vc);
2038 	}
2039 
2040 	return (NULL);
2041 }
2042 
2043 /*
2044  * Read a block from a pool and print it out.  The syntax of the
2045  * block descriptor is:
2046  *
2047  *	pool:vdev_specifier:offset:size[:flags]
2048  *
2049  *	pool           - The name of the pool you wish to read from
2050  *	vdev_specifier - Which vdev (see comment for zdb_vdev_lookup)
2051  *	offset         - offset, in hex, in bytes
2052  *	size           - Amount of data to read, in hex, in bytes
2053  *	flags          - A string of characters specifying options
2054  *		 b: Decode a blkptr at given offset within block
2055  *		*c: Calculate and display checksums
2056  *		*d: Decompress data before dumping
2057  *		 e: Byteswap data before dumping
2058  *		*g: Display data as a gang block header
2059  *		*i: Display as an indirect block
2060  *		 p: Do I/O to physical offset
2061  *		 r: Dump raw data to stdout
2062  *
2063  *              * = not yet implemented
2064  */
2065 static void
2066 zdb_read_block(char *thing, spa_t **spap)
2067 {
2068 	spa_t *spa = *spap;
2069 	int flags = 0;
2070 	uint64_t offset = 0, size = 0, blkptr_offset = 0;
2071 	zio_t *zio;
2072 	vdev_t *vd;
2073 	void *buf;
2074 	char *s, *p, *dup, *pool, *vdev, *flagstr;
2075 	int i, error, zio_flags;
2076 
2077 	dup = strdup(thing);
2078 	s = strtok(dup, ":");
2079 	pool = s ? s : "";
2080 	s = strtok(NULL, ":");
2081 	vdev = s ? s : "";
2082 	s = strtok(NULL, ":");
2083 	offset = strtoull(s ? s : "", NULL, 16);
2084 	s = strtok(NULL, ":");
2085 	size = strtoull(s ? s : "", NULL, 16);
2086 	s = strtok(NULL, ":");
2087 	flagstr = s ? s : "";
2088 
2089 	s = NULL;
2090 	if (size == 0)
2091 		s = "size must not be zero";
2092 	if (!IS_P2ALIGNED(size, DEV_BSIZE))
2093 		s = "size must be a multiple of sector size";
2094 	if (!IS_P2ALIGNED(offset, DEV_BSIZE))
2095 		s = "offset must be a multiple of sector size";
2096 	if (s) {
2097 		(void) printf("Invalid block specifier: %s  - %s\n", thing, s);
2098 		free(dup);
2099 		return;
2100 	}
2101 
2102 	for (s = strtok(flagstr, ":"); s; s = strtok(NULL, ":")) {
2103 		for (i = 0; flagstr[i]; i++) {
2104 			int bit = flagbits[(uchar_t)flagstr[i]];
2105 
2106 			if (bit == 0) {
2107 				(void) printf("***Invalid flag: %c\n",
2108 				    flagstr[i]);
2109 				continue;
2110 			}
2111 			flags |= bit;
2112 
2113 			/* If it's not something with an argument, keep going */
2114 			if ((bit & (ZDB_FLAG_CHECKSUM | ZDB_FLAG_DECOMPRESS |
2115 			    ZDB_FLAG_PRINT_BLKPTR)) == 0)
2116 				continue;
2117 
2118 			p = &flagstr[i + 1];
2119 			if (bit == ZDB_FLAG_PRINT_BLKPTR)
2120 				blkptr_offset = strtoull(p, &p, 16);
2121 			if (*p != ':' && *p != '\0') {
2122 				(void) printf("***Invalid flag arg: '%s'\n", s);
2123 				free(dup);
2124 				return;
2125 			}
2126 		}
2127 	}
2128 
2129 	if (spa == NULL || strcmp(spa_name(spa), pool) != 0) {
2130 		if (spa)
2131 			spa_close(spa, (void *)zdb_read_block);
2132 		error = spa_open(pool, spap, (void *)zdb_read_block);
2133 		if (error)
2134 			fatal("Failed to open pool '%s': %s",
2135 			    pool, strerror(error));
2136 		spa = *spap;
2137 	}
2138 
2139 	vd = zdb_vdev_lookup(spa->spa_root_vdev, vdev);
2140 	if (vd == NULL) {
2141 		(void) printf("***Invalid vdev: %s\n", vdev);
2142 		free(dup);
2143 		return;
2144 	} else {
2145 		if (vd->vdev_path)
2146 			(void) printf("Found vdev: %s\n", vd->vdev_path);
2147 		else
2148 			(void) printf("Found vdev type: %s\n",
2149 			    vd->vdev_ops->vdev_op_type);
2150 	}
2151 
2152 	buf = umem_alloc(size, UMEM_NOFAIL);
2153 
2154 	zio_flags = ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_QUEUE |
2155 	    ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY;
2156 
2157 	spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
2158 	zio = zio_root(spa, NULL, NULL, 0);
2159 	/* XXX todo - cons up a BP so RAID-Z will be happy */
2160 	zio_nowait(zio_vdev_child_io(zio, NULL, vd, offset, buf, size,
2161 	    ZIO_TYPE_READ, ZIO_PRIORITY_SYNC_READ, zio_flags, NULL, NULL));
2162 	error = zio_wait(zio);
2163 	spa_config_exit(spa, SCL_STATE, FTAG);
2164 
2165 	if (error) {
2166 		(void) printf("Read of %s failed, error: %d\n", thing, error);
2167 		goto out;
2168 	}
2169 
2170 	if (flags & ZDB_FLAG_PRINT_BLKPTR)
2171 		zdb_print_blkptr((blkptr_t *)(void *)
2172 		    ((uintptr_t)buf + (uintptr_t)blkptr_offset), flags);
2173 	else if (flags & ZDB_FLAG_RAW)
2174 		zdb_dump_block_raw(buf, size, flags);
2175 	else if (flags & ZDB_FLAG_INDIRECT)
2176 		zdb_dump_indirect((blkptr_t *)buf, size / sizeof (blkptr_t),
2177 		    flags);
2178 	else if (flags & ZDB_FLAG_GBH)
2179 		zdb_dump_gbh(buf, flags);
2180 	else
2181 		zdb_dump_block(thing, buf, size, flags);
2182 
2183 out:
2184 	umem_free(buf, size);
2185 	free(dup);
2186 }
2187 
2188 static boolean_t
2189 pool_match(nvlist_t *cfg, char *tgt)
2190 {
2191 	uint64_t v, guid = strtoull(tgt, NULL, 0);
2192 	char *s;
2193 
2194 	if (guid != 0) {
2195 		if (nvlist_lookup_uint64(cfg, ZPOOL_CONFIG_POOL_GUID, &v) == 0)
2196 			return (v == guid);
2197 	} else {
2198 		if (nvlist_lookup_string(cfg, ZPOOL_CONFIG_POOL_NAME, &s) == 0)
2199 			return (strcmp(s, tgt) == 0);
2200 	}
2201 	return (B_FALSE);
2202 }
2203 
2204 static char *
2205 find_zpool(char **target, nvlist_t **configp, int dirc, char **dirv)
2206 {
2207 	nvlist_t *pools;
2208 	nvlist_t *match = NULL;
2209 	char *name = NULL;
2210 	char *sepp = NULL;
2211 	char sep;
2212 	int count = 0;
2213 
2214 	if ((sepp = strpbrk(*target, "/@")) != NULL) {
2215 		sep = *sepp;
2216 		*sepp = '\0';
2217 	}
2218 
2219 	pools = zpool_find_import_activeok(g_zfs, dirc, dirv);
2220 
2221 	if (pools != NULL) {
2222 		nvpair_t *elem = NULL;
2223 		while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
2224 			verify(nvpair_value_nvlist(elem, configp) == 0);
2225 			if (pool_match(*configp, *target)) {
2226 				count++;
2227 				if (match != NULL) {
2228 					/* print previously found config */
2229 					if (name != NULL) {
2230 						(void) printf("%s\n", name);
2231 						dump_nvlist(match, 8);
2232 						name = NULL;
2233 					}
2234 					(void) printf("%s\n",
2235 					    nvpair_name(elem));
2236 					dump_nvlist(*configp, 8);
2237 				} else {
2238 					match = *configp;
2239 					name = nvpair_name(elem);
2240 				}
2241 			}
2242 		}
2243 	}
2244 	if (count > 1)
2245 		(void) fatal("\tMatched %d pools - use pool GUID "
2246 		    "instead of pool name or \n"
2247 		    "\tpool name part of a dataset name to select pool", count);
2248 
2249 	if (sepp)
2250 		*sepp = sep;
2251 	/*
2252 	 * If pool GUID was specified for pool id, replace it with pool name
2253 	 */
2254 	if (name && (strstr(*target, name) != *target)) {
2255 		int sz = 1 + strlen(name) + ((sepp) ? strlen(sepp) : 0);
2256 
2257 		*target = umem_alloc(sz, UMEM_NOFAIL);
2258 		(void) snprintf(*target, sz, "%s%s", name, sepp ? sepp : "");
2259 	}
2260 
2261 	*configp = name ? match : NULL;
2262 
2263 	return (name);
2264 }
2265 
2266 int
2267 main(int argc, char **argv)
2268 {
2269 	int i, c;
2270 	struct rlimit rl = { 1024, 1024 };
2271 	spa_t *spa = NULL;
2272 	objset_t *os = NULL;
2273 	char *endstr;
2274 	int dump_all = 1;
2275 	int verbose = 0;
2276 	int error;
2277 	char **searchdirs = NULL;
2278 	int nsearch = 0;
2279 	char *target;
2280 
2281 	(void) setrlimit(RLIMIT_NOFILE, &rl);
2282 	(void) enable_extended_FILE_stdio(-1, -1);
2283 
2284 	dprintf_setup(&argc, argv);
2285 
2286 	while ((c = getopt(argc, argv, "udhibcmsvCLS:U:lRep:t:")) != -1) {
2287 		switch (c) {
2288 		case 'u':
2289 		case 'd':
2290 		case 'i':
2291 		case 'h':
2292 		case 'b':
2293 		case 'c':
2294 		case 'm':
2295 		case 's':
2296 		case 'C':
2297 		case 'l':
2298 		case 'R':
2299 			dump_opt[c]++;
2300 			dump_all = 0;
2301 			break;
2302 		case 'L':
2303 		case 'e':
2304 			dump_opt[c]++;
2305 			break;
2306 		case 'v':
2307 			verbose++;
2308 			break;
2309 		case 'U':
2310 			spa_config_path = optarg;
2311 			break;
2312 		case 'p':
2313 			if (searchdirs == NULL) {
2314 				searchdirs = umem_alloc(sizeof (char *),
2315 				    UMEM_NOFAIL);
2316 			} else {
2317 				char **tmp = umem_alloc((nsearch + 1) *
2318 				    sizeof (char *), UMEM_NOFAIL);
2319 				bcopy(searchdirs, tmp, nsearch *
2320 				    sizeof (char *));
2321 				umem_free(searchdirs,
2322 				    nsearch * sizeof (char *));
2323 				searchdirs = tmp;
2324 			}
2325 			searchdirs[nsearch++] = optarg;
2326 			break;
2327 		case 'S':
2328 			dump_opt[c]++;
2329 			dump_all = 0;
2330 			zdb_sig_user_data = (strncmp(optarg, "user:", 5) == 0);
2331 			if (!zdb_sig_user_data && strncmp(optarg, "all:", 4))
2332 				usage();
2333 			endstr = strchr(optarg, ':') + 1;
2334 			if (strcmp(endstr, "fletcher2") == 0)
2335 				zdb_sig_cksumalg = ZIO_CHECKSUM_FLETCHER_2;
2336 			else if (strcmp(endstr, "fletcher4") == 0)
2337 				zdb_sig_cksumalg = ZIO_CHECKSUM_FLETCHER_4;
2338 			else if (strcmp(endstr, "sha256") == 0)
2339 				zdb_sig_cksumalg = ZIO_CHECKSUM_SHA256;
2340 			else if (strcmp(endstr, "all") == 0)
2341 				zdb_sig_cksumalg = ZIO_CHECKSUM_FLETCHER_2;
2342 			else
2343 				usage();
2344 			break;
2345 		case 't':
2346 			ub_max_txg = strtoull(optarg, NULL, 0);
2347 			if (ub_max_txg < TXG_INITIAL) {
2348 				(void) fprintf(stderr, "incorrect txg "
2349 				    "specified: %s\n", optarg);
2350 				usage();
2351 			}
2352 			break;
2353 		default:
2354 			usage();
2355 			break;
2356 		}
2357 	}
2358 
2359 	if (!dump_opt['e'] && searchdirs != NULL) {
2360 		(void) fprintf(stderr, "-p option requires use of -e\n");
2361 		usage();
2362 	}
2363 
2364 	kernel_init(FREAD);
2365 	g_zfs = libzfs_init();
2366 	ASSERT(g_zfs != NULL);
2367 
2368 	for (c = 0; c < 256; c++) {
2369 		if (dump_all && !strchr("elLR", c))
2370 			dump_opt[c] = 1;
2371 		if (dump_opt[c])
2372 			dump_opt[c] += verbose;
2373 	}
2374 
2375 	argc -= optind;
2376 	argv += optind;
2377 
2378 	if (argc < 1) {
2379 		if (!dump_opt['e'] && dump_opt['C']) {
2380 			dump_cachefile(spa_config_path);
2381 			return (0);
2382 		}
2383 		usage();
2384 	}
2385 
2386 	if (dump_opt['l']) {
2387 		dump_label(argv[0]);
2388 		return (0);
2389 	}
2390 
2391 	if (dump_opt['R']) {
2392 		flagbits['b'] = ZDB_FLAG_PRINT_BLKPTR;
2393 		flagbits['c'] = ZDB_FLAG_CHECKSUM;
2394 		flagbits['d'] = ZDB_FLAG_DECOMPRESS;
2395 		flagbits['e'] = ZDB_FLAG_BSWAP;
2396 		flagbits['g'] = ZDB_FLAG_GBH;
2397 		flagbits['i'] = ZDB_FLAG_INDIRECT;
2398 		flagbits['p'] = ZDB_FLAG_PHYS;
2399 		flagbits['r'] = ZDB_FLAG_RAW;
2400 
2401 		spa = NULL;
2402 		while (argv[0]) {
2403 			zdb_read_block(argv[0], &spa);
2404 			argv++;
2405 			argc--;
2406 		}
2407 		if (spa)
2408 			spa_close(spa, (void *)zdb_read_block);
2409 		return (0);
2410 	}
2411 
2412 	if (dump_opt['C'])
2413 		dump_config(argv[0]);
2414 
2415 	error = 0;
2416 	target = argv[0];
2417 
2418 	if (dump_opt['e']) {
2419 		nvlist_t *cfg = NULL;
2420 		char *name = find_zpool(&target, &cfg, nsearch, searchdirs);
2421 
2422 		error = ENOENT;
2423 		if (name) {
2424 			if ((error = spa_import(name, cfg, NULL)) != 0)
2425 				error = spa_import_verbatim(name, cfg, NULL);
2426 		}
2427 	}
2428 
2429 	if (error == 0) {
2430 		if (strpbrk(target, "/@") != NULL) {
2431 			error = dmu_objset_own(target, DMU_OST_ANY,
2432 			    B_TRUE, FTAG, &os);
2433 		} else {
2434 			error = spa_open(target, &spa, FTAG);
2435 			if (error) {
2436 				/*
2437 				 * If we're missing the log device then
2438 				 * try opening the pool after clearing the
2439 				 * log state.
2440 				 */
2441 				mutex_enter(&spa_namespace_lock);
2442 				if ((spa = spa_lookup(target)) != NULL &&
2443 				    spa->spa_log_state == SPA_LOG_MISSING) {
2444 					spa->spa_log_state = SPA_LOG_CLEAR;
2445 					error = 0;
2446 				}
2447 				mutex_exit(&spa_namespace_lock);
2448 
2449 				if (!error)
2450 					error = spa_open(target, &spa, FTAG);
2451 			}
2452 		}
2453 	}
2454 
2455 	if (error)
2456 		fatal("can't open '%s': %s", target, strerror(error));
2457 
2458 	argv++;
2459 	if (--argc > 0) {
2460 		zopt_objects = argc;
2461 		zopt_object = calloc(zopt_objects, sizeof (uint64_t));
2462 		for (i = 0; i < zopt_objects; i++) {
2463 			errno = 0;
2464 			zopt_object[i] = strtoull(argv[i], NULL, 0);
2465 			if (zopt_object[i] == 0 && errno != 0)
2466 				fatal("bad object number %s: %s",
2467 				    argv[i], strerror(errno));
2468 		}
2469 	}
2470 
2471 	if (os != NULL) {
2472 		dump_dir(os);
2473 		dmu_objset_disown(os, FTAG);
2474 	} else {
2475 		dump_zpool(spa);
2476 		spa_close(spa, FTAG);
2477 	}
2478 
2479 	fuid_table_destroy();
2480 
2481 	libzfs_fini(g_zfs);
2482 	kernel_fini();
2483 
2484 	return (0);
2485 }
2486