[thin_delta] Add superblock and diff tags
This commit is contained in:
parent
182be112fa
commit
0e72f772d0
@ -6,9 +6,11 @@
|
|||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
#include "base/indented_stream.h"
|
||||||
#include "persistent-data/data-structures/btree_damage_visitor.h"
|
#include "persistent-data/data-structures/btree_damage_visitor.h"
|
||||||
#include "persistent-data/run.h"
|
#include "persistent-data/run.h"
|
||||||
#include "persistent-data/space-maps/core.h"
|
#include "persistent-data/space-maps/core.h"
|
||||||
|
#include "persistent-data/space-maps/disk.h"
|
||||||
#include "persistent-data/file_utils.h"
|
#include "persistent-data/file_utils.h"
|
||||||
#include "thin-provisioning/superblock.h"
|
#include "thin-provisioning/superblock.h"
|
||||||
#include "thin-provisioning/mapping_tree.h"
|
#include "thin-provisioning/mapping_tree.h"
|
||||||
@ -27,8 +29,11 @@ namespace local {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void usage(ostream &out) {
|
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"
|
<< "Options:\n"
|
||||||
|
<< " {--thin1, --snap1}\n"
|
||||||
|
<< " {--thin2, --snap2}\n"
|
||||||
|
<< " {-m, --metadata-snap}\n"
|
||||||
<< " {--verbose}\n"
|
<< " {--verbose}\n"
|
||||||
<< " {-h|--help}\n"
|
<< " {-h|--help}\n"
|
||||||
<< " {-V|--version}" << endl;
|
<< " {-V|--version}" << endl;
|
||||||
@ -201,7 +206,7 @@ namespace local {
|
|||||||
|
|
||||||
class diff_emitter {
|
class diff_emitter {
|
||||||
public:
|
public:
|
||||||
diff_emitter(ostream &out)
|
diff_emitter(indented_stream &out)
|
||||||
: out_(out) {
|
: out_(out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,18 +217,22 @@ namespace local {
|
|||||||
virtual void complete() = 0;
|
virtual void complete() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ostream &out() {
|
void indent() {
|
||||||
|
out_.indent();
|
||||||
|
}
|
||||||
|
|
||||||
|
indented_stream &out() {
|
||||||
return out_;
|
return out_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ostream &out_;
|
indented_stream &out_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class simple_emitter : public diff_emitter {
|
class simple_emitter : public diff_emitter {
|
||||||
public:
|
public:
|
||||||
simple_emitter(ostream &out)
|
simple_emitter(indented_stream &out)
|
||||||
: diff_emitter(out) {
|
: diff_emitter(out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +281,7 @@ namespace local {
|
|||||||
if (!current_type_)
|
if (!current_type_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
indent();
|
||||||
switch (*current_type_) {
|
switch (*current_type_) {
|
||||||
case LEFT_ONLY:
|
case LEFT_ONLY:
|
||||||
out() << "<left_only";
|
out() << "<left_only";
|
||||||
@ -300,12 +310,13 @@ namespace local {
|
|||||||
|
|
||||||
class verbose_emitter : public diff_emitter {
|
class verbose_emitter : public diff_emitter {
|
||||||
public:
|
public:
|
||||||
verbose_emitter(ostream &out)
|
verbose_emitter(indented_stream &out)
|
||||||
: diff_emitter(out) {
|
: diff_emitter(out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void left_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
|
void left_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
|
||||||
begin_block(LEFT_ONLY);
|
begin_block(LEFT_ONLY);
|
||||||
|
indent();
|
||||||
out() << "<range begin=\"" << vbegin << "\""
|
out() << "<range begin=\"" << vbegin << "\""
|
||||||
<< " data_begin=\"" << dbegin << "\""
|
<< " data_begin=\"" << dbegin << "\""
|
||||||
<< " length=\"" << len << "\"/>\n";
|
<< " length=\"" << len << "\"/>\n";
|
||||||
@ -313,6 +324,7 @@ namespace local {
|
|||||||
|
|
||||||
void right_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
|
void right_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
|
||||||
begin_block(RIGHT_ONLY);
|
begin_block(RIGHT_ONLY);
|
||||||
|
indent();
|
||||||
out() << "<range begin=\"" << vbegin << "\""
|
out() << "<range begin=\"" << vbegin << "\""
|
||||||
<< " data_begin=\"" << dbegin << "\""
|
<< " data_begin=\"" << dbegin << "\""
|
||||||
<< " length=\"" << len << "\"/>\n";
|
<< " length=\"" << len << "\"/>\n";
|
||||||
@ -320,6 +332,7 @@ namespace local {
|
|||||||
|
|
||||||
void blocks_differ(uint64_t vbegin, uint64_t left_dbegin, uint64_t right_dbegin, uint64_t len) {
|
void blocks_differ(uint64_t vbegin, uint64_t left_dbegin, uint64_t right_dbegin, uint64_t len) {
|
||||||
begin_block(DIFFER);
|
begin_block(DIFFER);
|
||||||
|
indent();
|
||||||
out() << "<range begin=\"" << vbegin << "\""
|
out() << "<range begin=\"" << vbegin << "\""
|
||||||
<< " left_data_begin=\"" << left_dbegin << "\""
|
<< " left_data_begin=\"" << left_dbegin << "\""
|
||||||
<< " right_data_begin=\"" << right_dbegin << "\""
|
<< " right_data_begin=\"" << right_dbegin << "\""
|
||||||
@ -328,6 +341,7 @@ namespace local {
|
|||||||
|
|
||||||
void blocks_same(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
|
void blocks_same(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
|
||||||
begin_block(SAME);
|
begin_block(SAME);
|
||||||
|
indent();
|
||||||
out() << "<range begin=\"" << vbegin << "\""
|
out() << "<range begin=\"" << vbegin << "\""
|
||||||
<< " data_begin=\"" << dbegin << "\""
|
<< " data_begin=\"" << dbegin << "\""
|
||||||
<< " length=\"" << len << "\"/>\n";
|
<< " length=\"" << len << "\"/>\n";
|
||||||
@ -359,6 +373,7 @@ namespace local {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void open(block_type t) {
|
void open(block_type t) {
|
||||||
|
indent();
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case LEFT_ONLY:
|
case LEFT_ONLY:
|
||||||
out() << "<left_only>\n";
|
out() << "<left_only>\n";
|
||||||
@ -376,24 +391,27 @@ namespace local {
|
|||||||
out() << "<same>\n";
|
out() << "<same>\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
out().inc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void close(block_type t) {
|
void close(block_type t) {
|
||||||
|
out().dec();
|
||||||
|
indent();
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case LEFT_ONLY:
|
case LEFT_ONLY:
|
||||||
out() << "</left_only>\n\n";
|
out() << "</left_only>\n";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RIGHT_ONLY:
|
case RIGHT_ONLY:
|
||||||
out() << "</right_only>\n\n";
|
out() << "</right_only>\n";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DIFFER:
|
case DIFFER:
|
||||||
out() << "</different>\n\n";
|
out() << "</different>\n";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SAME:
|
case SAME:
|
||||||
out() << "</same>\n\n";
|
out() << "</same>\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,16 +484,59 @@ namespace local {
|
|||||||
e.complete();
|
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) {
|
void delta_(application &app, flags const &fs) {
|
||||||
mapping_recorder mr1;
|
mapping_recorder mr1;
|
||||||
mapping_recorder mr2;
|
mapping_recorder mr2;
|
||||||
damage_visitor damage_v;
|
damage_visitor damage_v;
|
||||||
|
superblock_detail::superblock sb;
|
||||||
|
checked_space_map::ptr data_sm;
|
||||||
|
|
||||||
{
|
{
|
||||||
block_manager<>::ptr bm = open_bm(*fs.dev);
|
block_manager<>::ptr bm = open_bm(*fs.dev);
|
||||||
transaction_manager::ptr tm = open_tm(bm);
|
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_,
|
dev_tree dtree(*tm, sb.data_mapping_root_,
|
||||||
mapping_tree_detail::mtree_traits::ref_counter(tm));
|
mapping_tree_detail::mtree_traits::ref_counter(tm));
|
||||||
@ -508,13 +569,26 @@ namespace local {
|
|||||||
mr2.complete();
|
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) {
|
if (fs.verbose) {
|
||||||
verbose_emitter e(cout);
|
verbose_emitter e(is);
|
||||||
dump_diff(mr1.get_mappings(), mr2.get_mappings(), e);
|
dump_diff(mr1.get_mappings(), mr2.get_mappings(), e);
|
||||||
} else {
|
} else {
|
||||||
simple_emitter e(cout);
|
simple_emitter e(is);
|
||||||
dump_diff(mr1.get_mappings(), mr2.get_mappings(), e);
|
dump_diff(mr1.get_mappings(), mr2.get_mappings(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end_diff(is);
|
||||||
|
end_superblock(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
int delta(application &app, flags const &fs) {
|
int delta(application &app, flags const &fs) {
|
||||||
@ -541,13 +615,15 @@ int thin_delta_main(int argc, char **argv)
|
|||||||
flags fs;
|
flags fs;
|
||||||
local::application app(basename(argv[0]));
|
local::application app(basename(argv[0]));
|
||||||
|
|
||||||
char const shortopts[] = "hV";
|
char const shortopts[] = "hVm";
|
||||||
option const longopts[] = {
|
option const longopts[] = {
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "version", no_argument, NULL, 'V' },
|
{ "version", no_argument, NULL, 'V' },
|
||||||
|
{ "thin1", required_argument, NULL, 1 },
|
||||||
{ "snap1", required_argument, NULL, 1 },
|
{ "snap1", required_argument, NULL, 1 },
|
||||||
|
{ "thin2", required_argument, NULL, 2 },
|
||||||
{ "snap2", 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 }
|
{ "verbose", no_argument, NULL, 4 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -569,7 +645,7 @@ int thin_delta_main(int argc, char **argv)
|
|||||||
fs.snap2 = app.parse_snap(optarg);
|
fs.snap2 = app.parse_snap(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 'm':
|
||||||
abort();
|
abort();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user