[thin_delta] Add superblock and diff tags

This commit is contained in:
Joe Thornber 2015-03-25 10:09:39 +00:00
parent 182be112fa
commit 0e72f772d0

View File

@ -6,9 +6,11 @@
#include "version.h"
#include "base/indented_stream.h"
#include "persistent-data/data-structures/btree_damage_visitor.h"
#include "persistent-data/run.h"
#include "persistent-data/space-maps/core.h"
#include "persistent-data/space-maps/disk.h"
#include "persistent-data/file_utils.h"
#include "thin-provisioning/superblock.h"
#include "thin-provisioning/mapping_tree.h"
@ -27,8 +29,11 @@ namespace local {
}
void usage(ostream &out) {
out << "Usage: " << cmd_ << " [options] --snap1 <snap> --snap2 <snap> <device or file>\n"
out << "Usage: " << cmd_ << " [options] <device or file>\n"
<< "Options:\n"
<< " {--thin1, --snap1}\n"
<< " {--thin2, --snap2}\n"
<< " {-m, --metadata-snap}\n"
<< " {--verbose}\n"
<< " {-h|--help}\n"
<< " {-V|--version}" << endl;
@ -201,7 +206,7 @@ namespace local {
class diff_emitter {
public:
diff_emitter(ostream &out)
diff_emitter(indented_stream &out)
: out_(out) {
}
@ -212,18 +217,22 @@ namespace local {
virtual void complete() = 0;
protected:
ostream &out() {
void indent() {
out_.indent();
}
indented_stream &out() {
return out_;
}
private:
ostream &out_;
indented_stream &out_;
};
class simple_emitter : public diff_emitter {
public:
simple_emitter(ostream &out)
simple_emitter(indented_stream &out)
: diff_emitter(out) {
}
@ -272,6 +281,7 @@ namespace local {
if (!current_type_)
return;
indent();
switch (*current_type_) {
case LEFT_ONLY:
out() << "<left_only";
@ -300,27 +310,30 @@ namespace local {
class verbose_emitter : public diff_emitter {
public:
verbose_emitter(ostream &out)
verbose_emitter(indented_stream &out)
: diff_emitter(out) {
}
void left_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
begin_block(LEFT_ONLY);
out() << " <range begin=\"" << vbegin << "\""
indent();
out() << "<range begin=\"" << vbegin << "\""
<< " data_begin=\"" << dbegin << "\""
<< " length=\"" << len << "\"/>\n";
}
void right_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
begin_block(RIGHT_ONLY);
out() << " <range begin=\"" << vbegin << "\""
indent();
out() << "<range begin=\"" << vbegin << "\""
<< " data_begin=\"" << dbegin << "\""
<< " length=\"" << len << "\"/>\n";
}
void blocks_differ(uint64_t vbegin, uint64_t left_dbegin, uint64_t right_dbegin, uint64_t len) {
begin_block(DIFFER);
out() << " <range begin=\"" << vbegin << "\""
indent();
out() << "<range begin=\"" << vbegin << "\""
<< " left_data_begin=\"" << left_dbegin << "\""
<< " right_data_begin=\"" << right_dbegin << "\""
<< " length=\"" << len << "\"/>\n";
@ -328,7 +341,8 @@ namespace local {
void blocks_same(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
begin_block(SAME);
out() << " <range begin=\"" << vbegin << "\""
indent();
out() << "<range begin=\"" << vbegin << "\""
<< " data_begin=\"" << dbegin << "\""
<< " length=\"" << len << "\"/>\n";
}
@ -359,6 +373,7 @@ namespace local {
}
void open(block_type t) {
indent();
switch (t) {
case LEFT_ONLY:
out() << "<left_only>\n";
@ -376,24 +391,27 @@ namespace local {
out() << "<same>\n";
break;
}
out().inc();
}
void close(block_type t) {
out().dec();
indent();
switch (t) {
case LEFT_ONLY:
out() << "</left_only>\n\n";
out() << "</left_only>\n";
break;
case RIGHT_ONLY:
out() << "</right_only>\n\n";
out() << "</right_only>\n";
break;
case DIFFER:
out() << "</different>\n\n";
out() << "</different>\n";
break;
case SAME:
out() << "</same>\n\n";
out() << "</same>\n";
break;
}
@ -466,16 +484,59 @@ namespace local {
e.complete();
}
// FIXME: duplication with xml_format
void begin_superblock(indented_stream &out,
string const &uuid,
uint64_t time,
uint64_t trans_id,
uint32_t data_block_size,
uint64_t nr_data_blocks,
boost::optional<uint64_t> metadata_snap) {
out.indent();
out << "<superblock uuid=\"" << uuid << "\""
<< " time=\"" << time << "\""
<< " transaction=\"" << trans_id << "\""
<< " data_block_size=\"" << data_block_size << "\""
<< " nr_data_blocks=\"" << nr_data_blocks;
if (metadata_snap)
out << "\" metadata_snap=\"" << *metadata_snap;
out << "\">\n";
out.inc();
}
void end_superblock(indented_stream &out) {
out.dec();
out.indent();
out << "</superblock>\n";
}
void begin_diff(indented_stream &out, uint64_t snap1, uint64_t snap2) {
out.indent();
out << "<diff left=\"" << snap1 << "\" right=\"" << snap2 << "\">\n";
out.inc();
}
void end_diff(indented_stream &out) {
out.dec();
out.indent();
out << "</diff>\n";
}
void delta_(application &app, flags const &fs) {
mapping_recorder mr1;
mapping_recorder mr2;
damage_visitor damage_v;
superblock_detail::superblock sb;
checked_space_map::ptr data_sm;
{
block_manager<>::ptr bm = open_bm(*fs.dev);
transaction_manager::ptr tm = open_tm(bm);
superblock_detail::superblock sb = read_superblock(bm);
sb = read_superblock(bm);
data_sm = open_disk_sm(*tm, static_cast<void *>(&sb.data_space_map_root_));
dev_tree dtree(*tm, sb.data_mapping_root_,
mapping_tree_detail::mtree_traits::ref_counter(tm));
@ -508,13 +569,26 @@ namespace local {
mr2.complete();
}
indented_stream is(cout);
begin_superblock(is, "", sb.time_,
sb.trans_id_,
sb.data_block_size_,
data_sm->get_nr_blocks(),
sb.metadata_snap_ ?
boost::optional<block_address>(sb.metadata_snap_) :
boost::optional<block_address>());
begin_diff(is, *fs.snap1, *fs.snap2);
if (fs.verbose) {
verbose_emitter e(cout);
verbose_emitter e(is);
dump_diff(mr1.get_mappings(), mr2.get_mappings(), e);
} else {
simple_emitter e(cout);
simple_emitter e(is);
dump_diff(mr1.get_mappings(), mr2.get_mappings(), e);
}
end_diff(is);
end_superblock(is);
}
int delta(application &app, flags const &fs) {
@ -541,13 +615,15 @@ int thin_delta_main(int argc, char **argv)
flags fs;
local::application app(basename(argv[0]));
char const shortopts[] = "hV";
char const shortopts[] = "hVm";
option const longopts[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ "thin1", required_argument, NULL, 1 },
{ "snap1", required_argument, NULL, 1 },
{ "thin2", required_argument, NULL, 2 },
{ "snap2", required_argument, NULL, 2 },
{ "metadata-snap", no_argument, NULL, 3 },
{ "metadata-snap", no_argument, NULL, 'm' },
{ "verbose", no_argument, NULL, 4 }
};
@ -569,7 +645,7 @@ int thin_delta_main(int argc, char **argv)
fs.snap2 = app.parse_snap(optarg);
break;
case 3:
case 'm':
abort();
break;