Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Apr 2017 16:58:41 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r316862 - in vendor/illumos/dist: cmd/zdb man/man1m
Message-ID:  <201704141658.v3EGwfxU030989@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Fri Apr 14 16:58:41 2017
New Revision: 316862
URL: https://svnweb.freebsd.org/changeset/base/316862

Log:
  6410 teach zdb to perform object lookups by path
  
  illumos/illumos-gate@ed61ec1da9132e570b0853386d0f78a32f852cd2
  https://github.com/illumos/illumos-gate/commit/ed61ec1da9132e570b0853386d0f78a32f852cd2
  
  https://www.illumos.org/issues/6410
    This is primarily intended to ease debugging & testing ZFS when one is only
    interested in things like the on-disk location of a specific object's blocks,
    but doesn't know their object id. This allows doing things like the following
    (FreeBSD-based example):
            # zpool create -f foo da0
            # dd if=/dev/zero of=/foo/1 bs=1M count=4 >/dev/null 2>&1
            # zpool export foo
            # zdb -vvvvv -o "ZFS plain file" foo /1
            Object  lvl   iblk   dblk  dsize  lsize   %full  type
                 8    2    16K   128K  3.99M     4M  100.00  ZFS plain file (K=inherit) (Z=inherit)
                                                168   bonus  System attributes
            dnode flags: USED_BYTES USERUSED_ACCOUNTED
            dnode maxblkid: 31
            path    /1
            uid     0
            gid     0
            atime   Thu Apr 23 22:45:32 2015
            mtime   Thu Apr 23 22:45:32 2015
            ctime   Thu Apr 23 22:45:32 2015
            crtime  Thu Apr 23 22:45:32 2015
            gen     7
            mode    100644
            size    4194304
            parent  4
            links   1
            pflags  40800000004
            Indirect blocks:
                  0 L1  DVA[0]=<0:c19200:600> DVA[1]=<0:10800019200:600> [L1 ZFS
    plain file] fletcher4 lz4 LE contiguous unique double size=4000L/200P birth=7L/
  
  Reviewed by: Pavel Zakharov <pavel.zakharov@delphix.com>
  Reviewed by: Matthew Ahrens <mahrens@delphix.com>
  Reviewed by: Will Andrews <will@freebsd.org>
  Approved by: Dan McDonald <danmcd@omniti.com>
  Author: Yuri Pankov <yuri.pankov@nexenta.com>

Modified:
  vendor/illumos/dist/cmd/zdb/zdb.c
  vendor/illumos/dist/man/man1m/zdb.1m

Modified: vendor/illumos/dist/cmd/zdb/zdb.c
==============================================================================
--- vendor/illumos/dist/cmd/zdb/zdb.c	Fri Apr 14 16:57:06 2017	(r316861)
+++ vendor/illumos/dist/cmd/zdb/zdb.c	Fri Apr 14 16:58:41 2017	(r316862)
@@ -23,7 +23,7 @@
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
- * Copyright 2016 Nexenta Systems, Inc.
+ * Copyright 2017 Nexenta Systems, Inc.
  */
 
 #include <stdio.h>
