From a44e7faa6c63998a4c058901a5c587706abe56ab Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 13 Apr 2017 09:40:56 -0700 Subject: [PATCH] OpenZFS 6410 - teach zdb to perform object lookups by path Authored by: Yuri Pankov Reviewed by: Pavel Zakharov Reviewed by: Matthew Ahrens Reviewed by: Will Andrews Approved by: Dan McDonald Ported-by: Brian Behlendorf Porting Notes: - Replaced zdb.8 with upstream mdoc zdb.1m version. Updated to include Linux specific features: -V verbatium imports and improved label printing (-u, and -l). - Minor changes to `zdb -h` output to honor 80 character limit. OpenZFS-issue: https://www.illumos.org/issues/6410 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/ed61ec1 Closes #6006 --- cmd/zdb/zdb.c | 325 +++++++++++++------ man/man8/zdb.8 | 837 +++++++++++++++++++------------------------------ 2 files changed, 562 insertions(+), 600 deletions(-) diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index b58b709e79..13d0bcf0e5 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -22,8 +22,10 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016 by Delphix. All rights reserved. - * Copyright (c) 2015, 2017, Intel Corporation. + * Copyright (c) 2014 Integros [integros.com] * Copyright 2016 Nexenta Systems, Inc. + * Copyright (c) 2017 Lawrence Livermore National Security, LLC. + * Copyright (c) 2015, 2017, Intel Corporation. */ #include @@ -122,19 +124,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 [-AbcdDFGhiLMPsvVX] [-e [-p ...]] " + "[-I ]\n" + "\t\t[-o =]... [-t ] [-U ] [-x ]\n" + "\t\t[ [ ...]]\n" + "\t%s [-AdiPv] [-e [-p ...]] [-U ] " + "[ ...]\n" + "\t%s -C [-A] [-U ]\n" + "\t%s -l [-Aqu] \n" + "\t%s -m [-AFLPX] [-e [-p ...]] [-t ] [-U ]\n" + "\t\t [ [ ...]]\n" + "\t%s -O \n" + "\t%s -R [-A] [-e [-p ...]] [-U ]\n" + "\t\t ::[:]\n" + "\t%s -S [-AP] [-e [-p ...]] [-U ] \n\n", + cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, + cmdname); (void) fprintf(stderr, " Dataset name must include at least one " "separator character '/' or '@'\n"); @@ -143,52 +148,56 @@ 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 -- 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 -- use one or more with " - "-e to specify path to vdev dir\n"); - (void) fprintf(stderr, " -x -- " - "dump all read blocks into specified directory\n"); - (void) fprintf(stderr, " -P print numbers in parsable form\n"); - (void) fprintf(stderr, " -t -- highest txg to use when " - "searching for uberblocks\n"); - (void) fprintf(stderr, " -I -- " - "specify the maximum number of " - "checksumming I/Os [default is 200]\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 -- " + "specify the maximum number of\n " + "checksumming I/Os [default is 200]\n"); (void) fprintf(stderr, " -o = set global " - "variable to an unsigned 32-bit integer value\n"); + "variable to an unsigned 32-bit integer\n"); + (void) fprintf(stderr, " -p -- 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 -- highest txg to use when " + "searching for uberblocks\n"); (void) fprintf(stderr, " -u uberblock\n"); + (void) fprintf(stderr, " -U -- use alternate " + "cachefile\n"); + (void) fprintf(stderr, " -x -- " + "dump all read blocks into specified directory\n"); + (void) fprintf(stderr, " -X attempt extreme rewind (does not " + "work with dataset)\n"); + (void) fprintf(stderr, " -V verbatim import (as if it had been " + "loaded at boot)\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"); @@ -1607,8 +1616,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(void) @@ -1735,25 +1791,7 @@ dump_znode(objset_t *os, uint64_t object, void *data, size_t size) 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; @@ -2499,6 +2537,108 @@ dump_label_uberblocks(label_t *label, uint64_t ashift, int label_num) } } +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) { @@ -2677,11 +2817,9 @@ dump_one_dir(const char *dsname, void *arg) objset_t *os; spa_feature_t f; - 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 (f = 0; f < SPA_FEATURES; f++) { if (!dmu_objset_ds(os)->ds_feature_inuse[f]) @@ -2692,9 +2830,8 @@ dump_one_dir(const char *dsname, void *arg) } dump_dir(os); - dmu_objset_disown(os, FTAG); + close_objset(os, FTAG); fuid_table_destroy(); - sa_loaded = B_FALSE; return (0); } @@ -4077,38 +4214,37 @@ main(int argc, char **argv) spa_config_path = spa_config_path_env; while ((c = getopt(argc, argv, - "bcdhilmMI:suCDRSAFLXx:evp:t:U:PVGoq")) != -1) { + "AbcCdDeFGhiI:lLmMo:Op:PqRsSt:uU:vVx: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; - case 'V': - flags |= ZFS_IMPORT_VERBATIM; - break; + /* NB: Sort single match options below. */ case 'I': max_inflight = strtoull(optarg, NULL, 0); if (max_inflight == 0) { @@ -4118,6 +4254,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 *), @@ -4147,14 +4288,12 @@ main(int argc, char **argv) case 'v': verbose++; break; + case 'V': + flags |= ZFS_IMPORT_VERBATIM; + break; case 'x': vn_dumpdir = optarg; break; - case 'o': - error = set_global_var(optarg); - if (error != 0) - usage(); - break; default: usage(); break; @@ -4196,7 +4335,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; @@ -4221,6 +4360,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); @@ -4285,8 +4431,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); @@ -4329,10 +4474,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(); diff --git a/man/man8/zdb.8 b/man/man8/zdb.8 index 667f6b1714..83e7fba145 100644 --- a/man/man8/zdb.8 +++ b/man/man8/zdb.8 @@ -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,556 +11,378 @@ .\" .\" Copyright 2012, Richard Lowe. .\" Copyright (c) 2012, 2016 by Delphix. All rights reserved. -.\" Copyright 2016 Nexenta Systems, Inc. +.\" Copyright 2017 Nexenta Systems, Inc. +.\" Copyright (c) 2017 Lawrence Livermore National Security, LLC. +.\" Copyright (c) 2017 Intel Corporation. .\" -.TH "ZDB" "8" "April 9, 2016" "" "" - -.SH "NAME" -\fBzdb\fR - Display zpool debugging and consistency information - -.SH "SYNOPSIS" -\fBzdb\fR [-CumdibcsDvhLMXFPAG] [-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(8) nor an fsdb(8) utility. - -.P +.Dd April 11, 2017 +.Dt ZDB 8 SMM +.Os Linux +.Sh NAME +.Nm zdb +.Nd display zpool debugging and consistency information +.Sh SYNOPSIS +.Nm +.Op Fl AbcdDFGhiLMPsvVX +.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 AFLPVX +.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 and dump the unique -configuration nvlist(s). \fBzdb -l\fR will return 1 if an error occured, 2 if -no configuration nvlist could be unpacked (errors or not), and 0 otherwise. -Specify multiple times to increase verbosity. -.P -If the \fB-u\fR option is also specified, also display the uberblocks on this -device. Specify multiple times to increase verbosity. -.P -If the \fB-q\fR option is also specified, don't dump the configurations or the -uberblocks. -.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. Each unique configuration is displayed only once. +.It Fl ll Ar device +In addition display label space usage stats. +.It Fl lll Ar device +Display every configuration, unique or not. +.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. Specify +multiple times to increase verbosity. +.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 +.Nm . +.It Fl S Simulate the effects of deduplication, constructing a DDT and then display -that DDT as with \fB-DD\fR. -.RE - -.sp -.ne 2 -.na -\fB-u\fR -.ad -.sp .6 -.RS 4n +that DDT as with +.Fl DD . +.It Fl u Display the current uberblock. -.RE - -.P +.El +.Pp Other options: - -.sp -.ne 2 -.na -\fB-A\fR -.ad -.sp .6 -.RS 4n +.Bl -tag -width Ds +.It Fl A Do not abort should any assertion fail. -.RE - -.sp -.ne 2 -.na -\fB-AA\fR -.ad -.sp .6 -.RS 4n +.It Fl AA Enable panic recovery, certain errors which would otherwise be fatal are demoted to warnings. -.RE - -.sp -.ne 2 -.na -\fB-AAA\fR -.ad -.sp .6 -.RS 4n +.It Fl AAA Do not abort if asserts fail and also enable panic recovery. -.RE - -.sp -.ne 2 -.na -\fB-e\fR [-p \fIpath\fR]... -.ad -.sp .6 -.RS 4n -Operate on an exported pool, not present in \fB/etc/zfs/zpool.cache\fR. The -\fB-p\fR flag specifies the path under which devices are to be searched. -.RE - -.sp -.ne 2 -.na -\fB-x\fR \fIdumpdir\fR -.ad -.sp .6 -.RS 4n +.It Fl e Op Fl p Ar path ... +Operate on an exported pool, not present in +.Pa /etc/zfs/zpool.cache . +The +.Fl p +flag specifies the path under which devices are to be searched. +.It Fl x Ar dumpdir All blocks accessed will be copied to files in the specified directory. The blocks will be placed in sparse files whose name is the same as -that of the file or device read. zdb can be then run on the generated files. -Note that the \fB-bbc\fR flags are sufficient to access (and thus copy) +that of the file or device read. +.Nm +can be then run on the generated files. +Note that the +.Fl bbc +flags are sufficient to access +.Pq and thus copy all metadata on the pool. -.RE - -.sp -.ne 2 -.na -\fB-F\fR -.ad -.sp .6 -.RS 4n +.It Fl F Attempt to make an unreadable pool readable by trying progressively older transactions. -.RE - -.sp -.ne 2 -.na -\fB-G\fR -.ad -.sp .6 -.RS 4n -Dump the contents of the zfs_dbgmsg buffer before exiting zdb. zfs_dbgmsg is -a buffer used by ZFS to dump advanced debug information. -.RE - -.sp -.ne 2 -.na -\fB-I \fIinflight I/Os\fR \fR -.ad -.sp .6 -.RS 4n -Limit the number of outstanding checksum I/Os to the specified value. The -default value is 200. This option affects the performance of the \fB-c\fR +.It Fl G +Dump the contents of the zfs_dbgmsg buffer before exiting +.Nm . +zfs_dbgmsg is a buffer used by ZFS to dump advanced debug information. +.It Fl I Ar inflight I/Os +Limit the number of outstanding checksum I/Os to the specified value. +The default value is 200. +This option affects the performance of the +.Fl c option. -.RE - -.sp -.ne 2 -.na -\fB-o \fIvar\fR=\fIvalue\fR ... \fR -.ad -.sp .6 -.RS 4n -Set the given global libzpool variable to the provided value. The value must -be an unsigned 32-bit integer. Currently only little-endian systems are -supported to avoid accidentally setting the high 32 bits of 64-bit variables. -.RE - -.sp -.ne 2 -.na -\fB-P\fR -.ad -.sp .6 -.RS 4n +.It Fl o Ar var Ns = Ns Ar value ... +Set the given global libzpool variable to the provided value. +The value must be an unsigned 32-bit integer. +Currently only little-endian systems are supported to avoid accidentally setting +the high 32 bits of 64-bit variables. +.It Fl P Print numbers in an unscaled form more amenable to parsing, eg. 1000000 rather than 1M. -.RE - -.sp -.ne 2 -.na -\fB-t\fR \fItransaction\fR -.ad -.sp .6 -.RS 4n -Specify the highest transaction to use when searching for uberblocks. See also -the \fB-u\fR and \fB-l\fR options for a means to see the available uberblocks -and their associated transaction numbers. -.RE - -.sp -.ne 2 -.na -\fB-U\fR \fIcachefile\fR -.ad -.sp .6 -.RS 4n -Use a cache file other than \fB/etc/zfs/zpool.cache\fR. -.RE - -.sp -.ne 2 -.na -\fB-v\fR -.ad -.sp .6 -.RS 4n -Enable verbosity. Specify multiple times for increased verbosity. -.RE - -.sp -.ne 2 -.na -\fB-X\fR -.ad -.sp .6 -.RS 4n -Attempt \'extreme\' transaction rewind, that is attempt the same recovery as -\fB-F\fR but read transactions otherwise deemed too old. -.RE - -.sp -.ne 2 -.na -\fB-V\fR -.ad -.sp .6 -.RS 4n -Attempt a verbatim import. This mimics the behavior of the kernel when loading -a pool from a cachefile. -.RE - -.P +.It Fl t Ar transaction +Specify the highest transaction to use when searching for uberblocks. +See also the +.Fl u +and +.Fl l +options for a means to see the available uberblocks and their associated +transaction numbers. +.It Fl U Ar cachefile +Use a cache file other than +.Pa /etc/zfs/zpool.cache . +.It Fl v +Enable verbosity. +Specify multiple times for increased verbosity. +.It Fl V +Attempt a verbatim import. This mimics the behavior of the kernel when +loading a pool from a cachefile. +.It Fl X +Attempt +.Qq extreme +transaction rewind, that is attempt the same recovery as +.Fl F +but read transactions otherwise deemed too old. +.El +.Pp Specifying a display option more than once enables verbosity for only that option, with more occurrences enabling more verbosity. -.P +.Pp If no options are specified, all information about the named pool will be displayed at default verbosity. - -.SH "EXAMPLES" -.LP -\fBExample 1 \fRDisplay the configuration of imported pool 'rpool' -.sp -.in +2 -.nf +.Sh EXAMPLES +.Bl -tag -width Ds +.It Xo +.Sy Example 1 +Display the configuration of imported pool +.Pa rpool +.Xc +.Bd -literal # zdb -C rpool MOS Configuration: version: 28 name: 'rpool' ... -.fi -.in -2 -.sp - -.LP -\fBExample 2 \fRDisplay basic dataset information about 'rpool' -.sp -.in +2 -.nf +.Ed +.It Xo +.Sy Example 2 +Display basic dataset information about +.Pa rpool +.Xc +.Bd -literal # zdb -d rpool Dataset mos [META], ID 0, cr_txg 4, 26.9M, 1051 objects Dataset rpool/swap [ZVOL], ID 59, cr_txg 356, 486M, 2 objects ... -.fi -.in -2 -.sp - -.LP -\fBExample 3 \fRDisplay basic information about object 0 -in 'rpool/export/home' -.sp -.in +2 -.nf +.Ed +.It Xo +.Sy Example 3 +Display basic information about object 0 in +.Pa rpool/export/home +.Xc +.Bd -literal # zdb -d rpool/export/home 0 Dataset rpool/export/home [ZPL], ID 137, cr_txg 1546, 32K, 8 objects Object lvl iblk dblk dsize lsize %full type 0 7 16K 16K 15.0K 16K 25.00 DMU dnode -.fi -.in -2 -.sp - -.LP -\fBExample 4 \fRDisplay the predicted effect of enabling deduplication on 'rpool' -.sp -.in +2 -.nf +.Ed +.It Xo +.Sy Example 4 +Display the predicted effect of enabling deduplication on +.Pa rpool +.Xc +.Bd -literal # zdb -S rpool Simulated DDT histogram: @@ -573,14 +394,8 @@ refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE 2 35.0K 1.33G 699M 699M 74.7K 2.79G 1.45G 1.45G ... dedup = 1.11, compress = 1.80, copies = 1.00, dedup * compress / copies = 2.00 -.fi -.in -2 -.sp - -.SH "ENVIRONMENT VARIABLES" -.TP -.B "SPA_CONFIG_PATH" -Override the default \fBspa_config_path\fR (\fI/etc/zfs/zpool.cache\fR) setting. If \fB-U\fR flag is specified it will override this environment variable settings once again. - -.SH "SEE ALSO" -zfs(8), zpool(8) +.Ed +.El +.Sh SEE ALSO +.Xr zfs 8 , +.Xr zpool 8