thin-provisioning-tools/thin-provisioning/thin_delta.cc

708 lines
15 KiB
C++
Raw Normal View History

2014-06-09 17:56:55 +05:30
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
2014-06-09 15:07:46 +05:30
#include <getopt.h>
#include <iostream>
2014-06-09 15:18:29 +05:30
#include <libgen.h>
2014-06-09 15:07:46 +05:30
#include "version.h"
#include "base/indented_stream.h"
2020-07-27 08:18:54 +05:30
#include "base/run.h"
2014-06-10 21:08:20 +05:30
#include "persistent-data/data-structures/btree_damage_visitor.h"
#include "persistent-data/space-maps/core.h"
#include "persistent-data/space-maps/disk.h"
2014-06-10 21:08:20 +05:30
#include "persistent-data/file_utils.h"
#include "thin-provisioning/superblock.h"
#include "thin-provisioning/mapping_tree.h"
#include "thin-provisioning/metadata.h"
2014-08-27 18:31:31 +05:30
#include "thin-provisioning/commands.h"
2014-06-10 21:08:20 +05:30
2014-06-09 15:07:46 +05:30
using namespace std;
2014-06-10 21:08:20 +05:30
using namespace thin_provisioning;
2014-06-09 15:07:46 +05:30
//----------------------------------------------------------------
2014-08-27 18:31:31 +05:30
namespace local {
2014-06-09 17:56:55 +05:30
class application {
public:
application(string const &cmd)
: cmd_(cmd) {
}
void usage(ostream &out) {
out << "Usage: " << cmd_ << " [options] <device or file>\n"
2014-06-17 19:30:38 +05:30
<< "Options:\n"
<< " {--thin1, --snap1}\n"
<< " {--thin2, --snap2}\n"
<< " {-m, --metadata-snap} [block#]\n"
2014-06-17 19:30:38 +05:30
<< " {--verbose}\n"
<< " {-h|--help}\n"
2014-06-09 17:56:55 +05:30
<< " {-V|--version}" << endl;
}
void die(string const &msg) {
cerr << msg << endl;
usage(cerr);
exit(1);
}
uint64_t parse_int(string const &str, string const &desc) {
2014-06-09 17:56:55 +05:30
try {
2014-06-10 21:08:20 +05:30
return boost::lexical_cast<uint64_t>(str);
2014-06-09 17:56:55 +05:30
} catch (...) {
ostringstream out;
out << "Couldn't parse " << desc << ": '" << str << "'";
2014-06-09 17:56:55 +05:30
die(out.str());
}
return 0; // never get here
}
private:
string cmd_;
};
struct flags {
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
flags()
: verbose(false),
use_metadata_snap(false) {
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
}
bool verbose;
bool use_metadata_snap;
2014-06-09 17:56:55 +05:30
boost::optional<string> dev;
boost::optional<uint64_t> metadata_snap;
2014-06-10 21:08:20 +05:30
boost::optional<uint64_t> snap1;
boost::optional<uint64_t> snap2;
2014-06-09 17:56:55 +05:30
};
2014-06-10 21:08:20 +05:30
//--------------------------------
struct mapping {
mapping()
: vbegin_(0),
dbegin_(0),
len_(0) {
}
mapping(uint64_t vbegin, uint64_t dbegin, uint64_t len)
: vbegin_(vbegin),
dbegin_(dbegin),
len_(len) {
}
uint64_t vbegin_, dbegin_, len_;
};
ostream &operator <<(ostream &out, mapping const &m) {
out << "mapping[vbegin = " << m.vbegin_
<< ", dbegin = " << m.dbegin_
<< ", len = " << m.len_ << "]";
return out;
}
//--------------------------------
template <typename Container>
class mapping_stream {
public:
mapping_stream(Container const &c)
: it_(c.begin()),
end_(c.end()) {
m_ = *it_;
}
mapping const &get_mapping() const {
return m_;
}
bool more_mappings() const {
return it_ != end_;
}
void consume(uint64_t delta) {
if (it_ == end_)
throw runtime_error("end of stream already reached");
if (delta > m_.len_)
throw runtime_error("delta too long");
if (delta == m_.len_) {
++it_;
m_ = *it_;
} else {
m_.vbegin_ += delta;
m_.dbegin_ += delta;
m_.len_ -= delta;
}
}
private:
typename Container::const_iterator it_;
typename Container::const_iterator end_;
mapping m_;
};
//--------------------------------
typedef std::deque<mapping> mapping_deque;
// Builds up an in core rep of the mappings for a device.
class mapping_recorder {
2014-06-10 21:08:20 +05:30
public:
mapping_recorder() {
no_range();
2014-06-10 21:08:20 +05:30
}
void visit(btree_path const &path, mapping_tree_detail::block_time const &bt) {
record(path[0], bt.block_);
}
void complete() {
if (range_in_progress()) {
push_range();
no_range();
}
}
mapping_deque const &get_mappings() const {
return mappings_;
2014-06-10 21:08:20 +05:30
}
private:
void no_range() {
2014-06-10 21:08:20 +05:30
obegin_ = oend_ = 0;
dbegin_ = dend_ = 0;
}
void inc_range() {
oend_++;
dend_++;
}
2014-06-10 21:08:20 +05:30
void begin_range(uint64_t oblock, uint64_t dblock) {
obegin_ = oend_ = oblock;
dbegin_ = dend_ = dblock;
inc_range();
}
2014-06-10 21:08:20 +05:30
bool range_in_progress() {
return oend_ != obegin_;
}
2014-06-10 21:08:20 +05:30
bool continues_range(uint64_t oblock, uint64_t dblock) {
return (oblock == oend_) && (dblock == dend_);
}
2014-06-10 21:08:20 +05:30
void push_range() {
mapping m(obegin_, dbegin_, oend_ - obegin_);
mappings_.push_back(m);
2014-06-10 21:08:20 +05:30
}
void record(uint64_t oblock, uint64_t dblock) {
if (!range_in_progress())
begin_range(oblock, dblock);
else if (!continues_range(oblock, dblock)) {
push_range();
begin_range(oblock, dblock);
} else
inc_range();
}
2014-06-10 21:08:20 +05:30
uint64_t obegin_, oend_;
uint64_t dbegin_, dend_;
mapping_deque mappings_;
2014-06-10 21:08:20 +05:30
};
//--------------------------------
2014-06-10 21:08:20 +05:30
class damage_visitor {
public:
virtual void visit(btree_path const &path, btree_detail::damage const &d) {
throw std::runtime_error("damage in mapping tree, please run thin_check");
}
};
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
//--------------------------------
class diff_emitter {
public:
diff_emitter(indented_stream &out)
: out_(out) {
}
2014-06-10 21:08:20 +05:30
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
virtual void left_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) = 0;
virtual void right_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) = 0;
virtual void blocks_differ(uint64_t vbegin, uint64_t left_dbegin, uint64_t right_dbegin, uint64_t len) = 0;
virtual void blocks_same(uint64_t vbegin, uint64_t dbegin, uint64_t len) = 0;
virtual void complete() = 0;
protected:
void indent() {
out_.indent();
}
indented_stream &out() {
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
return out_;
}
private:
indented_stream &out_;
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
};
class simple_emitter : public diff_emitter {
public:
simple_emitter(indented_stream &out)
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
: diff_emitter(out) {
}
void left_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
add_range(LEFT_ONLY, vbegin, len);
}
void right_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
add_range(RIGHT_ONLY, vbegin, len);
}
void blocks_differ(uint64_t vbegin, uint64_t left_dbegin, uint64_t right_dbegin, uint64_t len) {
add_range(DIFFER, vbegin, len);
}
void blocks_same(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
add_range(SAME, vbegin, len);
}
void complete() {
if (current_type_)
emit_range();
}
private:
enum block_type {
LEFT_ONLY,
RIGHT_ONLY,
DIFFER,
SAME
};
void add_range(block_type t, uint64_t vbegin, uint64_t len) {
if (current_type_ && *current_type_ == t && vbegin == vend_) {
vend_ += len;
return;
}
emit_range();
current_type_ = t;
vbegin_ = vbegin;
vend_ = vbegin_ + len;
}
void emit_range() {
if (!current_type_)
return;
indent();
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
switch (*current_type_) {
case LEFT_ONLY:
out() << "<left_only";
break;
case RIGHT_ONLY:
out() << "<right_only";
break;
case DIFFER:
out() << "<different";
break;
case SAME:
out() << "<same";
break;
}
out() << " begin=\"" << vbegin_ << "\""
<< " length=\"" << vend_ - vbegin_ << "\"/>\n";
}
boost::optional<block_type> current_type_;
uint64_t vbegin_, vend_;
};
class verbose_emitter : public diff_emitter {
public:
verbose_emitter(indented_stream &out)
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
: diff_emitter(out) {
}
void left_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
begin_block(LEFT_ONLY);
indent();
out() << "<range begin=\"" << vbegin << "\""
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
<< " data_begin=\"" << dbegin << "\""
<< " length=\"" << len << "\"/>\n";
}
2014-06-10 21:08:20 +05:30
void right_only(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
begin_block(RIGHT_ONLY);
indent();
out() << "<range begin=\"" << vbegin << "\""
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
<< " data_begin=\"" << dbegin << "\""
<< " length=\"" << len << "\"/>\n";
}
2014-06-10 21:08:20 +05:30
void blocks_differ(uint64_t vbegin, uint64_t left_dbegin, uint64_t right_dbegin, uint64_t len) {
begin_block(DIFFER);
indent();
out() << "<range begin=\"" << vbegin << "\""
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
<< " left_data_begin=\"" << left_dbegin << "\""
<< " right_data_begin=\"" << right_dbegin << "\""
<< " length=\"" << len << "\"/>\n";
}
void blocks_same(uint64_t vbegin, uint64_t dbegin, uint64_t len) {
begin_block(SAME);
indent();
out() << "<range begin=\"" << vbegin << "\""
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
<< " data_begin=\"" << dbegin << "\""
<< " length=\"" << len << "\"/>\n";
}
2014-06-10 21:08:20 +05:30
void complete() {
if (current_type_)
close(*current_type_);
}
private:
enum block_type {
LEFT_ONLY,
RIGHT_ONLY,
DIFFER,
SAME
};
void begin_block(block_type t) {
if (!current_type_) {
current_type_ = t;
open(t);
} else if (*current_type_ != t) {
close(*current_type_);
current_type_ = t;
open(t);
}
2014-06-10 21:08:20 +05:30
}
void open(block_type t) {
indent();
switch (t) {
case LEFT_ONLY:
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
out() << "<left_only>\n";
break;
2014-06-10 21:08:20 +05:30
case RIGHT_ONLY:
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
out() << "<right_only>\n";
break;
2014-06-10 21:08:20 +05:30
case DIFFER:
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
out() << "<different>\n";
break;
case SAME:
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
out() << "<same>\n";
break;
}
out().inc();
2014-06-10 21:08:20 +05:30
}
void close(block_type t) {
out().dec();
indent();
switch (t) {
case LEFT_ONLY:
out() << "</left_only>\n";
break;
case RIGHT_ONLY:
out() << "</right_only>\n";
break;
case DIFFER:
out() << "</different>\n";
break;
case SAME:
out() << "</same>\n";
break;
}
}
2014-06-10 21:08:20 +05:30
boost::optional<block_type> current_type_;
};
//----------------------------------------------------------------
void dump_diff(mapping_deque const &left,
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
mapping_deque const &right,
diff_emitter &e) {
// We iterate through both sets of mappings in parallel
// noting any differences.
mapping_stream<mapping_deque> ls{left};
mapping_stream<mapping_deque> rs{right};
while (ls.more_mappings() && rs.more_mappings()) {
auto &lm = ls.get_mapping();
auto &rm = rs.get_mapping();
if (lm.vbegin_ < rm.vbegin_) {
auto delta = min<uint64_t>(lm.len_, rm.vbegin_ - lm.vbegin_);
e.left_only(lm.vbegin_, lm.dbegin_, delta);
ls.consume(delta);
} else if (lm.vbegin_ > rm.vbegin_) {
auto delta = min<uint64_t>(rm.len_, lm.vbegin_ - rm.vbegin_);
e.right_only(rm.vbegin_, rm.dbegin_, delta);
rs.consume(delta);
} else if (lm.dbegin_ != rm.dbegin_) {
auto delta = min<uint64_t>(lm.len_, rm.len_);
e.blocks_differ(lm.vbegin_, lm.dbegin_, rm.dbegin_, delta);
ls.consume(delta);
rs.consume(delta);
} else {
auto delta = min<uint64_t>(lm.len_, rm.len_);
e.blocks_same(lm.vbegin_, lm.dbegin_, delta);
ls.consume(delta);
rs.consume(delta);
}
}
while (ls.more_mappings()) {
auto &lm = ls.get_mapping();
e.left_only(lm.vbegin_, lm.dbegin_, lm.len_);
ls.consume(lm.len_);
}
while (rs.more_mappings()) {
auto &rm = rs.get_mapping();
e.right_only(rm.vbegin_, rm.dbegin_, rm.len_);
rs.consume(rm.len_);
}
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;
2014-06-10 21:08:20 +05:30
damage_visitor damage_v;
superblock_detail::superblock sb;
block_address nr_data_blocks = 0ull;
{
block_manager::ptr bm = open_bm(*fs.dev, block_manager::READ_ONLY, !fs.use_metadata_snap);
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<uint64_t> snap1_root = md->mappings_top_level_->lookup(k);
if (!snap1_root) {
ostringstream out;
out << "Unable to find mapping tree for snap1 (" << *fs.snap1 << ")";
app.die(out.str());
}
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<uint64_t> snap2_root = md->mappings_top_level_->lookup(k);
if (!snap2_root) {
ostringstream out;
out << "Unable to find mapping tree for snap2 (" << *fs.snap2 << ")";
app.die(out.str());
}
single_mapping_tree snap2(*md->tm_, *snap2_root,
mapping_tree_detail::block_traits::ref_counter(md->tm_->get_sm()));
btree_visit_values(snap1, mr1, damage_v);
mr1.complete();
btree_visit_values(snap2, mr2, damage_v);
mr2.complete();
if (md->data_sm_)
nr_data_blocks = md->data_sm_->get_nr_blocks();
}
indented_stream is(cout);
begin_superblock(is, "", sb.time_,
sb.trans_id_,
sb.data_block_size_,
nr_data_blocks,
sb.metadata_snap_ ?
boost::optional<block_address>(sb.metadata_snap_) :
boost::optional<block_address>());
begin_diff(is, *fs.snap1, *fs.snap2);
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
if (fs.verbose) {
verbose_emitter e(is);
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
dump_diff(mr1.get_mappings(), mr2.get_mappings(), e);
} else {
simple_emitter e(is);
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
dump_diff(mr1.get_mappings(), mr2.get_mappings(), e);
}
end_diff(is);
end_superblock(is);
2014-06-10 21:08:20 +05:30
}
int delta(application &app, flags const &fs) {
try {
delta_(app, fs);
} catch (exception const &e) {
app.die(e.what());
return 1; // never get here
}
return 0;
}
2014-06-09 15:18:29 +05:30
}
//----------------------------------------------------------------
2014-06-09 17:56:55 +05:30
// FIXME: add metadata snap switch
thin_delta_cmd::thin_delta_cmd()
: command("thin_delta")
{
}
void
thin_delta_cmd::usage(std::ostream &out) const
{
// FIXME: finish
}
int
thin_delta_cmd::run(int argc, char **argv)
2014-06-09 15:07:46 +05:30
{
2014-08-27 18:31:31 +05:30
using namespace local;
2014-06-09 15:07:46 +05:30
int c;
2014-06-09 17:56:55 +05:30
flags fs;
2014-08-27 18:31:31 +05:30
local::application app(basename(argv[0]));
2014-06-09 17:56:55 +05:30
char const shortopts[] = "hVm::";
2014-06-09 15:07:46 +05:30
option const longopts[] = {
2014-06-09 15:18:29 +05:30
{ "help", no_argument, NULL, 'h' },
2014-06-09 17:56:55 +05:30
{ "version", no_argument, NULL, 'V' },
{ "thin1", required_argument, NULL, 1 },
2014-06-09 17:56:55 +05:30
{ "snap1", required_argument, NULL, 1 },
{ "thin2", required_argument, NULL, 2 },
2014-06-09 17:56:55 +05:30
{ "snap2", required_argument, NULL, 2 },
{ "metadata-snap", optional_argument, NULL, 'm' },
{ "verbose", no_argument, NULL, 4 },
{ NULL, no_argument, NULL, 0 }
2014-06-09 15:07:46 +05:30
};
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
switch (c) {
2014-06-09 15:18:29 +05:30
case 'h':
2014-06-09 17:56:55 +05:30
app.usage(cout);
2014-06-09 15:18:29 +05:30
return 0;
2014-06-09 15:07:46 +05:30
case 'V':
cout << THIN_PROVISIONING_TOOLS_VERSION << endl;
return 0;
2014-06-09 17:56:55 +05:30
case 1:
fs.snap1 = app.parse_int(optarg, "thin id 1");
2014-06-09 17:56:55 +05:30
break;
case 2:
fs.snap2 = app.parse_int(optarg, "thin id 2");
2014-06-09 17:56:55 +05:30
break;
case 'm':
fs.use_metadata_snap = true;
if (optarg)
fs.metadata_snap = app.parse_int(optarg, "metadata snapshot block");
[thin_delta] By default output a simpler format that ignores the data locations. Most people will access the data via the thin device itself, so there's really no need to output the locations of the data on pool device. Doing this allows us to run together adjacent thin blocks (even if they are not adjacent on the pool dev). Simple format: <same begin="0" length="1"/> <different begin="1" length="4"/> <same begin="5" length="1"/> <different begin="6" length="6"/> <same begin="12" length="1"/> <different begin="13" length="9"/> <same begin="22" length="1"/> <different begin="23" length="4"/> <same begin="27" length="1"/> <different begin="28" length="3"/> <same begin="31" length="1"/> <different begin="32" length="1"/> The old format is available using the --verbose switch: <same> <range begin="0" data_begin="0" length="1"/> </same> <different> <range begin="1" left_data_begin="24576" right_data_begin="16384" length="1"/> <range begin="2" left_data_begin="24577" right_data_begin="2" length="1"/> <range begin="3" left_data_begin="24578" right_data_begin="16385" length="1"/> <range begin="4" left_data_begin="24579" right_data_begin="4" length="1"/> </different> <same> <range begin="5" data_begin="5" length="1"/> </same> <different> <range begin="6" left_data_begin="24580" right_data_begin="16386" length="1"/> <range begin="7" left_data_begin="7" right_data_begin="16387" length="1"/> <range begin="8" left_data_begin="24581" right_data_begin="8" length="1"/> <range begin="9" left_data_begin="24582" right_data_begin="16388" length="1"/> <range begin="10" left_data_begin="10" right_data_begin="16389" length="1"/> <range begin="11" left_data_begin="24583" right_data_begin="11" length="1"/> </different> <same> <range begin="12" data_begin="12" length="1"/> </same> <different> <range begin="13" left_data_begin="24584" right_data_begin="13" length="1"/> <range begin="14" left_data_begin="24585" right_data_begin="16390" length="1"/> <range begin="15" left_data_begin="24586" right_data_begin="15" length="1"/> <range begin="16" left_data_begin="16" right_data_begin="16391" length="1"/> <range begin="17" left_data_begin="24587" right_data_begin="16392" length="1"/> <range begin="18" left_data_begin="18" right_data_begin="16393" length="3"/> <range begin="21" left_data_begin="24588" right_data_begin="21" length="1"/> </different> <same> <range begin="22" data_begin="22" length="1"/> </same> <different> <range begin="23" left_data_begin="24589" right_data_begin="23" length="1"/> <range begin="24" left_data_begin="24590" right_data_begin="16396" length="1"/> <range begin="25" left_data_begin="24591" right_data_begin="25" length="1"/> <range begin="26" left_data_begin="26" right_data_begin="16397" length="1"/> </different> <same> <range begin="27" data_begin="27" length="1"/> </same> <different> <range begin="28" left_data_begin="24592" right_data_begin="28" length="2"/> <range begin="30" left_data_begin="30" right_data_begin="16398" length="1"/> </different> <same> <range begin="31" data_begin="31" length="1"/> </same> <different> <range begin="32" left_data_begin="24594" right_data_begin="32" length="1"/> </different>
2014-06-17 18:50:33 +05:30
break;
case 4:
fs.verbose = true;
break;
default:
2014-06-09 17:56:55 +05:30
app.usage(cerr);
return 1;
2014-06-09 15:07:46 +05:30
}
}
2014-06-09 17:56:55 +05:30
if (argc == optind)
app.die("No input device provided.");
else
fs.dev = argv[optind];
if (!fs.snap1)
app.die("--snap1 not specified.");
if (!fs.snap2)
app.die("--snap2 not specified.");
2014-06-10 21:08:20 +05:30
return delta(app, fs);
2014-06-09 15:07:46 +05:30
}
//----------------------------------------------------------------