From 7ceb500fc8f648c5cbf776da36a5b9c92bfa5fcc Mon Sep 17 00:00:00 2001 From: Ming-Hung Tsai Date: Tue, 20 Oct 2020 14:50:21 +0800 Subject: [PATCH] [thin_delta] Support comparing two specific subtrees --- thin-provisioning/thin_delta.cc | 67 ++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/thin-provisioning/thin_delta.cc b/thin-provisioning/thin_delta.cc index e5b368f..0eb119e 100644 --- a/thin-provisioning/thin_delta.cc +++ b/thin-provisioning/thin_delta.cc @@ -36,6 +36,8 @@ namespace { boost::optional metadata_snap; boost::optional snap1; boost::optional snap2; + boost::optional root1; + boost::optional root2; }; //-------------------------------- @@ -481,9 +483,26 @@ namespace { out << "\n"; } - void begin_diff(indented_stream &out, uint64_t snap1, uint64_t snap2) { + // FIXME: always show the blocknr? + void begin_diff(indented_stream &out, + boost::optional snap1, + boost::optional root1, + boost::optional snap2, + boost::optional root2) { out.indent(); - out << "\n"; + out << "\n"; out.inc(); } @@ -505,8 +524,12 @@ namespace { metadata::ptr md(fs.use_metadata_snap ? new metadata(bm, fs.metadata_snap) : new metadata(bm)); sb = md->sb_; - dev_tree::key k = {*fs.snap1}; - boost::optional snap1_root = md->mappings_top_level_->lookup(k); + boost::optional snap1_root; + if (fs.snap1) { + dev_tree::key k = {*fs.snap1}; + snap1_root = md->mappings_top_level_->lookup(k); + } else if (fs.root1) + snap1_root = *fs.root1; if (!snap1_root) { ostringstream out; @@ -517,8 +540,12 @@ namespace { single_mapping_tree snap1(*md->tm_, *snap1_root, mapping_tree_detail::block_traits::ref_counter(md->tm_->get_sm())); - k[0] = *fs.snap2; - boost::optional snap2_root = md->mappings_top_level_->lookup(k); + boost::optional snap2_root; + if (fs.snap2) { + dev_tree::key k = {*fs.snap2}; + snap2_root = md->mappings_top_level_->lookup(k); + } else if (fs.root2) + snap2_root = *fs.root2; if (!snap2_root) { ostringstream out; @@ -546,7 +573,7 @@ namespace { sb.metadata_snap_ ? boost::optional(sb.metadata_snap_) : boost::optional()); - begin_diff(is, *fs.snap1, *fs.snap2); + begin_diff(is, fs.snap1, fs.root1, fs.snap2, fs.root2); if (fs.verbose) { verbose_emitter e(is); @@ -586,8 +613,8 @@ thin_delta_cmd::usage(std::ostream &out) const { out << "Usage: " << get_name() << " [options] \n" << "Options:\n" - << " {--thin1, --snap1}\n" - << " {--thin2, --snap2}\n" + << " {--thin1, --snap1, --root1}\n" + << " {--thin2, --snap2, --root2}\n" << " {-m, --metadata-snap} [block#]\n" << " {--verbose}\n" << " {-h|--help}\n" @@ -610,6 +637,8 @@ thin_delta_cmd::run(int argc, char **argv) { "thin2", required_argument, NULL, 2 }, { "snap2", required_argument, NULL, 2 }, { "verbose", no_argument, NULL, 4 }, + { "root1", required_argument, NULL, 5 }, + { "root2", required_argument, NULL, 6 }, { NULL, no_argument, NULL, 0 } }; @@ -641,6 +670,14 @@ thin_delta_cmd::run(int argc, char **argv) fs.verbose = true; break; + case 5: + fs.root1 = parse_uint64(optarg, "thin root 1"); + break; + + case 6: + fs.root2 = parse_uint64(optarg, "thin root 2"); + break; + default: usage(cerr); return 1; @@ -652,11 +689,15 @@ thin_delta_cmd::run(int argc, char **argv) else fs.dev = argv[optind]; - if (!fs.snap1) - die("--snap1 not specified."); + if (!fs.snap1 && !fs.root1) + die("--snap1 or --root1 not specified."); + if (!!fs.snap1 && !!fs.root1) + die("--snap1 and --root1 are not compatible."); - if (!fs.snap2) - die("--snap2 not specified."); + if (!fs.snap2 && !fs.root2) + die("--snap2 or --root2 not specified."); + if (!!fs.snap2 && !!fs.root2) + die("--snap2 and --root2 are not compatible."); return delta(fs); }