@@ -120,19 +120,22 @@ static void
 usage(void)
 {
 	(void) fprintf(stderr,
-	    "Usage: %s [-CmMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] "
-	    "[-U config] [-I inflight I/Os] [-x dumpdir] [-o var=value] "
-	    "poolname [object...]\n"
-	    "       %s [-divPA] [-e -p path...] [-U config] dataset "
-	    "[object...]\n"
-	    "       %s -mM [-LXFPA] [-t txg] [-e [-p path...]] [-U config] "
-	    "poolname [vdev [metaslab...]]\n"
-	    "       %s -R [-A] [-e [-p path...]] poolname "
-	    "vdev:offset:size[:flags]\n"
-	    "       %s -S [-PA] [-e [-p path...]] [-U config] poolname\n"
-	    "       %s -l [-Aqu] device\n"
-	    "       %s -C [-A] [-U config]\n\n",
-	    cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
+	    "Usage:\t%s [-AbcdDFGhiLMPsvX] [-e [-p <path> ...]] "
+	    "[-I <inflight I/Os>]\n"
+	    "\t\t[-o <var>=<value>]... [-t <txg>] [-U <cache>] [-x <dumpdir>]\n"
+	    "\t\t[<poolname> [<object> ...]]\n"
+	    "\t%s [-AdiPv] [-e [-p <path> ...]] [-U <cache>] <dataset> "
+	    "[<object> ...]\n"
+	    "\t%s -C [-A] [-U <cache>]\n"
+	    "\t%s -l [-Aqu] <device>\n"
+	    "\t%s -m [-AFLPX] [-e [-p <path> ...]] [-t <txg>] [-U <cache>]\n"
+	    "\t\t<poolname> [<vdev> [<metaslab> ...]]\n"
+	    "\t%s -O <dataset> <path>\n"
+	    "\t%s -R [-A] [-e [-p <path> ...]] [-U <cache>]\n"
+	    "\t\t<poolname> <vdev>:<offset>:<size>[:<flags>]\n"
+	    "\t%s -S [-AP] [-e [-p <path> ...]] [-U <cache>] <poolname>\n\n",
+	    cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname,
+	    cmdname);
 
 	(void) fprintf(stderr, "    Dataset name must include at least one "
 	    "separator character '/' or '@'\n");
@@ -141,52 +144,54 @@ usage(void)
 	(void) fprintf(stderr, "    If object numbers are specified, only "
 	    "those objects are dumped\n\n");
 	(void) fprintf(stderr, "    Options to control amount of output:\n");
-	(void) fprintf(stderr, "        -d dataset(s)\n");
-	(void) fprintf(stderr, "        -i intent logs\n");
-	(void) fprintf(stderr, "        -C config (or cachefile if alone)\n");
-	(void) fprintf(stderr, "        -h pool history\n");
 	(void) fprintf(stderr, "        -b block statistics\n");
-	(void) fprintf(stderr, "        -m metaslabs\n");
-	(void) fprintf(stderr, "        -M metaslab groups\n");
 	(void) fprintf(stderr, "        -c checksum all metadata (twice for "
 	    "all data) blocks\n");
-	(void) fprintf(stderr, "        -s report stats on zdb's I/O\n");
+	(void) fprintf(stderr, "        -C config (or cachefile if alone)\n");
+	(void) fprintf(stderr, "        -d dataset(s)\n");
 	(void) fprintf(stderr, "        -D dedup statistics\n");
-	(void) fprintf(stderr, "        -S simulate dedup to measure effect\n");
-	(void) fprintf(stderr, "        -v verbose (applies to all others)\n");
+	(void) fprintf(stderr, "        -h pool history\n");
+	(void) fprintf(stderr, "        -i intent logs\n");
 	(void) fprintf(stderr, "        -l read label contents\n");
 	(void) fprintf(stderr, "        -L disable leak tracking (do not "
 	    "load spacemaps)\n");
+	(void) fprintf(stderr, "        -m metaslabs\n");
+	(void) fprintf(stderr, "        -M metaslab groups\n");
+	(void) fprintf(stderr, "        -O perform object lookups by path\n");
 	(void) fprintf(stderr, "        -R read and display block from a "
-	    "device\n\n");
+	    "device\n");
+	(void) fprintf(stderr, "        -s report stats on zdb's I/O\n");
+	(void) fprintf(stderr, "        -S simulate dedup to measure effect\n");
+	(void) fprintf(stderr, "        -v verbose (applies to all "
+	    "others)\n\n");
 	(void) fprintf(stderr, "    Below options are intended for use "
 	    "with other options:\n");
 	(void) fprintf(stderr, "        -A ignore assertions (-A), enable "
 	    "panic recovery (-AA) or both (-AAA)\n");
-	(void) fprintf(stderr, "        -F attempt automatic rewind within "
-	    "safe range of transaction groups\n");
-	(void) fprintf(stderr, "        -U <cachefile_path> -- use alternate "
-	    "cachefile\n");
-	(void) fprintf(stderr, "        -X attempt extreme rewind (does not "
-	    "work with dataset)\n");
 	(void) fprintf(stderr, "        -e pool is exported/destroyed/"
 	    "has altroot/not in a cachefile\n");
-	(void) fprintf(stderr, "        -p <path> -- use one or more with "
-	    "-e to specify path to vdev dir\n");
-	(void) fprintf(stderr, "        -x <dumpdir> -- "
-	    "dump all read blocks into specified directory\n");
-	(void) fprintf(stderr, "        -P print numbers in parseable form\n");
-	(void) fprintf(stderr, "        -t <txg> -- highest txg to use when "
-	    "searching for uberblocks\n");
+	(void) fprintf(stderr, "        -F attempt automatic rewind within "
+	    "safe range of transaction groups\n");
+	(void) fprintf(stderr, "        -G dump zfs_dbgmsg buffer before "
+	    "exiting\n");
 	(void) fprintf(stderr, "        -I <number of inflight I/Os> -- "
 	    "specify the maximum number of "
 	    "checksumming I/Os [default is 200]\n");
