diff --git a/cmd/zdb/Makefile.am b/cmd/zdb/Makefile.am index c93c9c37cd8d..ebdc19128e1a 100644 --- a/cmd/zdb/Makefile.am +++ b/cmd/zdb/Makefile.am @@ -10,6 +10,7 @@ zdb_SOURCES = \ %D%/zdb_il.c zdb_LDADD = \ + libzdb.la \ libzpool.la \ libzfs_core.la \ libnvpair.la diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 2062f4fa1026..afdc5a2c8b54 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -88,36 +88,10 @@ #include #include +#include + #include "zdb.h" -#define ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ? \ - zio_compress_table[(idx)].ci_name : "UNKNOWN") -#define ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \ - zio_checksum_table[(idx)].ci_name : "UNKNOWN") -#define ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : \ - (idx) == DMU_OTN_ZAP_DATA || (idx) == DMU_OTN_ZAP_METADATA ? \ - DMU_OT_ZAP_OTHER : \ - (idx) == DMU_OTN_UINT64_DATA || (idx) == DMU_OTN_UINT64_METADATA ? \ - DMU_OT_UINT64_OTHER : DMU_OT_NUMTYPES) - -/* Some platforms require part of inode IDs to be remapped */ -#ifdef __APPLE__ -#define ZDB_MAP_OBJECT_ID(obj) INO_XNUTOZFS(obj, 2) -#else -#define ZDB_MAP_OBJECT_ID(obj) (obj) -#endif - -static const char * -zdb_ot_name(dmu_object_type_t type) -{ - if (type < DMU_OT_NUMTYPES) - return (dmu_ot[type].ot_name); - else if ((type & DMU_OT_NEWTYPE) && - ((type & DMU_OT_BYTESWAP_MASK) < DMU_BSWAP_NUMFUNCS)) - return (dmu_ot_byteswap[type & DMU_OT_BYTESWAP_MASK].ob_name); - else - return ("UNKNOWN"); -} extern int reference_tracking_enable; extern int zfs_recover; @@ -135,35 +109,12 @@ typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size); static uint64_t *zopt_metaslab = NULL; static unsigned zopt_metaslab_args = 0; -typedef struct zopt_object_range { - uint64_t zor_obj_start; - uint64_t zor_obj_end; - uint64_t zor_flags; -} zopt_object_range_t; static zopt_object_range_t *zopt_object_ranges = NULL; static unsigned zopt_object_args = 0; static int flagbits[256]; -#define ZOR_FLAG_PLAIN_FILE 0x0001 -#define ZOR_FLAG_DIRECTORY 0x0002 -#define ZOR_FLAG_SPACE_MAP 0x0004 -#define ZOR_FLAG_ZAP 0x0008 -#define ZOR_FLAG_ALL_TYPES -1 -#define ZOR_SUPPORTED_FLAGS (ZOR_FLAG_PLAIN_FILE | \ - ZOR_FLAG_DIRECTORY | \ - ZOR_FLAG_SPACE_MAP | \ - ZOR_FLAG_ZAP) - -#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_RAW 0x0020 -#define ZDB_FLAG_PRINT_BLKPTR 0x0040 -#define ZDB_FLAG_VERBOSE 0x0080 static uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */ static int leaked_objects = 0; @@ -176,62 +127,7 @@ static void mos_obj_refd_multiple(uint64_t); static int dump_bpobj_cb(void *arg, const blkptr_t *bp, boolean_t free, dmu_tx_t *tx); -typedef struct sublivelist_verify { - /* FREE's that haven't yet matched to an ALLOC, in one sub-livelist */ - zfs_btree_t sv_pair; - /* ALLOC's without a matching FREE, accumulates across sub-livelists */ - zfs_btree_t sv_leftover; -} sublivelist_verify_t; - -static int -livelist_compare(const void *larg, const void *rarg) -{ - const blkptr_t *l = larg; - const blkptr_t *r = rarg; - - /* Sort them according to dva[0] */ - uint64_t l_dva0_vdev, r_dva0_vdev; - l_dva0_vdev = DVA_GET_VDEV(&l->blk_dva[0]); - r_dva0_vdev = DVA_GET_VDEV(&r->blk_dva[0]); - if (l_dva0_vdev < r_dva0_vdev) - return (-1); - else if (l_dva0_vdev > r_dva0_vdev) - return (+1); - - /* if vdevs are equal, sort by offsets. */ - uint64_t l_dva0_offset; - uint64_t r_dva0_offset; - l_dva0_offset = DVA_GET_OFFSET(&l->blk_dva[0]); - r_dva0_offset = DVA_GET_OFFSET(&r->blk_dva[0]); - if (l_dva0_offset < r_dva0_offset) { - return (-1); - } else if (l_dva0_offset > r_dva0_offset) { - return (+1); - } - - /* - * Since we're storing blkptrs without cancelling FREE/ALLOC pairs, - * it's possible the offsets are equal. In that case, sort by txg - */ - if (l->blk_birth < r->blk_birth) { - return (-1); - } else if (l->blk_birth > r->blk_birth) { - return (+1); - } - return (0); -} - -typedef struct sublivelist_verify_block { - dva_t svb_dva; - - /* - * We need this to check if the block marked as allocated - * in the livelist was freed (and potentially reallocated) - * in the metaslab spacemaps at a later TXG. - */ - uint64_t svb_allocated_txg; -} sublivelist_verify_block_t; static void zdb_print_blkptr(const blkptr_t *bp, int flags); diff --git a/include/Makefile.am b/include/Makefile.am index 5f38f6ac6ddb..cb28a2d6c96c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -186,6 +186,7 @@ USER_H = \ libuutil.h \ libuutil_common.h \ libuutil_impl.h \ + libzdb.h \ libzfs.h \ libzfs_core.h \ libzfsbootenv.h \ diff --git a/include/libzdb.h b/include/libzdb.h new file mode 100644 index 000000000000..ef910d0a2c5a --- /dev/null +++ b/include/libzdb.h @@ -0,0 +1,68 @@ +#define ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ? \ + zio_compress_table[(idx)].ci_name : "UNKNOWN") +#define ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \ + zio_checksum_table[(idx)].ci_name : "UNKNOWN") +#define ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : \ + (idx) == DMU_OTN_ZAP_DATA || (idx) == DMU_OTN_ZAP_METADATA ? \ + DMU_OT_ZAP_OTHER : \ + (idx) == DMU_OTN_UINT64_DATA || (idx) == DMU_OTN_UINT64_METADATA ? \ + DMU_OT_UINT64_OTHER : DMU_OT_NUMTYPES) + +/* Some platforms require part of inode IDs to be remapped */ +#ifdef __APPLE__ +#define ZDB_MAP_OBJECT_ID(obj) INO_XNUTOZFS(obj, 2) +#else +#define ZDB_MAP_OBJECT_ID(obj) (obj) +#endif + +#define ZOR_FLAG_PLAIN_FILE 0x0001 +#define ZOR_FLAG_DIRECTORY 0x0002 +#define ZOR_FLAG_SPACE_MAP 0x0004 +#define ZOR_FLAG_ZAP 0x0008 +#define ZOR_FLAG_ALL_TYPES -1 +#define ZOR_SUPPORTED_FLAGS (ZOR_FLAG_PLAIN_FILE | \ + ZOR_FLAG_DIRECTORY | \ + ZOR_FLAG_SPACE_MAP | \ + ZOR_FLAG_ZAP) + +#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_RAW 0x0020 +#define ZDB_FLAG_PRINT_BLKPTR 0x0040 +#define ZDB_FLAG_VERBOSE 0x0080 + + +typedef struct zdb_ctx { +} zdb_ctx_t; + +typedef struct zopt_object_range { + uint64_t zor_obj_start; + uint64_t zor_obj_end; + uint64_t zor_flags; +} zopt_object_range_t; + + +typedef struct sublivelist_verify { + /* FREE's that haven't yet matched to an ALLOC, in one sub-livelist */ + zfs_btree_t sv_pair; + + /* ALLOC's without a matching FREE, accumulates across sub-livelists */ + zfs_btree_t sv_leftover; +} sublivelist_verify_t; + +typedef struct sublivelist_verify_block { + dva_t svb_dva; + + /* + * We need this to check if the block marked as allocated + * in the livelist was freed (and potentially reallocated) + * in the metaslab spacemaps at a later TXG. + */ + uint64_t svb_allocated_txg; +} sublivelist_verify_block_t; + +const char *zdb_ot_name(dmu_object_type_t type); +int livelist_compare(const void *larg, const void *rarg); diff --git a/lib/Makefile.am b/lib/Makefile.am index 499ebdaeba9b..050a6cac0a37 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -9,11 +9,11 @@ # These library interfaces are subject to change at any time. # # -# CMDS: zhack/ztest/zdb/ zfs/zpool/zed/ +# CMDS: zhack/ztest/ zfs/zpool/zed/ # raidz_{test,bench} zinject/zstream # | | # LIBS: | | libzfsbootenv* -# | | | +# |--libzdb--zdb | | # | | | # libzpool libzfs* ----------------+ # | | | \ / | | | @@ -62,6 +62,7 @@ include $(srcdir)/%D%/libspl/Makefile.am include $(srcdir)/%D%/libtpool/Makefile.am include $(srcdir)/%D%/libunicode/Makefile.am include $(srcdir)/%D%/libuutil/Makefile.am +include $(srcdir)/%D%/libzdb/Makefile.am include $(srcdir)/%D%/libzfs_core/Makefile.am include $(srcdir)/%D%/libzfs/Makefile.am include $(srcdir)/%D%/libzfsbootenv/Makefile.am diff --git a/lib/libzdb/Makefile.am b/lib/libzdb/Makefile.am new file mode 100644 index 000000000000..ec4fd92b984e --- /dev/null +++ b/lib/libzdb/Makefile.am @@ -0,0 +1,7 @@ +libzdb_la_CFLAGS = $(AM_CFLAGS) $(LIBRARY_CFLAGS) +libzdb_la_CFLAGS += -fvisibility=hidden + +noinst_LTLIBRARIES += libzdb.la + +libzdb_la_SOURCES = \ + %D%/libzdb.c diff --git a/lib/libzdb/libzdb.c b/lib/libzdb/libzdb.c new file mode 100644 index 000000000000..9989fa1eb80f --- /dev/null +++ b/lib/libzdb/libzdb.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +const char * +zdb_ot_name(dmu_object_type_t type) +{ + if (type < DMU_OT_NUMTYPES) + return (dmu_ot[type].ot_name); + else if ((type & DMU_OT_NEWTYPE) && + ((type & DMU_OT_BYTESWAP_MASK) < DMU_BSWAP_NUMFUNCS)) + return (dmu_ot_byteswap[type & DMU_OT_BYTESWAP_MASK].ob_name); + else + return ("UNKNOWN"); +} + +int +livelist_compare(const void *larg, const void *rarg) +{ + const blkptr_t *l = larg; + const blkptr_t *r = rarg; + + /* Sort them according to dva[0] */ + uint64_t l_dva0_vdev, r_dva0_vdev; + l_dva0_vdev = DVA_GET_VDEV(&l->blk_dva[0]); + r_dva0_vdev = DVA_GET_VDEV(&r->blk_dva[0]); + if (l_dva0_vdev < r_dva0_vdev) + return (-1); + else if (l_dva0_vdev > r_dva0_vdev) + return (+1); + + /* if vdevs are equal, sort by offsets. */ + uint64_t l_dva0_offset; + uint64_t r_dva0_offset; + l_dva0_offset = DVA_GET_OFFSET(&l->blk_dva[0]); + r_dva0_offset = DVA_GET_OFFSET(&r->blk_dva[0]); + if (l_dva0_offset < r_dva0_offset) { + return (-1); + } else if (l_dva0_offset > r_dva0_offset) { + return (+1); + } + + /* + * Since we're storing blkptrs without cancelling FREE/ALLOC pairs, + * it's possible the offsets are equal. In that case, sort by txg + */ + if (l->blk_birth < r->blk_birth) { + return (-1); + } else if (l->blk_birth > r->blk_birth) { + return (+1); + } + return (0); +}