zdb.c revision d41e76436a9498c7a8ab1f783125ac49f517eaf9
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/zfs_context.h>
#include <sys/spa_impl.h>
#include <sys/zfs_znode.h>
#include <sys/vdev_impl.h>
#include <sys/metaslab_impl.h>
#include <sys/dmu_objset.h>
#include <sys/dsl_dataset.h>
#include <sys/dsl_pool.h>
#include <sys/zil_impl.h>
#include <sys/resource.h>
#include <sys/dmu_traverse.h>
#include <sys/zio_checksum.h>
#include <sys/zio_compress.h>
#include <sys/zfs_fuid.h>
#include <libzfs.h>
const char cmdname[] = "zdb";
extern void dump_intent_log(zilog_t *);
int zopt_objects = 0;
int zdb_advance = ADVANCE_PRE;
/*
* These libumem hooks provide a reasonable set of defaults for the allocator's
* debugging facilities.
*/
const char *
{
return ("default,verbose"); /* $UMEM_DEBUG setting */
}
const char *
_umem_logging_init(void)
{
return ("fail,contents"); /* $UMEM_LOGGING setting */
}
static void
usage(void)
{
"Usage: %s [-udibcsvL] [-U cachefile_path] [-O order] "
"[-B os:obj:level:blkid] [-S user:cksumalg] "
"dataset [object...]\n"
" %s -C [pool]\n"
" %s -l dev\n"
" %s -R vdev:offset:size:flags\n"
" %s [-p path_to_vdev_dir]\n"
" %s -e pool | GUID | devid ...\n",
"dump blkptr signatures\n");
"visitation order\n");
"cachefile\n");
"simulate bad block\n");
"device\n");
"has altroot\n");
"to make only that option verbose\n");
exit(1);
}
static void
{
exit(1);
}
static void
{
switch (nvpair_type(elem)) {
case DATA_TYPE_STRING:
{
char *value;
}
break;
case DATA_TYPE_UINT64:
{
}
break;
case DATA_TYPE_NVLIST:
{
nvpair_name(elem));
}
break;
case DATA_TYPE_NVLIST_ARRAY:
{
&count) == 0);
for (c = 0; c < count; c++) {
nvpair_name(elem), c);
}
}
break;
default:
(void) printf("bad config type %d for %s\n",
}
}
}
/* ARGSUSED */
static void
{
}
const char dump_zap_stars[] = "****************************************";
static void
{
int i;
int maxidx = 0;
for (i = 0; i < ZAP_HISTOGRAM_SIZE; i++) {
maxidx = i;
minidx = i;
}
if (max < dump_zap_width)
}
static void
{
int error;
if (error)
return;
if (zs.zs_ptrtbl_len == 0) {
(void) printf("\tmicrozap: %llu bytes, %llu entries\n",
return;
}
(void) printf("\tFat ZAP stats:\n");
(void) printf("\t\tPointer table:\n");
(void) printf("\t\t\t%llu elements\n",
(void) printf("\t\t\tzt_blk: %llu\n",
(void) printf("\t\t\tzt_numblks: %llu\n",
(void) printf("\t\t\tzt_shift: %llu\n",
(void) printf("\t\t\tzt_blks_copied: %llu\n",
(void) printf("\t\t\tzt_nextblk: %llu\n",
(void) printf("\t\tZAP entries: %llu\n",
(void) printf("\t\tLeaf blocks: %llu\n",
(void) printf("\t\tTotal blocks: %llu\n",
(void) printf("\t\tzap_block_type: 0x%llx\n",
(void) printf("\t\tzap_magic: 0x%llx\n",
(void) printf("\t\tzap_salt: 0x%llx\n",
(void) printf("\t\tLeafs with 2^n pointers:\n");
(void) printf("\t\tBlocks with n*5 entries:\n");
(void) printf("\t\tBlocks n/10 full:\n");
(void) printf("\t\tEntries with n chunks:\n");
(void) printf("\t\tBuckets with n entries:\n");
}
/*ARGSUSED*/
static void
{
}
/*ARGSUSED*/
void
{
}
/*ARGSUSED*/
static void
{
}
/*ARGSUSED*/
static void
{
void *prop;
int i;
(void) printf("\n");
zap_cursor_advance(&zc)) {
if (attr.za_num_integers == 0) {
(void) printf("\n");
continue;
}
} else {
for (i = 0; i < attr.za_num_integers; i++) {
switch (attr.za_integer_length) {
case 2:
(void) printf("%u ",
break;
case 4:
(void) printf("%u ",
break;
case 8:
(void) printf("%lld ",
break;
}
}
}
(void) printf("\n");
}
}
/*ARGSUSED*/
static void
{
const char *typenames[] = {
/* 0 */ "not specified",
/* 1 */ "FIFO",
/* 2 */ "Character Device",
/* 3 */ "3 (invalid)",
/* 4 */ "Directory",
/* 5 */ "5 (invalid)",
/* 6 */ "Block Device",
/* 7 */ "7 (invalid)",
/* 8 */ "Regular File",
/* 9 */ "9 (invalid)",
/* 10 */ "Symbolic Link",
/* 11 */ "11 (invalid)",
/* 12 */ "Socket",
/* 13 */ "Door",
/* 14 */ "Event Port",
/* 15 */ "15 (invalid)",
};
(void) printf("\n");
zap_cursor_advance(&zc)) {
(void) printf("\t\t%s = %lld (type: %s)\n",
}
}
static void
{
"INVALID", "INVALID", "INVALID", "INVALID" };
if (smo->smo_object == 0)
return;
/*
* Print out the freelist entries in both encoded and decoded form.
*/
alloc = 0;
if (SM_DEBUG_DECODE(entry)) {
(void) printf("\t\t[%4llu] %s: txg %llu, pass %llu\n",
} else {
(void) printf("\t\t[%4llu] %c range:"
" %08llx-%08llx size: %06llx\n",
mapshift)),
else
}
}
(void) printf("space_map_object alloc (%llu) INCONSISTENT "
"with space map summary (%llu)\n",
}
}
static void
{
char freebuf[5];
(void) printf("\t%10llx %10llu %5s\n",
freebuf);
return;
}
(void) printf(
"\tvdev %llu offset %08llx spacemap %4llu free %5s\n",
}
static void
{
int c, m;
(void) printf("\nMetaslabs:\n");
for (c = 0; c < rvd->vdev_children; c++) {
(void) printf("\n vdev %llu = %s\n\n",
(void) printf("\t%10s %10s %5s\n",
"offset", "spacemap", "free");
(void) printf("\t%10s %10s %5s\n",
"------", "--------", "----");
}
for (m = 0; m < vd->vdev_ms_count; m++)
(void) printf("\n");
}
}
static void
{
int c;
if (indent == 0)
(void) printf("\nDirty time logs:\n\n");
/*
* Everything in this DTL must appear in all parent DTL unions.
*/
(void) printf("\t%*soutage [%llu,%llu] length %llu\n",
indent, "",
}
(void) printf("\n");
&vd->vdev_dtl_map);
(void) printf("\n");
}
for (c = 0; c < vd->vdev_children; c++)
}
/*ARGSUSED*/
static void
{
}
static uint64_t
{
if (level < 0)
return (blkid);
}
static void
{
int i;
blkbuf[0] = '\0';
for (i = 0; i < ndvas; i++)
}
/* ARGSUSED */
static int
{
int l;
"Error %d reading <%llu, %llu, %lld, %llu>: ",
goto out;
}
} else {
}
} else {
}
}
}
fill++;
}
}
} else {
}
}
out:
} else {
}
}
/*ARGSUSED*/
static void
{
int advance = zdb_advance;
(void) printf("Indirect blocks:\n");
if (object == 0)
advance |= ADVANCE_DATA;
continue;
(void) printf("\n");
}
/*ARGSUSED*/
static void
{
return;
(void) printf("\t\thead_dataset_obj = %llu\n",
(void) printf("\t\tparent_dir_obj = %llu\n",
(void) printf("\t\torigin_obj = %llu\n",
(void) printf("\t\tchild_dir_zapobj = %llu\n",
(void) printf("\t\tprops_zapobj = %llu\n",
(void) printf("\t\tdeleg_zapobj = %llu\n",
}
/*ARGSUSED*/
static void
{
char blkbuf[BP_SPRINTF_LEN];
return;
(void) printf("\t\tdataset_obj = %llu\n",
(void) printf("\t\tprev_snap_obj = %llu\n",
(void) printf("\t\tprev_snap_txg = %llu\n",
(void) printf("\t\tnext_snap_obj = %llu\n",
(void) printf("\t\tsnapnames_zapobj = %llu\n",
(void) printf("\t\tnum_children = %llu\n",
(void) printf("\t\tcreation_txg = %llu\n",
(void) printf("\t\tdeadlist_obj = %llu\n",
(void) printf("\t\tfsid_guid = %llu\n",
(void) printf("\t\tguid = %llu\n",
(void) printf("\t\tflags = %llx\n",
}
static void
{
char bytes[6];
char comp[6];
char uncomp[6];
return;
if (bplist_empty(&bpl)) {
bplist_close(&bpl);
return;
}
(void) printf("\n %s: %llu entries, %s (%s/%s comp)\n",
} else {
(void) printf("\n %s: %llu entries, %s\n",
}
bplist_close(&bpl);
return;
}
(void) printf("\n");
char blkbuf[BP_SPRINTF_LEN];
(void) printf("\tItem %3llu: %s\n",
}
bplist_close(&bpl);
}
static avl_tree_t idx_tree;
static avl_tree_t domain_tree;
static boolean_t fuid_table_loaded;
static void
{
if (fuid_table_loaded) {
}
}
/*
* print uid or gid information.
* For normal POSIX id just the id is printed in decimal format.
* For CIFS files with FUID the fuid is printed in hex followed by
* the doman-rid string.
*/
static void
{
if (FUID_INDEX(id)) {
char *domain;
} else {
}
}
static void
{
/* Load domain table, if not already loaded */
/* first find the fuid object. It lives in the master node */
&idx_tree, &domain_tree);
}
}
/*ARGSUSED*/
static void
{
int error;
if (error != 0) {
}
return;
}
}
/*ARGSUSED*/
static void
{
}
/*ARGSUSED*/
static void
{
}
dump_none, /* unallocated */
dump_zap, /* object directory */
dump_uint64, /* object array */
dump_none, /* packed nvlist */
dump_packed_nvlist, /* packed nvlist size */
dump_none, /* bplist */
dump_none, /* bplist header */
dump_none, /* SPA space map header */
dump_none, /* SPA space map */
dump_none, /* ZIL intent log */
dump_dnode, /* DMU dnode */
dump_dmu_objset, /* DMU objset */
dump_dsl_dir, /* DSL directory */
dump_zap, /* DSL directory child map */
dump_zap, /* DSL dataset snap map */
dump_zap, /* DSL props */
dump_dsl_dataset, /* DSL dataset */
dump_znode, /* ZFS znode */
dump_acl, /* ZFS V0 ACL */
dump_uint8, /* ZFS plain file */
dump_zpldir, /* ZFS directory */
dump_zap, /* ZFS master node */
dump_zap, /* ZFS delete queue */
dump_uint8, /* zvol object */
dump_zap, /* zvol prop */
dump_uint8, /* other uint8[] */
dump_uint64, /* other uint64[] */
dump_zap, /* other ZAP */
dump_zap, /* persistent error log */
dump_uint8, /* SPA history */
dump_uint64, /* SPA history offsets */
dump_zap, /* Pool properties */
dump_zap, /* DSL permissions */
dump_acl, /* ZFS ACL */
dump_uint8, /* ZFS SYSACL */
dump_none, /* FUID nvlist */
dump_packed_nvlist, /* FUID nvlist size */
};
static void
{
char aux[50];
int error;
if (*print_header) {
(void) printf("\n Object lvl iblk dblk lsize"
" asize type\n");
*print_header = 0;
}
if (object == 0) {
} else {
if (error)
fatal("dmu_bonus_hold(%llu) failed, errno %u",
}
lsize);
aux[0] = '\0';
}
}
(void) printf("%10lld %3u %5s %5s %5s %5s %s%s\n",
(void) printf("%10s %3s %5s %5s %5s %5s %s\n",
}
if (verbosity >= 4) {
*print_header = 1;
}
if (verbosity >= 5)
if (verbosity >= 5) {
/*
* Report the list of segments that comprise the object.
*/
int minlvl = 1;
minlvl = 0;
}
for (;;) {
blkfill, 0);
if (error)
break;
blkfill, 0);
(void) printf("\t\tsegment [%016llx, %016llx)"
if (error)
break;
}
}
}
static char *objset_types[DMU_OST_NUMTYPES] = {
"NONE", "META", "ZPL", "ZVOL", "OTHER", "ANY" };
/*ARGSUSED*/
static void
{
char numbuf[8];
char blkbuf[BP_SPRINTF_LEN];
char osname[MAXNAMELEN];
char *type = "UNKNOWN";
int print_header = 1;
int i, error;
} else {
}
if (verbosity >= 4) {
} else {
blkbuf[0] = '\0';
}
(void) printf("Dataset %s [%s], ID %llu, cr_txg %llu, "
"%s, %llu objects%s\n",
if (verbosity < 2)
return;
if (zopt_objects != 0) {
for (i = 0; i < zopt_objects; i++)
&print_header);
(void) printf("\n");
return;
}
object_count = 1;
object = 0;
object_count++;
}
(void) printf("\n");
}
static void
{
(void) printf("Uberblock\n\n");
(void) printf("\ttimestamp = %llu UTC = %s",
char blkbuf[BP_SPRINTF_LEN];
}
(void) printf("\n");
}
static void
dump_config(const char *pool)
{
}
}
static void
dump_label(const char *dev)
{
int fd;
int l;
exit(1);
}
exit(1);
}
for (l = 0; l < VDEV_LABELS; l++) {
(void) printf("--------------------------------------------\n");
(void) printf("LABEL %d\n", l);
(void) printf("--------------------------------------------\n");
(void) printf("failed to read label %d\n", l);
continue;
}
(void) printf("failed to unpack label %d\n", l);
continue;
}
}
}
/*ARGSUSED*/
static int
{
int error;
if (error) {
return (0);
}
return (0);
}
static void
{
int c, m, error;
for (c = 0; c < rvd->vdev_children; c++) {
for (m = 0; m < vd->vdev_ms_count; m++) {
if (error)
fatal("%s bad space map #%d, error %d",
}
}
}
static int
{
int error;
int d;
for (d = 0; d < BP_GET_NDVAS(bp); d++) {
return (ENXIO);
return (ENXIO);
/* Prepare our copy of the bp in case we need to read GBHs */
if (DVA_GET_GANG(&dva[d])) {
}
return (EAGAIN); /* allocated more than once */
}
return (ESTALE); /* not allocated at all */
}
}
if (BP_IS_GANG(bp)) {
int g;
/* LINTED - compile time assert */
if (error)
return (error);
if (BP_SHOULD_BYTESWAP(&blk))
for (g = 0; g < SPA_GBH_NBLKPTRS; g++) {
break;
if (error)
return (error);
}
}
return (0);
}
static void
{
/* LINTED */
(void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
(u_longlong_t)size);
}
static void
{
int c, m;
for (c = 0; c < rvd->vdev_children; c++) {
for (m = 0; m < vd->vdev_ms_count; m++) {
&msp->ms_allocmap[0]);
}
}
}
static void
{
uberblock_t ub = { 0 };
/*
* Reload the uberblock.
*/
}
/*
* Verify that the sum of the sizes of all blocks in the pool adds up
* to the SPA's sa_alloc total.
*/
typedef struct zdb_blkstats {
#define DMU_OT_DEFERRED DMU_OT_NONE
#define DMU_OT_TOTAL DMU_OT_NUMTYPES
#define ZB_TOTAL ZB_MAXLEVEL
typedef struct zdb_cb {
int zcb_readfails;
int zcb_haderrors;
} zdb_cb_t;
static void
{
int i, error;
for (i = 0; i < 4; i++) {
}
if (dump_opt['S']) {
if (print_sig) {
(void) printf("%llu\t%lld\t%lld\t%s\t%s\t%s\t"
"%llx:%llx:%llx:%llx\n",
}
}
if (dump_opt['L'])
return;
if (error == 0)
return;
}
static int
{
char blkbuf[BP_SPRINTF_LEN];
int error = 0;
} else {
}
else
blkbuf[0] = '\0';
if (!dump_opt['S']) {
(void) printf("zdb_blkptr_cb: Got error %d reading "
"<%llu, %llu, %lld, %llx> %s -- %s\n",
}
return (error);
}
zcb->zcb_readfails = 0;
(void) printf("objset %llu object %llu offset 0x%llx %s\n",
}
return (0);
}
static int
{
traverse_blk_cache_t dummy_cache = { 0 };
int leaks = 0;
int advance = zdb_advance;
int c, e, flags;
advance |= ADVANCE_DATA;
if (!dump_opt['S']) {
(void) printf("\nTraversing all blocks to %sverify"
" nothing leaked ...\n",
}
/*
* Load all space maps. As we traverse the pool, if we find a block
* that's not in its space map, that indicates a double-allocation,
* reference to a freed block, or an unclaimed block. Otherwise we
* remove the block from the space map. If the space maps are not
* empty when we're done, that indicates leaked blocks.
*/
if (!dump_opt['L'])
/*
* If there's a deferred-free bplist, process that first.
*/
if (spa->spa_sync_bplist_obj != 0) {
char blkbuf[BP_SPRINTF_LEN];
(void) printf("[%s] %s\n",
"deferred free", blkbuf);
}
}
}
/*
* Now traverse the pool. If we're reading all data to verify
* checksums, do a scrubbing read so that we validate all copies.
*/
if (advance & ADVANCE_DATA)
flags |= ZIO_FLAG_SCRUB;
continue;
(void) printf("\nError counts:\n\n");
for (e = 0; e < 256; e++) {
if (zcb.zcb_errors[e] != 0) {
(void) printf("\t%5d %llu\n",
}
}
}
/*
* Report any leaked segments.
*/
if (!dump_opt['L'])
/*
* If we're interested in printing out the blkptr signatures,
* return now as we don't print out anything else (including
* errors and leaks).
*/
if (dump_opt['S'])
if (dump_opt['L'])
(void) printf("\n\n *** Live pool traversal; "
"block counts are only approximate ***\n\n");
/*
* Log blocks allocated from a separate log device don't count
* as part of the normal pool space; factor them in here.
*/
logalloc = 0;
for (c = 0; c < rvd->vdev_children; c++)
(void) printf("\n\tNo leaks (block sum matches space"
" maps exactly)\n");
} else {
(void) printf("block traversal size %llu != alloc %llu "
"(leaked %lld)\n",
leaks = 1;
}
return (2);
(void) printf("\n");
(void) printf("\tbp count: %10llu\n",
(void) printf("\tbp logical: %10llu\t avg: %6llu\n",
(void) printf("\tbp physical: %10llu\t avg:"
" %6llu\tcompression: %6.2f\n",
(void) printf("\tbp allocated: %10llu\t avg:"
" %6llu\tcompression: %6.2f\n",
(void) printf("\tSPA allocated: %10llu\tused: %5.2f%%\n",
int l, t, level;
(void) printf("\nBlocks\tLSIZE\tPSIZE\tASIZE"
"\t avg\t comp\t%%Total\tType\n");
for (t = 0; t <= DMU_OT_NUMTYPES; t++) {
char *typename;
(void) printf("%6s\t%5s\t%5s\t%5s"
"\t%5s\t%5s\t%6s\t%s\n",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
typename);
continue;
}
continue;
continue;
continue;
(void) printf("%6s\t%5s\t%5s\t%5s\t%5s"
"\t%5.2f\t%6.2f\t",
else
(void) printf(" L%d %s\n",
}
}
}
(void) printf("\n");
if (leaks)
return (2);
if (zcb.zcb_haderrors)
return (3);
return (0);
}
static void
{
int rc = 0;
if (dump_opt['u'])
}
}
if (dump_opt['s'])
if (rc != 0)
}
#define ZDB_FLAG_CHECKSUM 0x0001
#define ZDB_FLAG_DECOMPRESS 0x0002
#define ZDB_FLAG_BSWAP 0x0004
#define ZDB_FLAG_GBH 0x0008
#define ZDB_FLAG_INDIRECT 0x0010
#define ZDB_FLAG_PHYS 0x0020
#define ZDB_FLAG_RAW 0x0040
#define ZDB_FLAG_PRINT_BLKPTR 0x0080
int flagbits[256];
static void
{
int d;
if (flags & ZDB_FLAG_BSWAP)
/*
* Super-ick warning: This code is also duplicated in
* replication, too.
*/
for (d = 0; d < BP_GET_NDVAS(bp); d++) {
(void) printf("\tDVA[%d]: vdev_id %lld / %llx\n", d,
(void) printf("\tDVA[%d]: GANG: %-5s GRID: %04llx\t"
"ASIZE: %llx\n", d,
(void) printf("\tDVA[%d]: :%llu:%llx:%llx:%s%s%s%s\n", d,
"d" : "",
}
(void) printf("\tLSIZE: %-16llx\t\tPSIZE: %llx\n",
(void) printf("\tENDIAN: %6s\t\t\t\t\tTYPE: %s\n",
(void) printf("\tBIRTH: %-16llx LEVEL: %-2llu\tFILL: %llx\n",
(void) printf("\tCKFUNC: %-16s\t\tCOMP: %s\n",
(void) printf("\tCKSUM: %llx:%llx:%llx:%llx\n",
}
static void
{
int i;
for (i = 0; i < nbps; i++)
}
static void
{
}
static void
{
if (flags & ZDB_FLAG_BSWAP)
}
static void
{
int i, j;
char *hdr, *c;
if (do_bswap)
hdr = " 7 6 5 4 3 2 1 0 f e d c b a 9 8";
else
hdr = " 0 1 2 3 4 5 6 7 8 9 a b c d e f";
for (i = 0; i < nwords; i += 2) {
(void) printf("%06llx: %016llx %016llx ",
(u_longlong_t)(i * sizeof (uint64_t)),
c = (char *)&d[i];
for (j = 0; j < 2 * sizeof (uint64_t); j++)
(void) printf("\n");
}
}
/*
* There are two acceptable formats:
* child[.child]* - For example: 0.1.1
*
* The second form can be used to specify arbitrary vdevs anywhere
* in the heirarchy. For example, in a pool with a mirror of
* RAID-Zs, you can specify either RAID-Z vdev with 0.0 or 0.1 .
*/
static vdev_t *
{
char *s, *p, *q;
int i;
return (NULL);
/* First, assume the x.x.x.x format */
goto name;
if (i < 0 || i >= vdev->vdev_children)
return (NULL);
if (*s == '\0')
return (vdev);
name:
for (i = 0; i < vdev->vdev_children; i++) {
continue;
else
return (vc);
}
return (vc);
return (vc);
return (vc);
}
return (NULL);
}
/*
* Read a block from a pool and print it out. The syntax of the
* block descriptor is:
*
* pool:vdev_specifier:offset:size[:flags]
*
* pool - The name of the pool you wish to read from
* vdev_specifier - Which vdev (see comment for zdb_vdev_lookup)
* offset - offset, in hex, in bytes
* size - Amount of data to read, in hex, in bytes
* flags - A string of characters specifying options
* b: Decode a blkptr at given offset within block
* *c: Calculate and display checksums
* *d: Decompress data before dumping
* e: Byteswap data before dumping
* *g: Display data as a gang block header
* *i: Display as an indirect block
* p: Do I/O to physical offset
* r: Dump raw data to stdout
*
* * = not yet implemented
*/
static void
{
int flags = 0;
void *buf;
spa_name = s ? s : "";
vdev = s ? s : "";
flagstr = s ? s : "";
s = NULL;
if (size == 0)
s = "size must not be zero";
s = "size must be a multiple of sector size";
s = "offset must be a multiple of sector size";
if (s) {
return;
}
for (i = 0; flagstr[i]; i++) {
if (bit == 0) {
(void) printf("***Invalid flag: %c\n",
flagstr[i]);
continue;
}
/* If it's not something with an argument, keep going */
ZDB_FLAG_PRINT_BLKPTR)) == 0)
continue;
p = &flagstr[i + 1];
if (bit == ZDB_FLAG_PRINT_BLKPTR)
if (*p != ':' && *p != '\0') {
(void) printf("***Invalid flag arg: '%s'\n", s);
return;
}
}
}
if (error)
fatal("Failed to open pool '%s': %s",
}
return;
} else {
else
(void) printf("Found vdev type: %s\n",
}
if (flags & ZDB_FLAG_PHYS)
/* XXX todo - cons up a BP so RAID-Z will be happy */
if (error) {
goto out;
}
if (flags & ZDB_FLAG_PRINT_BLKPTR)
zdb_print_blkptr((blkptr_t *)(void *)
else if (flags & ZDB_FLAG_RAW)
else if (flags & ZDB_FLAG_INDIRECT)
flags);
else if (flags & ZDB_FLAG_GBH)
else
out:
}
static boolean_t
{
char *s;
}
static boolean_t
{
}
static boolean_t
{
for (c = 0; c < children; ++c)
return (B_TRUE);
return (B_FALSE);
}
static boolean_t
{
for (c = 0; c < children; ++c) {
return (B_TRUE);
}
return (B_FALSE);
}
static boolean_t
{
&nvroot) == 0);
}
static boolean_t
{
&nvroot) == 0);
}
static boolean_t
{
if (guid != 0) {
return (
} else {
return (
}
}
static int
char *cachefile)
{
else
(void) fatal(
"More than one matching pool - "
} else {
error = 0;
}
}
}
}
return (error);
}
int
{
int i, c;
char *endstr;
int dump_all = 1;
int verbose = 0;
int error;
int exported = 0;
switch (c) {
case 'u':
case 'd':
case 'i':
case 'b':
case 'c':
case 's':
case 'C':
case 'l':
case 'R':
dump_opt[c]++;
dump_all = 0;
break;
case 'L':
dump_opt[c]++;
break;
case 'O':
if (endstr[0] == '!') {
endstr++;
set = 0;
} else {
set = 1;
}
flag = ADVANCE_PRE;
flag = ADVANCE_PRE;
flag = ADVANCE_DATA;
} else {
usage();
}
if (set)
zdb_advance |= flag;
else
zdb_advance &= ~flag;
break;
case 'B':
(void) printf("simulating bad block "
"<%llu, %llu, %lld, %llx>\n",
break;
case 'v':
verbose++;
break;
case 'U':
break;
case 'e':
exported = 1;
break;
case 'p':
break;
case 'S':
dump_opt[c]++;
dump_all = 0;
usage();
else
usage();
break;
default:
usage();
break;
}
}
(void) fatal("-p option requires use of -e\n");
g_zfs = libzfs_init();
/*
* Disable vdev caching. If we don't do this, live pool traversal
* won't make progress because it will never see disk updates.
*/
zfs_vdev_cache_size = 0;
for (c = 0; c < 256; c++) {
dump_opt[c] = 1;
if (dump_opt[c])
}
if (argc < 1) {
if (dump_opt['C']) {
return (0);
}
usage();
}
if (dump_opt['l']) {
dump_label(argv[0]);
return (0);
}
if (dump_opt['R']) {
while (argv[0]) {
argv++;
argc--;
}
if (spa)
return (0);
}
if (dump_opt['C'])
dump_config(argv[0]);
} else {
}
} else {
/*
* Check to see if the name refers to an exported zpool
*/
if (error == 0) {
else if (nvlist_add_string(nvl,
vdev_dir) != 0)
}
if (error == 0)
if (error == 0)
}
}
if (error)
argv++;
if (--argc > 0) {
zopt_objects = argc;
for (i = 0; i < zopt_objects; i++) {
errno = 0;
if (zopt_object[i] == 0 && errno != 0)
fatal("bad object number %s: %s",
}
}
} else {
}
kernel_fini();
return (0);
}