first drop of era_restore
This commit is contained in:
parent
1d12d0ff8e
commit
283ab4ad99
36
Makefile.in
36
Makefile.in
@ -63,6 +63,7 @@ SOURCE=\
|
||||
era/writeset_tree.cc \
|
||||
era/metadata.cc \
|
||||
era/metadata_dump.cc \
|
||||
era/restore_emitter.cc \
|
||||
era/xml_format.cc \
|
||||
\
|
||||
persistent-data/checksum.cc \
|
||||
@ -447,6 +448,41 @@ era_invalidate: $(ERA_INVALIDATE_OBJECTS) era/era_invalidate.o
|
||||
@echo " [LD] $@"
|
||||
$(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS) $(LIBEXPAT)
|
||||
|
||||
ERA_RESTORE_SOURCE=\
|
||||
block-cache/block_cache.cc \
|
||||
\
|
||||
base/base64.cc \
|
||||
base/error_state.cc \
|
||||
base/endian_utils.cc \
|
||||
base/xml_utils.cc \
|
||||
\
|
||||
era/writeset_tree.cc \
|
||||
era/era_detail.cc \
|
||||
era/era_array.cc \
|
||||
era/metadata.cc \
|
||||
era/metadata_dump.cc \
|
||||
era/restore_emitter.cc \
|
||||
era/superblock.cc \
|
||||
era/xml_format.cc \
|
||||
\
|
||||
persistent-data/checksum.cc \
|
||||
persistent-data/error_set.cc \
|
||||
persistent-data/file_utils.cc \
|
||||
persistent-data/hex_dump.cc \
|
||||
persistent-data/data-structures/btree.cc \
|
||||
persistent-data/data-structures/bitset.cc \
|
||||
persistent-data/space_map.cc \
|
||||
persistent-data/space-maps/disk.cc \
|
||||
persistent-data/space-maps/recursive.cc \
|
||||
persistent-data/space-maps/careful_alloc.cc \
|
||||
persistent-data/transaction_manager.cc \
|
||||
|
||||
ERA_RESTORE_OBJECTS=$(subst .cc,.o,$(ERA_RESTORE_SOURCE))
|
||||
|
||||
era_restore: $(ERA_RESTORE_OBJECTS) era/era_restore.o
|
||||
@echo " [LD] $@"
|
||||
$(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS) $(LIBEXPAT)
|
||||
|
||||
#----------------------------------------------------------------
|
||||
|
||||
DEPEND_FILES=\
|
||||
|
@ -22,16 +22,22 @@ namespace era {
|
||||
uint64_t writeset_root;
|
||||
};
|
||||
|
||||
// FIXME: implement
|
||||
struct era_detail_ref_counter {
|
||||
era_detail_ref_counter(persistent_data::transaction_manager::ptr tm) {
|
||||
era_detail_ref_counter(persistent_data::transaction_manager::ptr tm)
|
||||
: tm_(tm) {
|
||||
}
|
||||
|
||||
void inc(persistent_data::block_address b) {
|
||||
void inc(era_detail const &d) {
|
||||
tm_->get_sm()->inc(d.writeset_root);
|
||||
}
|
||||
|
||||
void dec(persistent_data::block_address b) {
|
||||
// I don't think we ever do this in the tools
|
||||
throw std::runtime_error("not implemented");
|
||||
}
|
||||
|
||||
private:
|
||||
persistent_data::transaction_manager::ptr tm_;
|
||||
};
|
||||
|
||||
struct era_detail_traits {
|
||||
|
115
era/era_restore.cc
Normal file
115
era/era_restore.cc
Normal file
@ -0,0 +1,115 @@
|
||||
#include "version.h"
|
||||
|
||||
#include "era/metadata.h"
|
||||
#include "era/restore_emitter.h"
|
||||
#include "era/xml_format.h"
|
||||
#include "persistent-data/file_utils.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <fstream>
|
||||
#include <getopt.h>
|
||||
#include <iostream>
|
||||
#include <libgen.h>
|
||||
#include <string>
|
||||
|
||||
using namespace boost;
|
||||
using namespace caching;
|
||||
using namespace persistent_data;
|
||||
using namespace std;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
struct flags {
|
||||
optional<string> input;
|
||||
optional<string> output;
|
||||
};
|
||||
|
||||
int restore(flags const &fs) {
|
||||
try {
|
||||
block_manager<>::ptr bm = open_bm(*fs.output, block_manager<>::READ_WRITE);
|
||||
metadata::ptr md(new metadata(bm, metadata::CREATE));
|
||||
emitter::ptr restorer = create_restore_emitter(md);
|
||||
|
||||
check_file_exists(*fs.input);
|
||||
ifstream in(fs.input->c_str(), ifstream::in);
|
||||
parse_xml(in, restorer);
|
||||
|
||||
} catch (std::exception &e) {
|
||||
cerr << e.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usage(ostream &out, string const &cmd) {
|
||||
out << "Usage: " << cmd << " [options]" << endl
|
||||
<< "Options:" << endl
|
||||
<< " {-h|--help}" << endl
|
||||
<< " {-i|--input} <input xml file>" << endl
|
||||
<< " {-o|--output} <output device or file>" << endl
|
||||
<< " {-V|--version}" << endl
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
flags fs;
|
||||
char const *prog_name = basename(argv[0]);
|
||||
char const *short_opts = "hi:o:V";
|
||||
option const long_opts[] = {
|
||||
{ "help", no_argument, NULL, 'h'},
|
||||
{ "input", required_argument, NULL, 'i' },
|
||||
{ "output", required_argument, NULL, 'o'},
|
||||
{ "version", no_argument, NULL, 'V'},
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
|
||||
while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
|
||||
switch(c) {
|
||||
case 'h':
|
||||
usage(cout, prog_name);
|
||||
return 0;
|
||||
|
||||
case 'i':
|
||||
fs.input = optional<string>(string(optarg));
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
fs.output = optional<string>(string(optarg));
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
cout << THIN_PROVISIONING_TOOLS_VERSION << endl;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
usage(cerr, prog_name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc != optind) {
|
||||
usage(cerr, prog_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!fs.input) {
|
||||
cerr << "No input file provided." << endl << endl;
|
||||
usage(cerr, prog_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!fs.output) {
|
||||
cerr << "No output file provided." << endl << endl;
|
||||
usage(cerr, prog_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return restore(fs);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
@ -53,4 +53,38 @@ metadata::open_metadata(block_manager<>::ptr bm, block_address loc)
|
||||
sb_.nr_blocks));
|
||||
}
|
||||
|
||||
void
|
||||
metadata::commit()
|
||||
{
|
||||
commit_space_map();
|
||||
commit_writesets();
|
||||
commit_era_array();
|
||||
commit_superblock();
|
||||
}
|
||||
|
||||
void
|
||||
metadata::commit_space_map()
|
||||
{
|
||||
metadata_sm_->commit();
|
||||
metadata_sm_->copy_root(&sb_.metadata_space_map_root, sizeof(sb_.metadata_space_map_root));
|
||||
}
|
||||
|
||||
void
|
||||
metadata::commit_writesets()
|
||||
{
|
||||
sb_.writeset_tree_root = writeset_tree_->get_root();
|
||||
}
|
||||
|
||||
void
|
||||
metadata::commit_era_array()
|
||||
{
|
||||
sb_.era_array_root = era_array_->get_root();
|
||||
}
|
||||
|
||||
void
|
||||
metadata::commit_superblock()
|
||||
{
|
||||
write_superblock(tm_->get_bm(), sb_);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
@ -29,7 +29,7 @@ namespace era {
|
||||
|
||||
metadata(block_manager<>::ptr bm, open_type ot);
|
||||
metadata(block_manager<>::ptr bm, block_address metadata_snap);
|
||||
void commit(bool clean_shutdown = true);
|
||||
void commit();
|
||||
|
||||
typedef persistent_data::transaction_manager tm;
|
||||
tm::ptr tm_;
|
||||
@ -41,6 +41,11 @@ namespace era {
|
||||
private:
|
||||
void open_metadata(block_manager<>::ptr bm,
|
||||
block_address loc = SUPERBLOCK_LOCATION);
|
||||
|
||||
void commit_space_map();
|
||||
void commit_writesets();
|
||||
void commit_era_array();
|
||||
void commit_superblock();
|
||||
};
|
||||
};
|
||||
|
||||
|
107
era/restore_emitter.cc
Normal file
107
era/restore_emitter.cc
Normal file
@ -0,0 +1,107 @@
|
||||
#include "era/restore_emitter.h"
|
||||
|
||||
#include "era/superblock.h"
|
||||
|
||||
using namespace era;
|
||||
using namespace persistent_data;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
class restorer : public emitter {
|
||||
public:
|
||||
restorer(metadata &md)
|
||||
: md_(md),
|
||||
in_superblock_(false),
|
||||
in_writeset_(false),
|
||||
in_era_array_(false) {
|
||||
}
|
||||
|
||||
virtual void begin_superblock(std::string const &uuid,
|
||||
uint32_t data_block_size,
|
||||
pd::block_address nr_blocks,
|
||||
uint32_t current_era) {
|
||||
superblock &sb = md_.sb_;
|
||||
memcpy(sb.uuid, reinterpret_cast<__u8 const *>(uuid.c_str()),
|
||||
min<size_t>(sizeof(sb.uuid), uuid.length()));
|
||||
sb.data_block_size = data_block_size;
|
||||
sb.nr_blocks = nr_blocks;
|
||||
sb.current_era = current_era;
|
||||
|
||||
nr_blocks = nr_blocks;
|
||||
}
|
||||
|
||||
virtual void end_superblock() {
|
||||
if (!in_superblock_)
|
||||
throw runtime_error("missing superblock");
|
||||
|
||||
md_.commit();
|
||||
}
|
||||
|
||||
virtual void begin_writeset(uint32_t era, uint32_t nr_bits) {
|
||||
if (!in_superblock_)
|
||||
throw runtime_error("missing superblock");
|
||||
|
||||
in_writeset_ = true;
|
||||
era_ = era;
|
||||
|
||||
bits_.reset(new bitset(md_.tm_));
|
||||
bits_->grow(nr_bits, false);
|
||||
}
|
||||
|
||||
virtual void writeset_bit(uint32_t bit, bool value) {
|
||||
bits_->set(bit, value);
|
||||
}
|
||||
|
||||
virtual void end_writeset() {
|
||||
in_writeset_ = false;
|
||||
|
||||
era_detail e;
|
||||
e.nr_bits = bits_->get_nr_bits();
|
||||
e.writeset_root = bits_->get_root();
|
||||
|
||||
uint64_t key[1] = {era_};
|
||||
md_.writeset_tree_->insert(key, e);
|
||||
}
|
||||
|
||||
virtual void begin_era_array() {
|
||||
if (!in_superblock_)
|
||||
throw runtime_error("missing superblock");
|
||||
|
||||
in_era_array_ = true;
|
||||
}
|
||||
|
||||
virtual void era(pd::block_address block, uint32_t era) {
|
||||
if (!in_era_array_)
|
||||
throw runtime_error("missing era array");
|
||||
|
||||
md_.era_array_->set(block, era);
|
||||
}
|
||||
|
||||
virtual void end_era_array() {
|
||||
in_era_array_ = false;
|
||||
}
|
||||
|
||||
private:
|
||||
metadata &md_;
|
||||
|
||||
bool in_superblock_;
|
||||
|
||||
bool in_writeset_;
|
||||
uint32_t era_;
|
||||
pd::bitset::ptr bits_;
|
||||
|
||||
bool in_era_array_;
|
||||
uint32_t nr_blocks_;
|
||||
};
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
emitter::ptr
|
||||
era::create_restore_emitter(metadata &md)
|
||||
{
|
||||
return emitter::ptr(new restorer(md));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
15
era/restore_emitter.h
Normal file
15
era/restore_emitter.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef ERA_RESTORE_EMITTER_H
|
||||
#define ERA_RESTORE_EMITTER_H
|
||||
|
||||
#include "era/emitter.h"
|
||||
#include "era/metadata.h"
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace era {
|
||||
emitter::ptr create_restore_emitter(metadata &md);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
#ifndef ERA_SUPERBLOCK_H
|
||||
#define ERA_SUPERBLOCK_h
|
||||
#define ERA_SUPERBLOCK_H
|
||||
|
||||
#include "persistent-data/block.h"
|
||||
#include "era/era_detail.h"
|
||||
|
Loading…
Reference in New Issue
Block a user