From 5f2c3bed690c3d5900759952a41e0c231ef7e687 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Mon, 28 Oct 2019 11:52:21 +0000 Subject: [PATCH] Add some ftests, and fixup whitespace from Nikhil's work --- Makefile.in | 2 +- .../scenario-string-constants.scm | 3 + functional-tests/thin-functional-tests.scm | 27 ++ man8/thin_dump.txt | 4 +- man8/thin_repair.txt | 4 +- man8/thin_restore.txt | 4 +- thin-provisioning/metadata.cc | 1 - thin-provisioning/metadata_dumper.cc | 260 +++++++++--------- thin-provisioning/metadata_dumper.h | 11 +- thin-provisioning/override_emitter.cc | 98 +++---- thin-provisioning/override_emitter.h | 79 +++--- thin-provisioning/restore_emitter.cc | 2 +- thin-provisioning/superblock.h | 3 +- thin-provisioning/thin_dump.cc | 71 ++--- thin-provisioning/thin_repair.cc | 141 +++++----- thin-provisioning/thin_restore.cc | 183 ++++++------ 16 files changed, 460 insertions(+), 433 deletions(-) diff --git a/Makefile.in b/Makefile.in index c3ac8e8..a623b06 100644 --- a/Makefile.in +++ b/Makefile.in @@ -101,7 +101,7 @@ SOURCE=\ thin-provisioning/metadata_checker.cc \ thin-provisioning/metadata_counter.cc \ thin-provisioning/metadata_dumper.cc \ - thin-provisioning/override_emitter.cc \ + thin-provisioning/override_emitter.cc \ thin-provisioning/pool_stream.cc \ thin-provisioning/restore_emitter.cc \ thin-provisioning/rmap_visitor.cc \ diff --git a/functional-tests/scenario-string-constants.scm b/functional-tests/scenario-string-constants.scm index bf9b86f..2a87ed9 100644 --- a/functional-tests/scenario-string-constants.scm +++ b/functional-tests/scenario-string-constants.scm @@ -46,6 +46,9 @@ Options: {-h|--help} {-i|--input} {-o|--output} + {--transaction-id} + {--data-block-size} + {--nr-data-blocks} {-q|--quiet} {-V|--version}") diff --git a/functional-tests/thin-functional-tests.scm b/functional-tests/thin-functional-tests.scm index ff86c1f..f38e15a 100644 --- a/functional-tests/thin-functional-tests.scm +++ b/functional-tests/thin-functional-tests.scm @@ -216,6 +216,33 @@ (run-ok-rcv (stdout _) (thin-restore "-i" xml "-o" md "--quiet") (assert-eof stdout))))) + (define-scenario (thin-restore override transaction-id) + "thin_restore obeys the --transaction-id override" + (with-empty-metadata (md) + (with-thin-xml (xml) + (run-ok-rcv (stdout stderr) (thin-restore "--transaction-id 2345" "-i" xml "-o" md) + (assert-eof stderr)) + (run-ok-rcv (stdout stderr) (thin-dump md) + (assert-matches ".*transaction=\"2345\"" stdout))))) + + (define-scenario (thin-restore override data-block-size) + "thin_restore obeys the --data-block-size override" + (with-empty-metadata (md) + (with-thin-xml (xml) + (run-ok-rcv (stdout stderr) (thin-restore "--data-block-size 8192" "-i" xml "-o" md) + (assert-eof stderr)) + (run-ok-rcv (stdout stderr) (thin-dump md) + (assert-matches ".*data_block_size=\"8192\"" stdout))))) + + (define-scenario (thin-restore override nr-data-blocks) + "thin_restore obeys the --nr-data-blocks override" + (with-empty-metadata (md) + (with-thin-xml (xml) + (run-ok-rcv (stdout stderr) (thin-restore "--nr-data-blocks 234500" "-i" xml "-o" md) + (assert-eof stderr)) + (run-ok-rcv (stdout stderr) (thin-dump md) + (assert-matches ".*nr_data_blocks=\"234500\"" stdout))))) + ;;;----------------------------------------------------------- ;;; thin_dump scenarios ;;;----------------------------------------------------------- diff --git a/man8/thin_dump.txt b/man8/thin_dump.txt index 177c139..cadd5c7 100644 --- a/man8/thin_dump.txt +++ b/man8/thin_dump.txt @@ -39,8 +39,8 @@ OPTIONS This option may be specified multiple times to select more than one thin device. - --transaction-id {natural} Override the transaction id given in the input xml. - --data-block-size {natural} Override the data block size given in the input xml. + --transaction-id {natural} Override the transaction id given in the input xml. + --data-block-size {natural} Override the data block size given in the input xml. --nr-data-blocks {natural} Override the nr data blocks given in the input xml. --skip-mappings Do not dump the mappings. diff --git a/man8/thin_repair.txt b/man8/thin_repair.txt index 3bba3da..96d070d 100644 --- a/man8/thin_repair.txt +++ b/man8/thin_repair.txt @@ -21,8 +21,8 @@ OPTIONS If a file is used for output, then it must be preallocated, and large enough to hold the metadata. - --transaction-id {natural} Override the transaction id given in the input xml. - --data-block-size {natural} Override the data block size given in the input xml. + --transaction-id {natural} Override the transaction id given in the input xml. + --data-block-size {natural} Override the data block size given in the input xml. --nr-data-blocks {natural} Override the nr data blocks given in the input xml. EXAMPLE diff --git a/man8/thin_restore.txt b/man8/thin_restore.txt index 45b59b9..4f9ac27 100644 --- a/man8/thin_restore.txt +++ b/man8/thin_restore.txt @@ -23,8 +23,8 @@ OPTIONS If a file is used for output, then it must be preallocated, and large enough to hold the metadata. - --transaction-id {natural} Override the transaction id given in the input xml. - --data-block-size {natural} Override the data block size given in the input xml. + --transaction-id {natural} Override the transaction id given in the input xml. + --data-block-size {natural} Override the data block size given in the input xml. --nr-data-blocks {natural} Override the nr data blocks given in the input xml. EXAMPLE diff --git a/thin-provisioning/metadata.cc b/thin-provisioning/metadata.cc index 58f0495..8efea77 100644 --- a/thin-provisioning/metadata.cc +++ b/thin-provisioning/metadata.cc @@ -33,7 +33,6 @@ using namespace base; using namespace thin_provisioning; - //---------------------------------------------------------------- namespace { diff --git a/thin-provisioning/metadata_dumper.cc b/thin-provisioning/metadata_dumper.cc index c56b94e..3fc3b30 100644 --- a/thin-provisioning/metadata_dumper.cc +++ b/thin-provisioning/metadata_dumper.cc @@ -276,20 +276,19 @@ namespace { class gatherer { public: - gatherer(block_manager<> &bm) - : bm_(bm), - referenced_(bm.get_nr_blocks(), false), - examined_(bm.get_nr_blocks(), false) { - } + gatherer(block_manager<> &bm) + : bm_(bm), + referenced_(bm.get_nr_blocks(), false), + examined_(bm.get_nr_blocks(), false) { + } - struct roots { - block_address mapping_root; - block_address detail_root; - uint32_t time; - }; - - optional + struct roots { + block_address mapping_root; + block_address detail_root; + uint32_t time; + }; + optional find_best_roots(transaction_manager &tm) { vector mapping_roots; vector device_roots; @@ -304,16 +303,16 @@ namespace { auto info = get_info(b); - if (info.valid) { - if (info.type == TOP_LEVEL) { - mapping_roots.push_back(info); - } + if (info.valid) { + if (info.type == TOP_LEVEL) { + mapping_roots.push_back(info); + } - else if (info.type == DEVICE_DETAILS) { - device_roots.push_back(info); - } - } - } + else if (info.type == DEVICE_DETAILS) { + device_roots.push_back(info); + } + } + } #if SHOW_WORKING cerr << "mapping candidates (" << mapping_roots.size() << "):\n"; @@ -332,27 +331,27 @@ namespace { cerr << "(" << p.first << ", " << p.second << ")\n"; #endif - if (pairs.size()) - return mk_roots(pairs[0]); - else - return optional(); - } + if (pairs.size()) + return mk_roots(pairs[0]); + else + return optional(); + } private: - uint32_t get_time(block_address b) const { - auto i = lookup_info(b); - return i ? i->age : 0; - } + uint32_t get_time(block_address b) const { + auto i = lookup_info(b); + return i ? i->age : 0; + } - roots mk_roots(pair const &p) { - roots r; + roots mk_roots(pair const &p) { + roots r; - r.mapping_root = p.second; - r.detail_root = p.first; - r.time = max(get_time(p.first), get_time(p.second)); + r.mapping_root = p.second; + r.detail_root = p.first; + r.time = max(get_time(p.first), get_time(p.second)); - return r; - } + return r; + } bool set_eq(set const &lhs, set const &rhs) { for (auto v : lhs) @@ -624,14 +623,13 @@ namespace { } } - optional lookup_info(block_address b) const { - auto it = infos_.find(b); - if (it == infos_.end()) - return optional(); - - return optional(it->second); - } + optional lookup_info(block_address b) const { + auto it = infos_.find(b); + if (it == infos_.end()) + return optional(); + return optional(it->second); + } block_manager<> &bm_; vector referenced_; @@ -779,102 +777,102 @@ namespace { return 0ull; } - - void - emit_trees_(block_manager<>::ptr bm, superblock_detail::superblock const &sb, + void + emit_trees_(block_manager<>::ptr bm, superblock_detail::superblock const &sb, emitter::ptr e, override_options const &ropts) - { - metadata md(bm, sb); - dump_options opts; - details_extractor de(opts); - device_tree_detail::damage_visitor::ptr dd_policy(details_damage_policy(true)); - walk_device_tree(*md.details_, de, *dd_policy); + { + metadata md(bm, sb); + dump_options opts; + details_extractor de(opts); + device_tree_detail::damage_visitor::ptr dd_policy(details_damage_policy(true)); + walk_device_tree(*md.details_, de, *dd_policy); - e->begin_superblock("", sb.time_, - sb.trans_id_, - sb.flags_, - sb.version_, - sb.data_block_size_, - get_nr_blocks(md), - boost::optional()); + e->begin_superblock("", sb.time_, + sb.trans_id_, + sb.flags_, + sb.version_, + sb.data_block_size_, + get_nr_blocks(md), + boost::optional()); - { - mapping_tree_detail::damage_visitor::ptr md_policy(mapping_damage_policy(true)); - mapping_tree_emit_visitor mte(opts, *md.tm_, e, de.get_details(), mapping_damage_policy(true)); - walk_mapping_tree(*md.mappings_top_level_, mte, *md_policy); - } + { + mapping_tree_detail::damage_visitor::ptr md_policy(mapping_damage_policy(true)); + mapping_tree_emit_visitor mte(opts, *md.tm_, e, de.get_details(), mapping_damage_policy(true)); + walk_mapping_tree(*md.mappings_top_level_, mte, *md_policy); + } - e->end_superblock(); - } + e->end_superblock(); + } - void - find_better_roots_(block_manager<>::ptr bm, superblock_detail::superblock &sb) - { - // We assume the superblock is wrong, and find the best roots - // for ourselves. We've had a few cases where people have - // activated a pool on multiple hosts at once, which results in - // the superblock being over written. - gatherer g(*bm); - auto tm = open_tm(bm, superblock_detail::SUPERBLOCK_LOCATION); - auto p = g.find_best_roots(*tm); + void + find_better_roots_(block_manager<>::ptr bm, superblock_detail::superblock &sb) + { + // We assume the superblock is wrong, and find the best roots + // for ourselves. We've had a few cases where people have + // activated a pool on multiple hosts at once, which results in + // the superblock being over written. + gatherer g(*bm); + auto tm = open_tm(bm, superblock_detail::SUPERBLOCK_LOCATION); + auto p = g.find_best_roots(*tm); - if (p) { - sb.metadata_snap_ = 0; - sb.time_ = p->time; - sb.device_details_root_ = p->detail_root; - sb.data_mapping_root_ = p->mapping_root; - sb.metadata_nr_blocks_ = bm->get_nr_blocks(); - } - } - - superblock_detail::superblock - recreate_superblock(override_options const &opts) - { - superblock_detail::superblock sb; - memset(&sb, 0, sizeof(sb)); - - // FIXME: we need to get this by walking both the mapping and device trees. - sb.time_ = 100000; + if (p) { + sb.metadata_snap_ = 0; + sb.time_ = p->time; + sb.device_details_root_ = p->detail_root; + sb.data_mapping_root_ = p->mapping_root; + sb.metadata_nr_blocks_ = bm->get_nr_blocks(); + } + } - sb.trans_id_ = opts.get_transaction_id(); - sb.version_ = superblock_detail::METADATA_VERSION; - sb.data_block_size_ = opts.get_data_block_size(); - // Check that this has been overridden. - opts.get_nr_data_blocks(); + superblock_detail::superblock + recreate_superblock(override_options const &opts) + { + superblock_detail::superblock sb; + memset(&sb, 0, sizeof(sb)); - return sb; - } + // FIXME: we need to get this by walking both the mapping and device trees. + sb.time_ = 100000; - optional - maybe_read_superblock(block_manager<>::ptr bm) - { - try { - auto sb = read_superblock(bm); - return optional(sb); - } catch (...) { - } - return optional(); - } + sb.trans_id_ = opts.get_transaction_id(); + sb.version_ = superblock_detail::METADATA_VERSION; + sb.data_block_size_ = opts.get_data_block_size(); - void - metadata_repair_(block_manager<>::ptr bm, emitter::ptr e, override_options const &opts) - { - auto msb = maybe_read_superblock(bm); - if (!msb) - msb = recreate_superblock(opts); + // Check that this has been overridden. + opts.get_nr_data_blocks(); - auto tm = open_tm(bm, superblock_detail::SUPERBLOCK_LOCATION); + return sb; + } - if (!get_dev_ids(*tm, msb->device_details_root_) || - !get_map_ids(*tm, msb->data_mapping_root_)) - find_better_roots_(bm, *msb); + optional + maybe_read_superblock(block_manager<>::ptr bm) + { + try { + auto sb = read_superblock(bm); + return optional(sb); + } catch (...) { + } - emit_trees_(bm, *msb, e, opts); - } + return optional(); + } + void + metadata_repair_(block_manager<>::ptr bm, emitter::ptr e, override_options const &opts) + { + auto msb = maybe_read_superblock(bm); + if (!msb) + msb = recreate_superblock(opts); + + auto tm = open_tm(bm, superblock_detail::SUPERBLOCK_LOCATION); + + if (!get_dev_ids(*tm, msb->device_details_root_) || + !get_map_ids(*tm, msb->data_mapping_root_)) + find_better_roots_(bm, *msb); + + emit_trees_(bm, *msb, e, opts); + } } //---------------------------------------------------------------- @@ -906,15 +904,15 @@ thin_provisioning::metadata_dump(metadata::ptr md, emitter::ptr e, dump_options void thin_provisioning::metadata_repair(block_manager<>::ptr bm, emitter::ptr e, override_options const &opts) { - try { - metadata_repair_(bm, e, opts); + try { + metadata_repair_(bm, e, opts); - } catch (override_error const &e) { - ostringstream out; - out << "The following field needs to be provided on the command line due to corruption in the superblock: " - << e.what(); - throw runtime_error(out.str()); - } + } catch (override_error const &e) { + ostringstream out; + out << "The following field needs to be provided on the command line due to corruption in the superblock: " + << e.what(); + throw runtime_error(out.str()); + } } //---------------------------------------------------------------- diff --git a/thin-provisioning/metadata_dumper.h b/thin-provisioning/metadata_dumper.h index 2de756f..f588015 100644 --- a/thin-provisioning/metadata_dumper.h +++ b/thin-provisioning/metadata_dumper.h @@ -47,8 +47,7 @@ namespace thin_provisioning { } bool skip_mappings_; - override_options overrides_; - + override_options overrides_; using dev_set = std::set; using maybe_dev_set = boost::optional; @@ -61,10 +60,10 @@ namespace thin_provisioning { // corruption encountered will cause an exception to be thrown. void metadata_dump(metadata::ptr md, emitter::ptr e, dump_options const &opts); - // We have to provide a different interface for repairing, since - // the superblock itself may be corrupt, so we wont be able - // to create the metadata object. - void metadata_repair(block_manager<>::ptr bm, emitter::ptr e, override_options const &opts); + // We have to provide a different interface for repairing, since + // the superblock itself may be corrupt, so we wont be able + // to create the metadata object. + void metadata_repair(block_manager<>::ptr bm, emitter::ptr e, override_options const &opts); // Only used by ll_restore, so we leave the repair arg void metadata_dump_subtree(metadata::ptr md, emitter::ptr e, bool repair, uint64_t subtree_root); diff --git a/thin-provisioning/override_emitter.cc b/thin-provisioning/override_emitter.cc index 554e435..9bebad3 100644 --- a/thin-provisioning/override_emitter.cc +++ b/thin-provisioning/override_emitter.cc @@ -23,72 +23,72 @@ using namespace thin_provisioning; //---------------------------------------------------------------- namespace { - class override_emitter : public emitter { - public: - override_emitter(emitter::ptr inner, override_options const &opts) - : inner_(inner), - opts_(opts) { - } + class override_emitter : public emitter { + public: + override_emitter(emitter::ptr inner, override_options const &opts) + : inner_(inner), + opts_(opts) { + } - virtual void begin_superblock(std::string const &uuid, - uint64_t time, - uint64_t trans_id, - boost::optional flags, - boost::optional version, - uint32_t data_block_size, - uint64_t nr_data_blocks, - boost::optional metadata_snap) { - inner_->begin_superblock(uuid, time, opts_.get_transaction_id(trans_id), + virtual void begin_superblock(std::string const &uuid, + uint64_t time, + uint64_t trans_id, + boost::optional flags, + boost::optional version, + uint32_t data_block_size, + uint64_t nr_data_blocks, + boost::optional metadata_snap) { + inner_->begin_superblock(uuid, time, opts_.get_transaction_id(trans_id), flags, version, opts_.get_data_block_size(data_block_size), opts_.get_nr_data_blocks(nr_data_blocks), metadata_snap); - } + } - virtual void end_superblock() { - inner_->end_superblock(); - } + virtual void end_superblock() { + inner_->end_superblock(); + } - virtual void begin_device(uint32_t dev, - uint64_t mapped_blocks, - uint64_t trans_id, - uint64_t creation_time, - uint64_t snap_time) { - inner_->begin_device(dev, mapped_blocks, trans_id, creation_time, snap_time); - } + virtual void begin_device(uint32_t dev, + uint64_t mapped_blocks, + uint64_t trans_id, + uint64_t creation_time, + uint64_t snap_time) { + inner_->begin_device(dev, mapped_blocks, trans_id, creation_time, snap_time); + } - virtual void end_device() { - inner_->end_device(); - } + virtual void end_device() { + inner_->end_device(); + } - virtual void begin_named_mapping(std::string const &name) { - inner_->begin_named_mapping(name); - } + virtual void begin_named_mapping(std::string const &name) { + inner_->begin_named_mapping(name); + } - virtual void end_named_mapping() { - inner_->end_named_mapping(); - } + virtual void end_named_mapping() { + inner_->end_named_mapping(); + } - virtual void identifier(std::string const &name) { - inner_->identifier(name); - } + virtual void identifier(std::string const &name) { + inner_->identifier(name); + } - virtual void range_map(uint64_t origin_begin, uint64_t data_begin, uint32_t time, uint64_t len) { - inner_->range_map(origin_begin, data_begin, time, len); - } + virtual void range_map(uint64_t origin_begin, uint64_t data_begin, uint32_t time, uint64_t len) { + inner_->range_map(origin_begin, data_begin, time, len); + } - virtual void single_map(uint64_t origin_block, uint64_t data_block, uint32_t time) { - inner_->single_map(origin_block, data_block, time); - } + virtual void single_map(uint64_t origin_block, uint64_t data_block, uint32_t time) { + inner_->single_map(origin_block, data_block, time); + } - private: - emitter::ptr inner_; - override_options opts_; - }; + private: + emitter::ptr inner_; + override_options opts_; + }; } emitter::ptr thin_provisioning::create_override_emitter(emitter::ptr inner, override_options const &opts) { - return emitter::ptr(new override_emitter(inner, opts)); + return emitter::ptr(new override_emitter(inner, opts)); } //---------------------------------------------------------------- diff --git a/thin-provisioning/override_emitter.h b/thin-provisioning/override_emitter.h index 0af316b..aebd7df 100644 --- a/thin-provisioning/override_emitter.h +++ b/thin-provisioning/override_emitter.h @@ -28,56 +28,57 @@ //---------------------------------------------------------------- namespace thin_provisioning { - struct override_error : public std::runtime_error { - override_error(std::string const &str) - : std::runtime_error(str) { - } - }; + struct override_error : public std::runtime_error { + override_error(std::string const &str) + : std::runtime_error(str) { + } + }; - struct override_options { - uint64_t get_transaction_id() const { - if (!transaction_id_) - bad_override_("transaction id"); + struct override_options { + uint64_t get_transaction_id() const { + if (!transaction_id_) + bad_override_("transaction id"); - return *transaction_id_; - } + return *transaction_id_; + } - uint64_t get_transaction_id(uint64_t dflt) const { - return transaction_id_ ? *transaction_id_ : dflt; - } + uint64_t get_transaction_id(uint64_t dflt) const { + return transaction_id_ ? *transaction_id_ : dflt; + } - uint32_t get_data_block_size() const { - if (!data_block_size_) - bad_override_("data block size"); + uint32_t get_data_block_size() const { + if (!data_block_size_) + bad_override_("data block size"); - return *data_block_size_; - } - uint32_t get_data_block_size(uint32_t dflt) const { - return data_block_size_ ? *data_block_size_ : dflt; - } + return *data_block_size_; + } - uint64_t get_nr_data_blocks() const { - if (!nr_data_blocks_) - bad_override_("nr data blocks"); + uint32_t get_data_block_size(uint32_t dflt) const { + return data_block_size_ ? *data_block_size_ : dflt; + } - return *nr_data_blocks_; - } + uint64_t get_nr_data_blocks() const { + if (!nr_data_blocks_) + bad_override_("nr data blocks"); - uint64_t get_nr_data_blocks(uint64_t dflt) const { - return nr_data_blocks_ ? *nr_data_blocks_ : dflt; - } + return *nr_data_blocks_; + } - boost::optional transaction_id_; - boost::optional data_block_size_; - boost::optional nr_data_blocks_; + uint64_t get_nr_data_blocks(uint64_t dflt) const { + return nr_data_blocks_ ? *nr_data_blocks_ : dflt; + } - private: - void bad_override_(std::string const &field) const { - throw override_error(field); - } - }; + boost::optional transaction_id_; + boost::optional data_block_size_; + boost::optional nr_data_blocks_; - emitter::ptr create_override_emitter(emitter::ptr inner, override_options const &opts); + private: + void bad_override_(std::string const &field) const { + throw override_error(field); + } + }; + + emitter::ptr create_override_emitter(emitter::ptr inner, override_options const &opts); } //---------------------------------------------------------------- diff --git a/thin-provisioning/restore_emitter.cc b/thin-provisioning/restore_emitter.cc index 9c76b1f..6e95a53 100644 --- a/thin-provisioning/restore_emitter.cc +++ b/thin-provisioning/restore_emitter.cc @@ -156,7 +156,7 @@ namespace { } metadata::ptr md_; - override_options opts_; + override_options opts_; bool in_superblock_; block_address nr_data_blocks_; diff --git a/thin-provisioning/superblock.h b/thin-provisioning/superblock.h index 7f6a569..4c5cc66 100644 --- a/thin-provisioning/superblock.h +++ b/thin-provisioning/superblock.h @@ -97,8 +97,7 @@ namespace thin_provisioning { block_address const SUPERBLOCK_LOCATION = 0; uint32_t const SUPERBLOCK_MAGIC = 27022010; - uint32_t const METADATA_VERSION = 2; - + uint32_t const METADATA_VERSION = 2; //-------------------------------- diff --git a/thin-provisioning/thin_dump.cc b/thin-provisioning/thin_dump.cc index 4635fe6..1b9cee2 100644 --- a/thin-provisioning/thin_dump.cc +++ b/thin-provisioning/thin_dump.cc @@ -26,6 +26,7 @@ #include "thin-provisioning/human_readable_format.h" #include "thin-provisioning/metadata.h" #include "thin-provisioning/metadata_dumper.h" +#include "thin-provisioning/override_emitter.h" #include "thin-provisioning/shared_library_emitter.h" #include "thin-provisioning/xml_format.h" #include "version.h" @@ -84,35 +85,34 @@ namespace { return e; } - int dump_(string const &path, ostream &out, struct flags &flags) { - try { - emitter::ptr inner = create_emitter(flags.format, out); - emitter::ptr e = create_override_emitter(inner, flags.opts.overrides_); + int dump_(string const &path, ostream &out, struct flags &flags) { + try { + emitter::ptr inner = create_emitter(flags.format, out); + emitter::ptr e = create_override_emitter(inner, flags.opts.overrides_); - if (flags.repair) { - auto bm = open_bm(path, block_manager<>::READ_ONLY, true); - metadata_repair(bm, e, flags.opts.overrides_); - } else { - metadata::ptr md = open_metadata(path, flags); - metadata_dump(md, e, flags.opts); - } + if (flags.repair) { + auto bm = open_bm(path, block_manager<>::READ_ONLY, true); + metadata_repair(bm, e, flags.opts.overrides_); + } else { + metadata::ptr md = open_metadata(path, flags); + metadata_dump(md, e, flags.opts); + } - } catch (std::exception &e) { - cerr << e.what() << endl; - return 1; - } + } catch (std::exception &e) { + cerr << e.what() << endl; + return 1; + } - return 0; - } - - int dump(string const &path, char const *output, struct flags &flags) { - if (output) { - ofstream out(output); - return dump_(path, out, flags); - } else - return dump_(path, cout, flags); - } + return 0; + } + int dump(string const &path, char const *output, struct flags &flags) { + if (output) { + ofstream out(output); + return dump_(path, out, flags); + } else + return dump_(path, cout, flags); + } } //---------------------------------------------------------------- @@ -156,6 +156,9 @@ thin_dump_cmd::run(int argc, char **argv) { "repair", no_argument, NULL, 'r'}, { "dev-id", required_argument, NULL, 1 }, { "skip-mappings", no_argument, NULL, 2 }, + { "transaction-id", required_argument, NULL, 3 }, + { "data-block-size", required_argument, NULL, 4 }, + { "nr-data-blocks", required_argument, NULL, 5 }, { "version", no_argument, NULL, 'V'}, { NULL, no_argument, NULL, 0 } }; @@ -207,17 +210,17 @@ thin_dump_cmd::run(int argc, char **argv) flags.opts.skip_mappings_ = true; break; - case 3: - flags.opts.overrides_.transaction_id_ = parse_uint64(optarg, "transaction id"); - break; + case 3: + flags.opts.overrides_.transaction_id_ = parse_uint64(optarg, "transaction id"); + break; - case 4: - flags.opts.overrides_.data_block_size_ = static_cast(parse_uint64(optarg, "data block size")); - break; + case 4: + flags.opts.overrides_.data_block_size_ = static_cast(parse_uint64(optarg, "data block size")); + break; - case 5: - flags.opts.overrides_.nr_data_blocks_ = parse_uint64(optarg, "nr data blocks"); - break; + case 5: + flags.opts.overrides_.nr_data_blocks_ = parse_uint64(optarg, "nr data blocks"); + break; case 'V': cout << THIN_PROVISIONING_TOOLS_VERSION << endl; diff --git a/thin-provisioning/thin_repair.cc b/thin-provisioning/thin_repair.cc index 31e4ff6..6d2e0d3 100644 --- a/thin-provisioning/thin_repair.cc +++ b/thin-provisioning/thin_repair.cc @@ -6,6 +6,7 @@ #include "base/output_file_requirements.h" #include "persistent-data/file_utils.h" #include "thin-provisioning/commands.h" +#include "thin-provisioning/override_emitter.h" #include "human_readable_format.h" #include "metadata_dumper.h" #include "metadata.h" @@ -17,28 +18,28 @@ using namespace std; using namespace thin_provisioning; namespace { - int repair(string const &old_path, string const &new_path, override_options const &opts) { - bool metadata_touched = false; - try { - // block size gets updated by the restorer - block_manager<>::ptr new_bm = open_bm(new_path, block_manager<>::READ_WRITE); - file_utils::check_file_exists(old_path, false); - metadata_touched = true; - metadata::ptr new_md(new metadata(new_bm, metadata::CREATE, 128, 0)); - emitter::ptr inner = create_restore_emitter(new_md); - emitter::ptr e = create_override_emitter(inner, opts); - block_manager<>::ptr old_bm = open_bm(old_path, block_manager<>::READ_ONLY); - metadata_repair(old_bm, e, opts); + int repair(string const &old_path, string const &new_path, override_options const &opts) { + bool metadata_touched = false; + try { + // block size gets updated by the restorer + block_manager<>::ptr new_bm = open_bm(new_path, block_manager<>::READ_WRITE); + file_utils::check_file_exists(old_path, false); + metadata_touched = true; + metadata::ptr new_md(new metadata(new_bm, metadata::CREATE, 128, 0)); + emitter::ptr inner = create_restore_emitter(new_md); + emitter::ptr e = create_override_emitter(inner, opts); + block_manager<>::ptr old_bm = open_bm(old_path, block_manager<>::READ_ONLY); + metadata_repair(old_bm, e, opts); - } catch (std::exception &e) { - if (metadata_touched) - file_utils::zero_superblock(new_path); - cerr << e.what() << endl; - return 1; - } + } catch (std::exception &e) { + if (metadata_touched) + file_utils::zero_superblock(new_path); + cerr << e.what() << endl; + return 1; + } - return 0; - } + return 0; + } } //---------------------------------------------------------------- @@ -51,15 +52,15 @@ thin_repair_cmd::thin_repair_cmd() void thin_repair_cmd::usage(std::ostream &out) const { - out << "Usage: " << get_name() << " [options] {device|file}" << endl - << "Options:" << endl - << " {-h|--help}" << endl - << " {-i|--input} " << endl - << " {-o|--output} " << endl - << " {--transaction-id} " << endl - << " {--data-block-size} " << endl - << " {--nr-data-blocks} " << endl - << " {-V|--version}" << endl; + out << "Usage: " << get_name() << " [options] {device|file}" << endl + << "Options:" << endl + << " {-h|--help}" << endl + << " {-i|--input} " << endl + << " {-o|--output} " << endl + << " {--transaction-id} " << endl + << " {--data-block-size} " << endl + << " {--nr-data-blocks} " << endl + << " {-V|--version}" << endl; } int @@ -67,56 +68,55 @@ thin_repair_cmd::run(int argc, char **argv) { int c; boost::optional input_path, output_path; - override_options opts; - + override_options opts; const char shortopts[] = "hi:o:V"; - const struct option longopts[] = { - { "help", no_argument, NULL, 'h'}, - { "input", required_argument, NULL, 'i'}, - { "output", required_argument, NULL, 'o'}, - { "transaction-id", required_argument, NULL, 1}, - { "data-block-size", required_argument, NULL, 2}, - { "nr-data-blocks", required_argument, NULL, 3}, - { "version", no_argument, NULL, 'V'}, - { NULL, no_argument, NULL, 0 } - }; + const struct option longopts[] = { + { "help", no_argument, NULL, 'h'}, + { "input", required_argument, NULL, 'i'}, + { "output", required_argument, NULL, 'o'}, + { "transaction-id", required_argument, NULL, 1}, + { "data-block-size", required_argument, NULL, 2}, + { "nr-data-blocks", required_argument, NULL, 3}, + { "version", no_argument, NULL, 'V'}, + { NULL, no_argument, NULL, 0 } + }; - while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { - switch(c) { - case 'h': - usage(cout); - return 0; + while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { + switch(c) { + case 'h': + usage(cout); + return 0; - case 'i': - input_path = optarg; - break; + case 'i': + input_path = optarg; + break; - case 'o': - output_path = optarg; - break; + case 'o': + output_path = optarg; + break; - case 1: - opts.transaction_id_ = parse_uint64(optarg, "transaction id"); - break; + case 1: + opts.transaction_id_ = parse_uint64(optarg, "transaction id"); + break; - case 2: - opts.data_block_size_ = static_cast(parse_uint64(optarg, "data block size")); - break; + case 2: + opts.data_block_size_ = static_cast(parse_uint64(optarg, "data block size")); + break; - case 3: - opts.nr_data_blocks_ = parse_uint64(optarg, "nr data blocks"); - break; + case 3: + opts.nr_data_blocks_ = parse_uint64(optarg, "nr data blocks"); + break; - case 'V': - cout << THIN_PROVISIONING_TOOLS_VERSION << endl; - return 0; + case 'V': + cout << THIN_PROVISIONING_TOOLS_VERSION << endl; + return 0; - default: - usage(cerr); - return 1; - } - } + default: + usage(cerr); + return 1; + } + } if (!input_path) { cerr << "no input file provided" << endl; @@ -133,8 +133,7 @@ thin_repair_cmd::run(int argc, char **argv) return 1; } - return repair(*input_path, *output_path, opts); - + return repair(*input_path, *output_path, opts); } //---------------------------------------------------------------- diff --git a/thin-provisioning/thin_restore.cc b/thin-provisioning/thin_restore.cc index 3441eab..6cdc6e8 100644 --- a/thin-provisioning/thin_restore.cc +++ b/thin-provisioning/thin_restore.cc @@ -45,28 +45,28 @@ using namespace thin_provisioning; //---------------------------------------------------------------- namespace { - int restore(string const &backup_file, string const &dev, bool quiet, override_options const &opts) { - bool metadata_touched = false; - try { - // The block size gets updated by the restorer. - block_manager<>::ptr bm(open_bm(dev, block_manager<>::READ_WRITE)); - file_utils::check_file_exists(backup_file); - metadata_touched = true; - metadata::ptr md(new metadata(bm, metadata::CREATE, 128, 0)); - emitter::ptr inner = create_restore_emitter(md); - emitter::ptr restorer = create_override_emitter(inner, opts); + int restore(string const &backup_file, string const &dev, bool quiet, override_options const &opts) { + bool metadata_touched = false; + try { + // The block size gets updated by the restorer. + block_manager<>::ptr bm(open_bm(dev, block_manager<>::READ_WRITE)); + file_utils::check_file_exists(backup_file); + metadata_touched = true; + metadata::ptr md(new metadata(bm, metadata::CREATE, 128, 0)); + emitter::ptr inner = create_restore_emitter(md); + emitter::ptr restorer = create_override_emitter(inner, opts); - parse_xml(backup_file, restorer, quiet); + parse_xml(backup_file, restorer, quiet); - } catch (std::exception &e) { - if (metadata_touched) - file_utils::zero_superblock(dev); - cerr << e.what() << endl; - return 1; - } + } catch (std::exception &e) { + if (metadata_touched) + file_utils::zero_superblock(dev); + cerr << e.what() << endl; + return 1; + } - return 0; - } + return 0; + } } //---------------------------------------------------------------- @@ -79,99 +79,98 @@ thin_restore_cmd::thin_restore_cmd() void thin_restore_cmd::usage(std::ostream &out) const { - out << "Usage: " << get_name() << " [options]" << endl - << "Options:" << endl - << " {-h|--help}" << endl - << " {-i|--input} " << endl - << " {-o|--output} " << endl - << " {--transaction-id} " << endl - << " {--data-block-size} " << endl - << " {--nr-data-blocks} " << endl - << " {-q|--quiet}" << endl - << " {-V|--version}" << endl; + out << "Usage: " << get_name() << " [options]" << endl + << "Options:" << endl + << " {-h|--help}" << endl + << " {-i|--input} " << endl + << " {-o|--output} " << endl + << " {--transaction-id} " << endl + << " {--data-block-size} " << endl + << " {--nr-data-blocks} " << endl + << " {-q|--quiet}" << endl + << " {-V|--version}" << endl; } int thin_restore_cmd::run(int argc, char **argv) { - int c; - const char *shortopts = "hi:o:qV"; - string input, output; - bool quiet = false; - override_options opts; + int c; + const char *shortopts = "hi:o:qV"; + string input, output; + bool quiet = false; + override_options opts; - const struct option longopts[] = { - { "help", no_argument, NULL, 'h'}, - { "input", required_argument, NULL, 'i' }, - { "output", required_argument, NULL, 'o'}, - { "transaction-id", required_argument, NULL, 1}, - { "data-block-size", required_argument, NULL, 2}, - { "nr-data-blocks", required_argument, NULL, 3}, - { "quiet", no_argument, NULL, 'q'}, - { "version", no_argument, NULL, 'V'}, - { NULL, no_argument, NULL, 0 } - }; + const struct option longopts[] = { + { "help", no_argument, NULL, 'h'}, + { "input", required_argument, NULL, 'i' }, + { "output", required_argument, NULL, 'o'}, + { "transaction-id", required_argument, NULL, 1}, + { "data-block-size", required_argument, NULL, 2}, + { "nr-data-blocks", required_argument, NULL, 3}, + { "quiet", no_argument, NULL, 'q'}, + { "version", no_argument, NULL, 'V'}, + { NULL, no_argument, NULL, 0 } + }; - while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { - switch(c) { - case 'h': - usage(cout); - return 0; + while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { + switch(c) { + case 'h': + usage(cout); + return 0; - case 'i': - input = optarg; - break; + case 'i': + input = optarg; + break; - case 'o': - output = optarg; - break; + case 'o': + output = optarg; + break; - case 1: - opts.transaction_id_ = parse_uint64(optarg, "transaction id"); - break; + case 1: + opts.transaction_id_ = parse_uint64(optarg, "transaction id"); + break; - case 2: - opts.data_block_size_ = static_cast(parse_uint64(optarg, "data block size")); - break; + case 2: + opts.data_block_size_ = static_cast(parse_uint64(optarg, "data block size")); + break; - case 3: - opts.nr_data_blocks_ = parse_uint64(optarg, "nr data blocks"); - break; + case 3: + opts.nr_data_blocks_ = parse_uint64(optarg, "nr data blocks"); + break; - case 'q': - quiet = true; - break; + case 'q': + quiet = true; + break; - case 'V': - cout << THIN_PROVISIONING_TOOLS_VERSION << endl; - return 0; + case 'V': + cout << THIN_PROVISIONING_TOOLS_VERSION << endl; + return 0; - default: - usage(cerr); - return 1; - } - } + default: + usage(cerr); + return 1; + } + } - if (argc != optind) { - usage(cerr); - return 1; - } + if (argc != optind) { + usage(cerr); + return 1; + } if (input.empty()) { - cerr << "No input file provided." << endl << endl; - usage(cerr); - return 1; - } + cerr << "No input file provided." << endl << endl; + usage(cerr); + return 1; + } - if (output.empty()) { - cerr << "No output file provided." << endl << endl; - usage(cerr); - return 1; - } else - check_output_file_requirements(output); + if (output.empty()) { + cerr << "No output file provided." << endl << endl; + usage(cerr); + return 1; + } else + check_output_file_requirements(output); - return restore(input, output, quiet, opts); + return restore(input, output, quiet, opts); } //---------------------------------------------------------------- -