/* * __ovfl_reuse_verbose -- * Dump information about a reuse overflow record. */ static int __ovfl_reuse_verbose(WT_SESSION_IMPL *session, WT_PAGE *page, WT_OVFL_REUSE *reuse, const char *tag) { WT_DECL_ITEM(tmp); WT_DECL_RET; WT_RET(__wt_scr_alloc(session, 64, &tmp)); WT_ERR(__wt_verbose(session, WT_VERB_OVERFLOW, "reuse: %s%s%p %s (%s%s%s) {%.*s}", tag == NULL ? "" : tag, tag == NULL ? "" : ": ", page, __wt_addr_string( session, WT_OVFL_REUSE_ADDR(reuse), reuse->addr_size, tmp), F_ISSET(reuse, WT_OVFL_REUSE_INUSE) ? "inuse" : "", F_ISSET(reuse, WT_OVFL_REUSE_INUSE) && F_ISSET(reuse, WT_OVFL_REUSE_JUST_ADDED) ? ", " : "", F_ISSET(reuse, WT_OVFL_REUSE_JUST_ADDED) ? "just-added" : "", WT_MIN(reuse->value_size, 40), (char *)WT_OVFL_REUSE_VALUE(reuse))); err: __wt_scr_free(session, &tmp); return (ret); }
/* * __wt_debug_addr_print -- * Print out an address. */ int __wt_debug_addr_print( WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size) { WT_DECL_ITEM(buf); WT_DECL_RET; WT_RET(__wt_scr_alloc(session, 128, &buf)); ret = __wt_fprintf(stderr, "%s\n", __wt_addr_string(session, addr, addr_size, buf)); __wt_scr_free(session, &buf); return (ret); }
/* * __wt_page_addr_string -- * Figure out a page's "address" and load a buffer with a printable, * nul-terminated representation of that address. */ const char * __wt_page_addr_string(WT_SESSION_IMPL *session, WT_REF *ref, WT_ITEM *buf) { size_t addr_size; const uint8_t *addr; if (__wt_ref_is_root(ref)) { buf->data = "[Root]"; buf->size = strlen("[Root]"); return (buf->data); } (void)__wt_ref_info(session, ref, &addr, &addr_size, NULL); return (__wt_addr_string(session, addr, addr_size, buf)); }
/* * __wt_page_addr_string -- * Figure out a page's "address" and load a buffer with a printable, * nul-terminated representation of that address. */ const char * __wt_page_addr_string(WT_SESSION_IMPL *session, WT_ITEM *buf, WT_PAGE *page) { uint32_t size; const uint8_t *addr; if (WT_PAGE_IS_ROOT(page)) { buf->data = "[Root]"; buf->size = WT_STORE_SIZE(strlen("[Root]")); return (buf->data); } (void)__wt_ref_info( session, page->parent, page->ref, &addr, &size, NULL); return (__wt_addr_string(session, buf, addr, size)); }
/* * __track_msg -- * Output a verbose message and associated page and address pair. */ static int __track_msg(WT_SESSION_IMPL *session, WT_PAGE *page, const char *msg, WT_PAGE_TRACK *track) { WT_DECL_RET; WT_DECL_ITEM(buf); char f[64]; WT_RET(__wt_scr_alloc(session, 64, &buf)); WT_VERBOSE_ERR( session, reconcile, "page %p %s (%s) %" PRIu32 "B @%s", page, msg, __wt_track_string(track, f, sizeof(f)), track->size, __wt_addr_string(session, buf, track->addr.addr, track->addr.size)); err: __wt_scr_free(&buf); return (ret); }
/* * __ovfl_txnc_verbose -- * Dump information about a transaction-cached overflow record. */ static int __ovfl_txnc_verbose(WT_SESSION_IMPL *session, WT_PAGE *page, WT_OVFL_TXNC *txnc, const char *tag) { WT_DECL_ITEM(tmp); WT_DECL_RET; WT_RET(__wt_scr_alloc(session, 64, &tmp)); WT_ERR(__wt_verbose(session, WT_VERB_OVERFLOW, "txn-cache: %s%s%p %s %" PRIu64 " {%.*s}", tag == NULL ? "" : tag, tag == NULL ? "" : ": ", page, __wt_addr_string( session, WT_OVFL_TXNC_ADDR(txnc), txnc->addr_size, tmp), txnc->current, WT_MIN(txnc->value_size, 40), (char *)WT_OVFL_TXNC_VALUE(txnc))); err: __wt_scr_free(session, &tmp); return (ret); }
/* * __ovfl_discard_verbose -- * Dump information about a discard overflow record. */ static int __ovfl_discard_verbose( WT_SESSION_IMPL *session, WT_PAGE *page, WT_CELL *cell, const char *tag) { WT_CELL_UNPACK *unpack, _unpack; WT_DECL_ITEM(tmp); WT_DECL_RET; WT_RET(__wt_scr_alloc(session, 512, &tmp)); unpack = &_unpack; __wt_cell_unpack(cell, unpack); WT_ERR(__wt_verbose(session, WT_VERB_OVERFLOW, "discard: %s%s%p %s", tag == NULL ? "" : tag, tag == NULL ? "" : ": ", page, __wt_addr_string(session, unpack->data, unpack->size, tmp))); err: __wt_scr_free(session, &tmp); return (ret); }
/* * __wt_verify -- * Verify a file. */ int __wt_verify(WT_SESSION_IMPL *session, const char *cfg[]) { WT_BM *bm; WT_BTREE *btree; WT_CKPT *ckptbase, *ckpt; WT_DECL_RET; WT_VSTUFF *vs, _vstuff; size_t root_addr_size; uint8_t root_addr[WT_BTREE_MAX_ADDR_COOKIE]; bool bm_start, quit; btree = S2BT(session); bm = btree->bm; ckptbase = NULL; bm_start = false; WT_CLEAR(_vstuff); vs = &_vstuff; WT_ERR(__wt_scr_alloc(session, 0, &vs->max_key)); WT_ERR(__wt_scr_alloc(session, 0, &vs->max_addr)); WT_ERR(__wt_scr_alloc(session, 0, &vs->tmp1)); WT_ERR(__wt_scr_alloc(session, 0, &vs->tmp2)); WT_ERR(__wt_scr_alloc(session, 0, &vs->tmp3)); WT_ERR(__wt_scr_alloc(session, 0, &vs->tmp4)); /* Check configuration strings. */ WT_ERR(__verify_config(session, cfg, vs)); /* Optionally dump specific block offsets. */ WT_ERR(__verify_config_offsets(session, cfg, &quit)); if (quit) goto done; /* Get a list of the checkpoints for this file. */ WT_ERR( __wt_meta_ckptlist_get(session, btree->dhandle->name, &ckptbase)); /* Inform the underlying block manager we're verifying. */ WT_ERR(bm->verify_start(bm, session, ckptbase, cfg)); bm_start = true; /* Loop through the file's checkpoints, verifying each one. */ WT_CKPT_FOREACH(ckptbase, ckpt) { WT_ERR(__wt_verbose(session, WT_VERB_VERIFY, "%s: checkpoint %s", btree->dhandle->name, ckpt->name)); /* Fake checkpoints require no work. */ if (F_ISSET(ckpt, WT_CKPT_FAKE)) continue; /* House-keeping between checkpoints. */ __verify_checkpoint_reset(vs); if (WT_VRFY_DUMP(vs)) WT_ERR(__wt_msg(session, "%s: checkpoint %s", btree->dhandle->name, ckpt->name)); /* Load the checkpoint. */ WT_ERR(bm->checkpoint_load(bm, session, ckpt->raw.data, ckpt->raw.size, root_addr, &root_addr_size, true)); /* * Ignore trees with no root page. * Verify, then discard the checkpoint from the cache. */ if (root_addr_size != 0 && (ret = __wt_btree_tree_open( session, root_addr, root_addr_size)) == 0) { if (WT_VRFY_DUMP(vs)) WT_ERR(__wt_msg(session, "Root: %s %s", __wt_addr_string(session, root_addr, root_addr_size, vs->tmp1), __wt_page_type_string( btree->root.page->type))); WT_WITH_PAGE_INDEX(session, ret = __verify_tree(session, &btree->root, vs)); WT_TRET(__wt_cache_op(session, WT_SYNC_DISCARD)); } /* Unload the checkpoint. */ WT_TRET(bm->checkpoint_unload(bm, session)); WT_ERR(ret); /* Display the tree shape. */ if (vs->dump_shape) WT_ERR(__verify_tree_shape(session, vs)); }