-	(void) fprintf(stderr, "        -G dump zfs_dbgmsg buffer before "
-	    "exiting\n");
 	(void) fprintf(stderr, "        -o <variable>=<value> set global "
 	    "variable to an unsigned 32-bit integer value\n");
+	(void) fprintf(stderr, "        -p <path> -- use one or more with "
+	    "-e to specify path to vdev dir\n");
+	(void) fprintf(stderr, "        -P print numbers in parseable form\n");
 	(void) fprintf(stderr, "        -q don't print label contents\n");
+	(void) fprintf(stderr, "        -t <txg> -- highest txg to use when "
+	    "searching for uberblocks\n");
 	(void) fprintf(stderr, "        -u uberblock\n");
+	(void) fprintf(stderr, "        -U <cachefile_path> -- use alternate "
+	    "cachefile\n");
+	(void) fprintf(stderr, "        -x <dumpdir> -- "
+	    "dump all read blocks into specified directory\n");
+	(void) fprintf(stderr, "        -X attempt extreme rewind (does not "
+	    "work with dataset)\n\n");
 	(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
 	    "to make only that option verbose\n");
 	(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
@@ -1576,8 +1581,55 @@ dump_deadlist(dsl_deadlist_t *dl)
 static avl_tree_t idx_tree;
 static avl_tree_t domain_tree;
 static boolean_t fuid_table_loaded;
-static boolean_t sa_loaded;
-sa_attr_type_t *sa_attr_table;
+static objset_t *sa_os = NULL;
+static sa_attr_type_t *sa_attr_table = NULL;
+
+static int
+open_objset(const char *path, dmu_objset_type_t type, void *tag, objset_t **osp)
+{
+	int err;
+	uint64_t sa_attrs = 0;
+	uint64_t version = 0;
+
+	VERIFY3P(sa_os, ==, NULL);
+	err = dmu_objset_own(path, type, B_TRUE, tag, osp);
+	if (err != 0) {
+		(void) fprintf(stderr, "failed to own dataset '%s': %s\n", path,
+		    strerror(err));
+		return (err);
+	}
+
+	if (dmu_objset_type(*osp) == DMU_OST_ZFS) {
+		(void) zap_lookup(*osp, MASTER_NODE_OBJ, ZPL_VERSION_STR,
+		    8, 1, &version);
+		if (version >= ZPL_VERSION_SA) {
+			(void) zap_lookup(*osp, MASTER_NODE_OBJ, ZFS_SA_ATTRS,
+			    8, 1, &sa_attrs);
+		}
+		err = sa_setup(*osp, sa_attrs, zfs_attr_table, ZPL_END,
+		    &sa_attr_table);
+		if (err != 0) {
+			(void) fprintf(stderr, "sa_setup failed: %s\n",
+			    strerror(err));
+			dmu_objset_disown(*osp, tag);
+			*osp = NULL;
+		}
+	}
+	sa_os = *osp;
+
+	return (0);
+}
+
+static void
+close_objset(objset_t *os, void *tag)
+{
+	VERIFY3P(os, ==, sa_os);
+	if (os->os_sa != NULL)
+		sa_tear_down(os);
+	dmu_objset_disown(os, tag);
+	sa_attr_table = NULL;
+	sa_os = NULL;
+}
 
 static void
 fuid_table_destroy()
@@ -1649,25 +1701,7 @@ dump_znode(objset_t *os, uint64_t object
 	int idx = 0;
 	int error;
 
-	if (!sa_loaded) {
-		uint64_t sa_attrs = 0;
-		uint64_t version;
-
-		VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR,
-		    8, 1, &version) == 0);
-		if (version >= ZPL_VERSION_SA) {
-			VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS,
-			    8, 1, &sa_attrs) == 0);
-		}
-		if ((error = sa_setup(os, sa_attrs, zfs_attr_table,
-		    ZPL_END, &sa_attr_table)) != 0) {
-			(void) printf("sa_setup failed errno %d, can't "
-			    "display znode contents\n", error);
-			return;
-		}
-		sa_loaded = B_TRUE;
-	}
-
+	VERIFY3P(os, ==, sa_os);
 	if (sa_handle_get(os, object, NULL, SA_HDL_PRIVATE, &hdl)) {
 		(void) printf("Failed to get handle for SA znode\n");
 		return;
@@ -2135,6 +2169,108 @@ dump_label_uberblocks(vdev_label_t *lbl,
 	}
 }
 
