From e3a646e4d2ca423feb4493f0b92e72f6e475aa8b Mon Sep 17 00:00:00 2001 From: Ming-Hung Tsai Date: Fri, 5 Feb 2021 16:15:24 +0800 Subject: [PATCH] [dbg] Improve error resilience of debugging tools Do not open the metadata. The tool interprets user specified blocks one-by-one. Thus, there's no need to preload the metadata structures. Also remove the unused --ignore-metadata-space-map option. It was designed to control the loading of space maps with the old metadata constructors. --- caching/cache_debug.cc | 42 ++++++++++--------- thin-provisioning/thin_debug.cc | 71 ++++++++++++++++----------------- 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/caching/cache_debug.cc b/caching/cache_debug.cc index 1053560..155fd94 100644 --- a/caching/cache_debug.cc +++ b/caching/cache_debug.cc @@ -48,7 +48,7 @@ namespace { class help : public dbg::command { virtual void exec(strings const &args, ostream &out) { out << "Commands:" << endl - << " superblock" << endl + << " superblock [block#]" << endl << " mapping_node " << endl << " mapping_array " << endl << " exit" << endl; @@ -82,16 +82,21 @@ namespace { class show_superblock : public dbg::command { public: - explicit show_superblock(metadata::ptr md) - : md_(md) { + explicit show_superblock(block_manager::ptr bm) + : bm_(bm) { } virtual void exec(strings const &args, ostream &out) { + if (args.size() > 2) + throw runtime_error("incorrect number of arguments"); + + block_address b = caching::SUPERBLOCK_LOCATION; + if (args.size() == 2) + b = boost::lexical_cast(args[1]); + caching::superblock sb = read_superblock(bm_, b); + formatter::ptr f = create_xml_formatter(); ostringstream version; - - superblock const &sb = md_->sb_; - field(*f, "csum", sb.csum); field(*f, "flags", sb.flags.encode()); field(*f, "blocknr", sb.blocknr); @@ -137,7 +142,7 @@ namespace { } private: - metadata::ptr md_; + block_manager::ptr bm_; }; class uint64_show_traits : public uint64_traits { @@ -167,8 +172,8 @@ namespace { template class show_btree_node : public dbg::command { public: - explicit show_btree_node(metadata::ptr md) - : md_(md) { + explicit show_btree_node(block_manager::ptr bm) + : bm_(bm) { } virtual void exec(strings const &args, ostream &out) { @@ -178,7 +183,7 @@ namespace { throw runtime_error("incorrect number of arguments"); block_address block = boost::lexical_cast(args[1]); - block_manager::read_ref rr = md_->tm_->read_lock(block); + block_manager::read_ref rr = bm_->read_lock(block); node_ref n = btree_detail::to_node(rr); if (n.get_type() == INTERNAL) @@ -211,15 +216,15 @@ namespace { f->output(out, 0); } - metadata::ptr md_; + block_manager::ptr bm_; }; template class show_array_block : public dbg::command { typedef array_block rblock; public: - explicit show_array_block(metadata::ptr md) - : md_(md) { + explicit show_array_block(block_manager::ptr bm) + : bm_(bm) { } virtual void exec(strings const& args, ostream &out) { @@ -227,7 +232,7 @@ namespace { throw runtime_error("incorrect number of arguments"); block_address block = boost::lexical_cast(args[1]); - block_manager::read_ref rr = md_->tm_->read_lock(block); + block_manager::read_ref rr = bm_->read_lock(block); rblock b(rr, typename ValueTraits::ref_counter()); show_array_entries(b, out); @@ -252,7 +257,7 @@ namespace { f->output(out, 0); } - metadata::ptr md_; + block_manager::ptr bm_; }; //-------------------------------- @@ -262,12 +267,11 @@ namespace { try { block_manager::ptr bm = open_bm(path, block_manager::READ_ONLY); - metadata::ptr md(new metadata(bm)); command_interpreter::ptr interp = create_command_interpreter(cin, cout); interp->register_command("hello", command::ptr(new hello)); - interp->register_command("superblock", command::ptr(new show_superblock(md))); - interp->register_command("mapping_node", command::ptr(new show_btree_node(md))); - interp->register_command("mapping_array", command::ptr(new show_array_block(md))); + interp->register_command("superblock", command::ptr(new show_superblock(bm))); + interp->register_command("mapping_node", command::ptr(new show_btree_node(bm))); + interp->register_command("mapping_array", command::ptr(new show_array_block(bm))); interp->register_command("help", command::ptr(new help)); interp->register_command("exit", command::ptr(new exit_handler(interp))); interp->enter_main_loop(); diff --git a/thin-provisioning/thin_debug.cc b/thin-provisioning/thin_debug.cc index e458d7d..37a5f18 100644 --- a/thin-provisioning/thin_debug.cc +++ b/thin-provisioning/thin_debug.cc @@ -48,7 +48,7 @@ namespace { class help : public dbg::command { virtual void exec(strings const &args, ostream &out) { out << "Commands:" << endl - << " superblock" << endl + << " superblock [block#]" << endl << " m1_node " << endl << " m2_node " << endl << " detail_node " << endl @@ -85,15 +85,20 @@ namespace { class show_superblock : public dbg::command { public: - explicit show_superblock(metadata::ptr md) - : md_(md) { + explicit show_superblock(block_manager::ptr bm) + : bm_(bm) { } virtual void exec(strings const &args, ostream &out) { + if (args.size() > 2) + throw runtime_error("incorrect number of arguments"); + + block_address b = superblock_detail::SUPERBLOCK_LOCATION; + if (args.size() == 2) + b = boost::lexical_cast(args[1]); + superblock_detail::superblock sb = read_superblock(bm_, b); + formatter::ptr f = create_xml_formatter(); - - thin_provisioning::superblock_detail::superblock const &sb = md_->sb_; - field(*f, "csum", sb.csum_); field(*f, "flags", sb.flags_); field(*f, "blocknr", sb.blocknr_); @@ -134,7 +139,7 @@ namespace { } private: - metadata::ptr md_; + block_manager::ptr bm_; }; class device_details_show_traits : public thin_provisioning::device_tree_detail::device_details_traits { @@ -185,8 +190,8 @@ namespace { template class show_btree_node : public dbg::command { public: - explicit show_btree_node(metadata::ptr md) - : md_(md) { + explicit show_btree_node(block_manager::ptr bm) + : bm_(bm) { } virtual void exec(strings const &args, ostream &out) { @@ -196,7 +201,7 @@ namespace { throw runtime_error("incorrect number of arguments"); block_address block = boost::lexical_cast(args[1]); - block_manager::read_ref rr = md_->tm_->read_lock(block); + block_manager::read_ref rr = bm_->read_lock(block); node_ref n = btree_detail::to_node(rr); if (n.get_type() == INTERNAL) @@ -229,32 +234,27 @@ namespace { f->output(out, 0); } - metadata::ptr md_; + block_manager::ptr bm_; }; class show_index_block : public dbg::command { public: - explicit show_index_block(metadata::ptr md) - : md_(md) { + explicit show_index_block(block_manager::ptr bm) + : bm_(bm) { } virtual void exec(strings const &args, ostream &out) { if (args.size() != 2) throw runtime_error("incorrect number of arguments"); - // manually load metadata_index, without using index_validator() block_address block = boost::lexical_cast(args[1]); - block_manager::read_ref rr = md_->tm_->read_lock(block); - sm_disk_detail::sm_root_disk const *d = - reinterpret_cast(md_->sb_.metadata_space_map_root_); - sm_disk_detail::sm_root v; - sm_disk_detail::sm_root_traits::unpack(*d, v); - block_address nr_indexes = base::div_up(v.nr_blocks_, ENTRIES_PER_BLOCK); + // no checksum validation for debugging purpose + block_manager::read_ref rr = bm_->read_lock(block); sm_disk_detail::metadata_index const *mdi = reinterpret_cast(rr.data()); - show_metadata_index(mdi, nr_indexes, out); + show_metadata_index(mdi, sm_disk_detail::MAX_METADATA_BITMAPS, out); } private: @@ -267,6 +267,10 @@ namespace { sm_disk_detail::index_entry ie; for (block_address i = 0; i < nr_indexes; i++) { sm_disk_detail::index_entry_traits::unpack(*(mdi->index + i), ie); + + if (!ie.blocknr_ && !ie.nr_free_ && !ie.none_free_before_) + continue; + formatter::ptr f2 = create_xml_formatter(); index_entry_show_traits::show(f2, "value", ie); f->child(boost::lexical_cast(i), f2); @@ -275,25 +279,24 @@ namespace { } unsigned const ENTRIES_PER_BLOCK = (MD_BLOCK_SIZE - sizeof(persistent_data::sm_disk_detail::bitmap_header)) * 4; - metadata::ptr md_; + block_manager::ptr bm_; }; //-------------------------------- - int debug_(string const &path, bool ignore_metadata_sm) { + int debug_(string const &path) { using dbg::command; try { block_manager::ptr bm = open_bm(path, block_manager::READ_ONLY, 1); - metadata::ptr md(new metadata(bm, false)); command_interpreter::ptr interp = create_command_interpreter(cin, cout); interp->register_command("hello", command::ptr(new hello)); - interp->register_command("superblock", command::ptr(new show_superblock(md))); - interp->register_command("m1_node", command::ptr(new show_btree_node(md))); - interp->register_command("m2_node", command::ptr(new show_btree_node(md))); - interp->register_command("detail_node", command::ptr(new show_btree_node(md))); - interp->register_command("index_block", command::ptr(new show_index_block(md))); - interp->register_command("index_node", command::ptr(new show_btree_node(md))); + interp->register_command("superblock", command::ptr(new show_superblock(bm))); + interp->register_command("m1_node", command::ptr(new show_btree_node(bm))); + interp->register_command("m2_node", command::ptr(new show_btree_node(bm))); + interp->register_command("detail_node", command::ptr(new show_btree_node(bm))); + interp->register_command("index_block", command::ptr(new show_index_block(bm))); + interp->register_command("index_node", command::ptr(new show_btree_node(bm))); interp->register_command("help", command::ptr(new help)); interp->register_command("exit", command::ptr(new exit_handler(interp))); interp->enter_main_loop(); @@ -329,10 +332,8 @@ thin_debug_cmd::run(int argc, char **argv) const struct option longopts[] = { { "help", no_argument, NULL, 'h'}, { "version", no_argument, NULL, 'V'}, - { "ignore-metadata-sm", no_argument, NULL, 1}, { NULL, no_argument, NULL, 0 } }; - bool ignore_metadata_sm = false; while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { switch(c) { @@ -343,10 +344,6 @@ thin_debug_cmd::run(int argc, char **argv) case 'V': cerr << THIN_PROVISIONING_TOOLS_VERSION << endl; return 0; - - case 1: - ignore_metadata_sm = true; - break; } } @@ -355,5 +352,5 @@ thin_debug_cmd::run(int argc, char **argv) exit(1); } - return debug_(argv[optind], ignore_metadata_sm); + return debug_(argv[optind]); }