From 6dc50866436fb451e542f40b6645f38b37cc2929 Mon Sep 17 00:00:00 2001 From: Ming-Hung Tsai Date: Wed, 13 Jan 2021 11:56:18 +0800 Subject: [PATCH] [thin_debug] Add commands to show space maps --- thin-provisioning/thin_debug.cc | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/thin-provisioning/thin_debug.cc b/thin-provisioning/thin_debug.cc index fa6e457..fc725e8 100644 --- a/thin-provisioning/thin_debug.cc +++ b/thin-provisioning/thin_debug.cc @@ -28,6 +28,7 @@ #include #include +#include "base/math_utils.h" #include "persistent-data/data-structures/btree.h" #include "persistent-data/data-structures/simple_traits.h" #include "persistent-data/file_utils.h" @@ -202,6 +203,8 @@ namespace { << " m1_node " << endl << " m2_node " << endl << " detail_node " << endl + << " index_block " << endl + << " index_node " << endl << " exit" << endl; } }; @@ -318,6 +321,18 @@ namespace { } }; + class index_entry_show_traits : public persistent_data::sm_disk_detail::index_entry_traits { + public: + typedef persistent_data::sm_disk_detail::index_entry_traits value_trait; + + static void show(formatter &f, string const &key, + persistent_data::sm_disk_detail::index_entry const &value) { + field(f, "blocknr", value.blocknr_); + field(f, "nr free", value.nr_free_); + field(f, "none free before", value.none_free_before_); + } + }; + template class show_btree_node : public command { public: @@ -368,6 +383,52 @@ namespace { metadata::ptr md_; }; + class show_index_block : public command { + public: + explicit show_index_block(metadata::ptr md) + : md_(md) { + } + + 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 = 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); + + sm_disk_detail::metadata_index const *mdi = + reinterpret_cast(rr.data()); + show_metadata_index(mdi, nr_indexes, out); + } + + private: + void show_metadata_index(sm_disk_detail::metadata_index const *mdi, block_address nr_indexes, ostream &out) { + xml_formatter f; + field(f, "csum", to_cpu(mdi->csum_)); + field(f, "padding", to_cpu(mdi->padding_)); + field(f, "blocknr", to_cpu(mdi->blocknr_)); + + 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); + formatter::ptr f2(new xml_formatter); + index_entry_show_traits::show(*f2, "value", ie); + f.child(lexical_cast(i), f2); + } + f.output(out, 0); + } + + unsigned const ENTRIES_PER_BLOCK = (MD_BLOCK_SIZE - sizeof(persistent_data::sm_disk_detail::bitmap_header)) * 4; + metadata::ptr md_; + }; + //-------------------------------- int debug(string const &path, bool ignore_metadata_sm) { @@ -380,6 +441,8 @@ namespace { 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("help", command::ptr(new help)); interp.register_command("exit", command::ptr(new exit_handler(interp))); interp.enter_main_loop();