+static char curpath[PATH_MAX];
+
+/*
+ * Iterate through the path components, recursively passing
+ * current one's obj and remaining path until we find the obj
+ * for the last one.
+ */
+static int
+dump_path_impl(objset_t *os, uint64_t obj, char *name)
+{
+	int err;
+	int header = 1;
+	uint64_t child_obj;
+	char *s;
+	dmu_buf_t *db;
+	dmu_object_info_t doi;
+
+	if ((s = strchr(name, '/')) != NULL)
+		*s = '\0';
+	err = zap_lookup(os, obj, name, 8, 1, &child_obj);
+
+	(void) strlcat(curpath, name, sizeof (curpath));
+
+	if (err != 0) {
+		(void) fprintf(stderr, "failed to lookup %s: %s\n",
+		    curpath, strerror(err));
+		return (err);
+	}
+
+	child_obj = ZFS_DIRENT_OBJ(child_obj);
+	err = sa_buf_hold(os, child_obj, FTAG, &db);
+	if (err != 0) {
+		(void) fprintf(stderr,
+		    "failed to get SA dbuf for obj %llu: %s\n",
+		    (u_longlong_t)child_obj, strerror(err));
+		return (EINVAL);
+	}
+	dmu_object_info_from_db(db, &doi);
+	sa_buf_rele(db, FTAG);
+
+	if (doi.doi_bonus_type != DMU_OT_SA &&
+	    doi.doi_bonus_type != DMU_OT_ZNODE) {
+		(void) fprintf(stderr, "invalid bonus type %d for obj %llu\n",
+		    doi.doi_bonus_type, (u_longlong_t)child_obj);
+		return (EINVAL);
+	}
+
+	if (dump_opt['v'] > 6) {
+		(void) printf("obj=%llu %s type=%d bonustype=%d\n",
+		    (u_longlong_t)child_obj, curpath, doi.doi_type,
+		    doi.doi_bonus_type);
+	}
+
+	(void) strlcat(curpath, "/", sizeof (curpath));
+
+	switch (doi.doi_type) {
+	case DMU_OT_DIRECTORY_CONTENTS:
+		if (s != NULL && *(s + 1) != '\0')
+			return (dump_path_impl(os, child_obj, s + 1));
+		/*FALLTHROUGH*/
+	case DMU_OT_PLAIN_FILE_CONTENTS:
+		dump_object(os, child_obj, dump_opt['v'], &header);
+		return (0);
+	default:
+		(void) fprintf(stderr, "object %llu has non-file/directory "
+		    "type %d\n", (u_longlong_t)obj, doi.doi_type);
+		break;
+	}
+
+	return (EINVAL);
+}
+
+/*
+ * Dump the blocks for the object specified by path inside the dataset.
+ */
+static int
+dump_path(char *ds, char *path)
+{
+	int err;
+	objset_t *os;
+	uint64_t root_obj;
+
+	err = open_objset(ds, DMU_OST_ZFS, FTAG, &os);
+	if (err != 0)
+		return (err);
+
+	err = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1, &root_obj);
+	if (err != 0) {
+		(void) fprintf(stderr, "can't lookup root znode: %s\n",
+		    strerror(err));
+		dmu_objset_disown(os, FTAG);
+		return (EINVAL);
+	}
+
+	(void) snprintf(curpath, sizeof (curpath), "dataset=%s path=/", ds);
+
+	err = dump_path_impl(os, root_obj, path);
+
+	close_objset(os, FTAG);
+	return (err);
+}
+
 static int
 dump_label(const char *dev)
 {
@@ -2234,11 +2370,9 @@ dump_one_dir(const char *dsname, void *a
 	int error;
 	objset_t *os;
 
-	error = dmu_objset_own(dsname, DMU_OST_ANY, B_TRUE, FTAG, &os);
-	if (error) {
-		(void) printf("Could not open %s, error %d\n", dsname, error);
+	error = open_objset(dsname, DMU_OST_ANY, FTAG, &os);
+	if (error != 0)
 		return (0);
-	}
 
 	for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
 		if (!dmu_objset_ds(os)->ds_feature_inuse[f])
@@ -2249,9 +2383,8 @@ dump_one_dir(const char *dsname, void *a
 	}
 
 	dump_dir(os);
-	dmu_objset_disown(os, FTAG);
+	close_objset(os, FTAG);
 	fuid_table_destroy();
-	sa_loaded = B_FALSE;
 	return (0);
 }
 
@@ -3592,35 +3725,37 @@ main(int argc, char **argv)
 		spa_config_path = spa_config_path_env;
 
 	while ((c = getopt(argc, argv,
-	    "bcdhilmMI:suCDRSAFLXx:evp:t:U:PGo:q")) != -1) {
+	    "AbcCdDeFGhiI:lLmMo:Op:PqRsSt:uU:vx:X")) != -1) {
 		switch (c) {
 		case 'b':
 		case 'c':
+		case 'C':
 		case 'd':
+		case 'D':
+		case 'G':
 		case 'h':
 		case 'i':
 		case 'l':
 		case 'm':
-		case 's':
-		case 'u':
-		case 'C':
-		case 'D':
 		case 'M':
+		case 'O':
 		case 'R':
+		case 's':
 		case 'S':
-		case 'G':
+		case 'u':
 			dump_opt[c]++;
 			dump_all = 0;
 			break;
 		case 'A':
+		case 'e':
 		case 'F':
 		case 'L':
-		case 'X':
-		case 'e':
 		case 'P':
 		case 'q':
+		case 'X':
 			dump_opt[c]++;
 			break;
+		/* NB: Sort single match options below. */
 		case 'I':
 			max_inflight = strtoull(optarg, NULL, 0);
 			if (max_inflight == 0) {
@@ -3630,6 +3765,11 @@ main(int argc, char **argv)
 				usage();
 			}
 			break;
+		case 'o':
+			error = set_global_var(optarg);
+			if (error != 0)
+				usage();
+			break;
 		case 'p':
 			if (searchdirs == NULL) {
 				searchdirs = umem_alloc(sizeof (char *),
@@ -3662,11 +3802,6 @@ main(int argc, char **argv)
 		case 'x':
 			vn_dumpdir = optarg;
 			break;
-		case 'o':
-			error = set_global_var(optarg);
-			if (error != 0)
-				usage();
-			break;
 		default:
 			usage();
 			break;
@@ -3704,7 +3839,7 @@ main(int argc, char **argv)
 		verbose = MAX(verbose, 1);
 
 	for (c = 0; c < 256; c++) {
-		if (dump_all && !strchr("elAFLRSXP", c))
+		if (dump_all && strchr("AeFlLOPRSX", c) == NULL)
 			dump_opt[c] = 1;
 		if (dump_opt[c])
 			dump_opt[c] += verbose;
@@ -3729,6 +3864,13 @@ main(int argc, char **argv)
 	if (dump_opt['l'])
 		return (dump_label(argv[0]));
 
+	if (dump_opt['O']) {
+		if (argc != 2)
+			usage();
+		dump_opt['v'] = verbose + 3;
+		return (dump_path(argv[0], argv[1]));
+	}
+
 	if (dump_opt['X'] || dump_opt['F'])
 		rewind = ZPOOL_DO_REWIND |
 		    (dump_opt['X'] ? ZPOOL_EXTREME_REWIND : 0);
@@ -3803,8 +3945,7 @@ main(int argc, char **argv)
 				}
 			}
 		} else {
-			error = dmu_objset_own(target, DMU_OST_ANY,
-			    B_TRUE, FTAG, &os);
+			error = open_objset(target, DMU_OST_ANY, FTAG, &os);
 		}
 	}
 	nvlist_free(policy);
@@ -3847,10 +3988,12 @@ main(int argc, char **argv)
 			zdb_read_block(argv[i], spa);
 	}
 
