From 86704deacb8b21ffdc64cd9ef1ee54d5e22ac1a1 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Tue, 9 Jun 2020 14:19:59 +0100 Subject: [PATCH] [thin_check] Add support for --metadata-snap. Not tested yet. --- .../scenario-string-constants.scm | 1 + thin-provisioning/metadata_checker.cc | 23 ++++++++++---- thin-provisioning/metadata_checker.h | 4 +-- thin-provisioning/superblock.cc | 5 ++-- thin-provisioning/superblock.h | 3 +- thin-provisioning/thin_check.cc | 30 +++++++++++++------ 6 files changed, 46 insertions(+), 20 deletions(-) diff --git a/functional-tests/scenario-string-constants.scm b/functional-tests/scenario-string-constants.scm index 88c9ab9..70ae39c 100644 --- a/functional-tests/scenario-string-constants.scm +++ b/functional-tests/scenario-string-constants.scm @@ -29,6 +29,7 @@ Options: {-q|--quiet} {-h|--help} {-V|--version} + {-m|--metadata-snap} {--override-mapping-root} {--clear-needs-check-flag} {--ignore-non-fatal-errors} diff --git a/thin-provisioning/metadata_checker.cc b/thin-provisioning/metadata_checker.cc index 21383bb..2c17caf 100644 --- a/thin-provisioning/metadata_checker.cc +++ b/thin-provisioning/metadata_checker.cc @@ -137,12 +137,13 @@ namespace { //-------------------------------- error_state examine_superblock(block_manager::ptr bm, + block_address sb_location, nested_output &out) { out << "examining superblock" << end_message(); nested_output::nest _ = out.push(); superblock_reporter sb_rep(out); - check_superblock(bm, sb_rep); + check_superblock(bm, sb_rep, sb_location); return sb_rep.get_error(); } @@ -307,18 +308,24 @@ namespace { error_state check() { error_state err = NO_ERROR; + auto sb_location = superblock_detail::SUPERBLOCK_LOCATION; - err << examine_superblock(bm_, out_); - + if (options_.use_metadata_snap_) { + superblock_detail::superblock sb = read_superblock(bm_, sb_location); + sb_location = sb.metadata_snap_; + if (sb_location == superblock_detail::SUPERBLOCK_LOCATION) + throw runtime_error("No metadata snapshot found."); + } + + err << examine_superblock(bm_, sb_location, out_); if (err == FATAL) { if (check_for_xml(bm_)) out_ << "This looks like XML. thin_check only checks the binary metadata format." << end_message(); return err; } - superblock_detail::superblock sb = read_superblock(bm_); - transaction_manager::ptr tm = - open_tm(bm_, superblock_detail::SUPERBLOCK_LOCATION); + superblock_detail::superblock sb = read_superblock(bm_, sb_location); + transaction_manager::ptr tm = open_tm(bm_, sb_location); sb.data_mapping_root_ = mapping_root(sb, options_); print_info(tm, sb, info_out_); @@ -412,6 +419,10 @@ void check_options::set_override_mapping_root(block_address b) { override_mapping_root_ = b; } +void check_options::set_metadata_snap() { + sm_opts_ = SPACE_MAP_NONE; +} + base::error_state thin_provisioning::check_metadata(block_manager::ptr bm, check_options const &check_opts, diff --git a/thin-provisioning/metadata_checker.h b/thin-provisioning/metadata_checker.h index 6f25587..1b94d7e 100644 --- a/thin-provisioning/metadata_checker.h +++ b/thin-provisioning/metadata_checker.h @@ -43,11 +43,11 @@ namespace thin_provisioning { void set_superblock_only(); void set_skip_mappings(); void set_override_mapping_root(bcache::block_address b); + void set_metadata_snap(); + bool use_metadata_snap_; data_mapping_options check_data_mappings_; - space_map_options sm_opts_; - boost::optional override_mapping_root_; }; diff --git a/thin-provisioning/superblock.cc b/thin-provisioning/superblock.cc index 7b1c493..3521f1d 100644 --- a/thin-provisioning/superblock.cc +++ b/thin-provisioning/superblock.cc @@ -194,11 +194,12 @@ namespace thin_provisioning { void check_superblock(block_manager::ptr bm, - superblock_detail::damage_visitor &visitor) { + superblock_detail::damage_visitor &visitor, + block_address sb_location) { using namespace superblock_detail; try { - bm->read_lock(SUPERBLOCK_LOCATION, superblock_validator()); + bm->read_lock(sb_location, superblock_validator()); } catch (std::exception const &e) { visitor.visit(superblock_corruption(e.what())); diff --git a/thin-provisioning/superblock.h b/thin-provisioning/superblock.h index 62bceb7..9704062 100644 --- a/thin-provisioning/superblock.h +++ b/thin-provisioning/superblock.h @@ -139,7 +139,8 @@ namespace thin_provisioning { superblock_detail::superblock const &sb); void check_superblock(persistent_data::block_manager::ptr bm, - superblock_detail::damage_visitor &visitor); + superblock_detail::damage_visitor &visitor, + persistent_data::block_address sb_location = superblock_detail::SUPERBLOCK_LOCATION); } //---------------------------------------------------------------- diff --git a/thin-provisioning/thin_check.cc b/thin-provisioning/thin_check.cc index 6b65395..c8397ed 100644 --- a/thin-provisioning/thin_check.cc +++ b/thin-provisioning/thin_check.cc @@ -109,15 +109,16 @@ thin_check_cmd::thin_check_cmd() void thin_check_cmd::usage(std::ostream &out) const { - out << "Usage: " << get_name() << " [options] {device|file}" << endl - << "Options:" << endl - << " {-q|--quiet}" << endl - << " {-h|--help}" << endl - << " {-V|--version}" << endl - << " {--override-mapping-root}" << endl - << " {--clear-needs-check-flag}" << endl - << " {--ignore-non-fatal-errors}" << endl - << " {--skip-mappings}" << endl + out << "Usage: " << get_name() << " [options] {device|file}\n" + << "Options:\n" + << " {-q|--quiet}\n" + << " {-h|--help}\n" + << " {-V|--version}\n" + << " {-m|--metadata-snap}\n" + << " {--override-mapping-root}\n" + << " {--clear-needs-check-flag}\n" + << " {--ignore-non-fatal-errors}\n" + << " {--skip-mappings}\n" << " {--super-block-only}" << endl; } @@ -132,6 +133,7 @@ thin_check_cmd::run(int argc, char **argv) { "quiet", no_argument, NULL, 'q'}, { "help", no_argument, NULL, 'h'}, { "version", no_argument, NULL, 'V'}, + { "metadata-snap", no_argument, NULL, 'm'}, { "super-block-only", no_argument, NULL, 1}, { "skip-mappings", no_argument, NULL, 2}, { "ignore-non-fatal-errors", no_argument, NULL, 3}, @@ -154,6 +156,10 @@ thin_check_cmd::run(int argc, char **argv) cout << THIN_PROVISIONING_TOOLS_VERSION << endl; return 0; + case 'm': + fs.check_opts.set_metadata_snap(); + break; + case 1: // super-block-only fs.check_opts.set_superblock_only(); @@ -185,6 +191,12 @@ thin_check_cmd::run(int argc, char **argv) } } + if (fs.clear_needs_check_flag_on_success && fs.check_opts.use_metadata_snap_) { + cerr << "--metadata-snap cannot be combined with --clear-needs-check-flag."; + usage(cerr); + exit(1); + } + if (argc == optind) { if (!fs.quiet) { cerr << "No input file provided." << endl;