-	(os != NULL) ? dmu_objset_disown(os, FTAG) : spa_close(spa, FTAG);
+	if (os != NULL)
+		close_objset(os, FTAG);
+	else
+		spa_close(spa, FTAG);
 
 	fuid_table_destroy();
-	sa_loaded = B_FALSE;
 
 	dump_debug_buffer();
 

Modified: vendor/illumos/dist/man/man1m/zdb.1m
==============================================================================
--- vendor/illumos/dist/man/man1m/zdb.1m	Fri Apr 14 16:57:06 2017	(r316861)
+++ vendor/illumos/dist/man/man1m/zdb.1m	Fri Apr 14 16:58:41 2017	(r316862)
@@ -1,4 +1,3 @@
-'\" t
 .\"
 .\" This file and its contents are supplied under the terms of the
 .\" Common Development and Distribution License ("CDDL"), version 1.0.
@@ -12,545 +11,372 @@
 .\"
 .\" Copyright 2012, Richard Lowe.
 .\" Copyright (c) 2012, 2016 by Delphix. All rights reserved.
-.\" Copyright 2016 Nexenta Systems, Inc.
+.\" Copyright 2017 Nexenta Systems, Inc.
 .\"
-.TH "ZDB" "1M" "April 9, 2016"
-
-.SH "NAME"
-\fBzdb\fR - Display zpool debugging and consistency information
-
-.SH "SYNOPSIS"
-\fBzdb\fR [-CmdibcsDvhLMXFPAG] [-e [-p \fIpath\fR...]] [-t \fItxg\fR]
-    [-U \fIcache\fR] [-I \fIinflight I/Os\fR] [-x \fIdumpdir\fR]
-    [-o \fIvar\fR=\fIvalue\fR] ... [\fIpoolname\fR [\fIobject\fR ...]]
-
-.P
-\fBzdb\fR [-divPA] [-e [-p \fIpath\fR...]] [-U \fIcache\fR]
-    \fIdataset\fR [\fIobject\fR ...]
-
-.P
-\fBzdb\fR -m [-MLXFPA] [-t \fItxg\fR] [-e [-p \fIpath\fR...]] [-U \fIcache\fR]
-    \fIpoolname\fR [\fIvdev\fR [\fImetaslab\fR ...]]
-
-.P
-\fBzdb\fR -R [-A] [-e [-p \fIpath\fR...]] [-U \fIcache\fR] \fIpoolname\fR
-    \fIvdev\fR:\fIoffset\fR:\fIsize\fR[:\fIflags\fR]
-
-.P
-\fBzdb\fR -S [-AP] [-e [-p \fIpath\fR...]] [-U \fIcache\fR] \fIpoolname\fR
-
-.P
-\fBzdb\fR -l [-Aqu] \fIdevice\fR
-
-.P
-\fBzdb\fR -C [-A] [-U \fIcache\fR]
-
-.SH "DESCRIPTION"
-The \fBzdb\fR utility displays information about a ZFS pool useful for
-debugging and performs some amount of consistency checking. It is a not a
-general purpose tool and options (and facilities) may change. This is neither
-a fsck(1M) nor an fsdb(1M) utility.
-
-.P
+.Dd January 14, 2017
+.Dt ZDB 1M
+.Os
+.Sh NAME
+.Nm zdb
+.Nd display zpool debugging and consistency information
+.Sh SYNOPSIS
+.Nm
+.Op Fl AbcdDFGhiLMPsvX
+.Op Fl e Op Fl p Ar path ...
+.Op Fl I Ar inflight I/Os
+.Oo Fl o Ar var Ns = Ns Ar value Oc Ns ...
+.Op Fl t Ar txg
+.Op Fl U Ar cache
+.Op Fl x Ar dumpdir
+.Op Ar poolname Op Ar object ...
+.Nm
+.Op Fl AdiPv
+.Op Fl e Op Fl p Ar path ...
+.Op Fl U Ar cache
+.Ar dataset Op Ar object ...
+.Nm
+.Fl C
+.Op Fl A
+.Op Fl U Ar cache
+.Nm
+.Fl l
+.Op Fl Aqu
+.Ar device
+.Nm
+.Fl m
+.Op Fl AFLPX
+.Op Fl t Ar txg
+.Op Fl e Op Fl p Ar path ...
+.Op Fl U Ar cache
+.Ar poolname Op Ar vdev Op Ar metaslab ...
+.Nm
+.Fl O
+.Ar dataset path
+.Nm
+.Fl R
+.Op Fl A
+.Op Fl e Op Fl p Ar path ...
+.Op Fl U Ar cache
+.Ar poolname vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op : Ns Ar flags
+.Nm
+.Fl S
+.Op Fl AP
+.Op Fl e Op Fl p Ar path ...
+.Op Fl U Ar cache
+.Ar poolname
+.Sh DESCRIPTION
+The
+.Nm
+utility displays information about a ZFS pool useful for debugging and performs
+some amount of consistency checking.
+It is a not a general purpose tool and options
+.Pq and facilities
+may change.
+This is neither a
+.Xr fsck 1M
+nor an
+.Xr fsdb 1M
+utility.
+.Pp
 The output of this command in general reflects the on-disk structure of a ZFS
-pool, and is inherently unstable. The precise output of most invocations is
-not documented, a knowledge of ZFS internals is assumed.
-
-.P
-If the \fIdataset\fR argument does not contain any \fB/\fR or \fB@\fR
-characters, it is interpreted as a pool name.  The root dataset can be
-specified as \fIpool\fB/\fR (pool name followed by a slash).
-
-.P
+pool, and is inherently unstable.
+The precise output of most invocations is not documented, a knowledge of ZFS
+internals is assumed.
+.Pp
+If the
+.Ar dataset
+argument does not contain any
+.Qq Sy /
+or
+.Qq Sy @
+characters, it is interpreted as a pool name.
+The root dataset can be specified as
+.Ar pool Ns /
+.Pq pool name followed by a slash .
+.Pp
 When operating on an imported and active pool it is possible, though unlikely,
 that zdb may interpret inconsistent pool data and behave erratically.
-
-.SH "OPTIONS"
+.Sh OPTIONS
 Display options:
-
-.sp
-.ne 2
-.na
-\fB-b\fR
-.ad
-.sp .6
-.RS 4n
-Display statistics regarding the number, size (logical, physical and
-allocated) and deduplication of blocks.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-c\fR
-.ad
-.sp .6
-.RS 4n
+.Bl -tag -width Ds
+.It Fl b
+Display statistics regarding the number, size
+.Pq logical, physical and allocated
+and deduplication of blocks.
+.It Fl c
 Verify the checksum of all metadata blocks while printing block statistics
-(see \fB-b\fR).
-.sp
+.Po see
+.Fl b
+.Pc .
+.Pp
 If specified multiple times, verify the checksums of all blocks.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-C\fR
-.ad
-.sp .6
-.RS 4n
-Display information about the configuration. If specified with no other
-options, instead display information about the cache file
-(\fB/etc/zfs/zpool.cache\fR). To specify the cache file to display, see
-\fB-U\fR.
-.P
-If specified multiple times, and a pool name is also specified display both
-the cached configuration and the on-disk configuration.  If specified multiple
-times with \fB-e\fR also display the configuration that would be used were the
-pool to be imported.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-d\fR
-.ad
-.sp .6
-.RS 4n
-Display information about datasets. Specified once, displays basic dataset
-information: ID, create transaction, size, and object count.
-.sp
+.It Fl C
+Display information about the configuration.
+If specified with no other options, instead display information about the cache
+file
+.Pq Pa /etc/zfs/zpool.cache .
+To specify the cache file to display, see
+.Fl U .
+.Pp
+If specified multiple times, and a pool name is also specified display both the
+cached configuration and the on-disk configuration.
+If specified multiple times with
+.Fl e
+also display the configuration that would be used were the pool to be imported.
+.It Fl d
+Display information about datasets.
+Specified once, displays basic dataset information: ID, create transaction,
+size, and object count.
+.Pp
 If specified multiple times provides greater and greater verbosity.
-.sp
-If object IDs are specified, display information about those specific objects only.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-D\fR
-.ad
-.sp .6
-.RS 4n
-Display deduplication statistics, including the deduplication ratio (dedup),
-compression ratio (compress), inflation due to the zfs copies property
-(copies), and an overall effective ratio (dedup * compress / copies).
-.sp
-If specified twice, display a histogram of deduplication statistics, showing
-the allocated (physically present on disk) and referenced (logically
-referenced in the pool) block counts and sizes by reference count.
-.sp
-If specified a third time, display the statistics independently for each deduplication table.
-.sp
-If specified a fourth time, dump the contents of the deduplication tables describing duplicate blocks.
-.sp
-If specified a fifth time, also dump the contents of the deduplication tables describing unique blocks.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-h\fR
-.ad
-.sp .6
-.RS 4n
-Display pool history similar to \fBzpool history\fR, but include internal
-changes, transaction, and dataset information.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-i\fR
-.ad
-.sp .6
-.RS 4n
-Display information about intent log (ZIL) entries relating to each
-dataset. If specified multiple times, display counts of each intent log
-transaction type.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-l\fR \fIdevice\fR
-.ad
-.sp .6
-.RS 4n
-Read the vdev labels from the specified device. \fBzdb -l\fR will return 0 if
-valid label was found, 1 if error occured, and 2 if no valid labels were found.
-.P
-If the \fB-u\fR option is also specified, also display the uberblocks on this
-device.
-.P
-If the \fB-q\fR option is also specified, don't print the labels.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-L\fR
-.ad
-.sp .6
-.RS 4n
-Disable leak tracing and the loading of space maps.  By default, \fBzdb\fR
+.Pp
+If object IDs are specified, display information about those specific objects
+only.
+.It Fl D
+Display deduplication statistics, including the deduplication ratio
+.Pq Sy dedup ,
+compression ratio
+.Pq Sy compress ,
+inflation due to the zfs copies property
+.Pq Sy copies ,
+and an overall effective ratio
+.Pq Sy dedup No * Sy compress No / Sy copies .
+.It Fl DD
+Display a histogram of deduplication statistics, showing the allocated
+.Pq physically present on disk
+and referenced
+.Pq logically referenced in the pool
+block counts and sizes by reference count.
+.It Fl DDD
+Display the statistics independently for each deduplication table.
+.It Fl DDDD
+Dump the contents of the deduplication tables describing duplicate blocks.
+.It Fl DDDDD
+Also dump the contents of the deduplication tables describing unique blocks.
+.It Fl h
+Display pool history similar to
+.Nm zpool Cm history ,
+but include internal changes, transaction, and dataset information.
+.It Fl i
+Display information about intent log
+.Pq ZIL
+entries relating to each dataset.
+If specified multiple times, display counts of each intent log transaction type.
+.It Fl l Ar device
+Read the vdev labels from the specified device.
+.Nm Fl l
+will return 0 if valid label was found, 1 if error occurred, and 2 if no valid
+labels were found.
+.Pp
+If the
+.Fl q
+option is also specified, don't print the labels.
+.Pp
+If the
+.Fl u
+option is also specified, also display the uberblocks on this device.
+.It Fl L
+Disable leak tracing and the loading of space maps.
+By default,
+.Nm
 verifies that all non-free blocks are referenced, which can be very expensive.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-m\fR
-.ad
-.sp .6
-.RS 4n
+.It Fl m
 Display the offset, spacemap, and free space of each metaslab.
-When specified twice, also display information about the on-disk free
-space histogram associated with each metaslab. When specified three time,
-display the maximum contiguous free space, the in-core free space histogram,
-and the percentage of free space in each space map.  When specified
-four times display every spacemap record.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-M\fR
-.ad
-.sp .6
-.RS 4n
+.It Fl mm
+Also display information about the on-disk free space histogram associated with
+each metaslab.
+.It Fl mmm
+Display the maximum contiguous free space, the in-core free space histogram, and
+the percentage of free space in each space map.
+.It Fl mmmm
+Display every spacemap record.
+.It Fl M
 Display the offset, spacemap, and free space of each metaslab.
-When specified twice, also display information about the maximum contiguous
-free space and the percentage of free space in each space map.  When specified
-three times display every spacemap record.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-R\fR \fIpoolname\fR \fIvdev\fR:\fIoffset\fR:\fIsize\fR[:\fIflags\fR]
-.ad
-.sp .6
-.RS 4n
-Read and display a block from the specified device. By default the block is
-displayed as a hex dump, but see the description of the \'r\' flag, below.
-.sp
-The block is specified in terms of a colon-separated tuple \fIvdev\fR (an
-integer vdev identifier) \fIoffset\fR (the offset within the vdev) \fIsize\fR
-(the size of the block to read) and, optionally, \fIflags\fR (a set of flags,
-described below).
-
-.sp
-.ne 2
-.na
-\fBb\fR \fIoffset\fR
-.ad
-.sp .6
-.RS 4n
+.It Fl MM
+Also display information about the maximum contiguous free space and the
+percentage of free space in each space map.
+.It Fl MMM
+Display every spacemap record.
+.It Fl O Ar dataset path
+Look up the specified
+.Ar path
+inside of the
+.Ar dataset
+and display its metadata and indirect blocks.
+Specified
+.Ar path
+must be relative to the root of
+.Ar dataset .
+This option can be combined with
+.Fl v
+for increasing verbosity.
+.It Fl R Ar poolname vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op : Ns Ar flags
+Read and display a block from the specified device.
+By default the block is displayed as a hex dump, but see the description of the
+.Sy r
+flag, below.
+.Pp
+The block is specified in terms of a colon-separated tuple
+.Ar vdev
+.Pq an integer vdev identifier
+.Ar offset
+.Pq the offset within the vdev
+.Ar size
+.Pq the size of the block to read
+and, optionally,
+.Ar flags
+.Pq a set of flags, described below .
+.Pp
+.Bl -tag -compact -width "b offset"
+.It Sy b Ar offset
 Print block pointer
-.RE
-
-.sp
-.ne 2
-.na
-\fBd\fR
-.ad
-.sp .6
-.RS 4n
+.It Sy d
 Decompress the block
-.RE
-
-.sp
-.ne 2
-.na
-\fBe\fR
-.ad
-.sp .6
-.RS 4n
+.It Sy e
 Byte swap the block
-.RE
-
-.sp
-.ne 2
-.na
-\fBg\fR
-.ad
-.sp .6
-.RS 4n
+.It Sy g
 Dump gang block header
-.RE
-
-.sp
-.ne 2
-.na
-\fBi\fR
-.ad
-.sp .6
-.RS 4n
+.It Sy i
 Dump indirect block
-.RE
-
-.sp
-.ne 2
-.na
-\fBr\fR
-.ad
-.sp .6
-.RS 4n
+.It Sy r
 Dump raw uninterpreted block data
-.RE
-.RE
-
-.sp
-.ne 2
-.na
-\fB-s\fR
-.ad
-.sp .6
-.RS 4n
-Report statistics on \fBzdb\fR\'s I/O. Display operation counts, bandwidth,
-and error counts of I/O to the pool from \fBzdb\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB-S\fR
-.ad
-.sp .6
-.RS 4n
+.El
+.It Fl s
+Report statistics on
+.Nm zdb
+I/O.
+Display operation counts, bandwidth, and error counts of I/O to the pool from

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704141658.v3EGwfxU030989>