[cache_dump, cache_restore] restore/dump cycle works
This commit is contained in:
parent
c476de1756
commit
61e90998c0
@ -23,7 +23,7 @@ GEM
|
||||
multi_test (0.0.2)
|
||||
rspec-expectations (2.14.2)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
thinp_xml (0.0.9)
|
||||
thinp_xml (0.0.10)
|
||||
ejt_command_line (= 0.0.2)
|
||||
|
||||
PLATFORMS
|
||||
|
@ -4,14 +4,24 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "version.h"
|
||||
#include "caching/metadata.h"
|
||||
#include "caching/xml_format.h"
|
||||
#include "persistent-data/file_utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace caching;
|
||||
using namespace caching::superblock_detail;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
string to_string(unsigned char const *data) {
|
||||
// FIXME: we're assuming the data is zero terminated here
|
||||
return std::string(reinterpret_cast<char const *>(data));
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
|
||||
string const STDOUT_PATH("-");
|
||||
|
||||
bool want_stdout(string const &output) {
|
||||
@ -19,16 +29,30 @@ namespace {
|
||||
}
|
||||
|
||||
int dump_(string const &dev, ostream &out) {
|
||||
block_manager<>::ptr bm = open_bm(dev, block_io<>::READ_ONLY);
|
||||
metadata::ptr md(new metadata(bm, metadata::OPEN));
|
||||
emitter::ptr e = create_xml_emitter(out);
|
||||
|
||||
superblock const &sb = md->sb_;
|
||||
e->begin_superblock(to_string(sb.uuid), sb.data_block_size, sb.cache_blocks, to_string(sb.policy_name));
|
||||
e->end_superblock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dump(string const &dev, string const &output) {
|
||||
if (want_stdout(output)) {
|
||||
try {
|
||||
if (want_stdout(output))
|
||||
return dump_(dev, cout);
|
||||
else {
|
||||
ofstream out(output.c_str());
|
||||
return dump_(dev, out);
|
||||
} else
|
||||
return dump_(dev, cout);
|
||||
}
|
||||
|
||||
} catch (std::exception &e) {
|
||||
cerr << e.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void usage(ostream &out, string const &cmd) {
|
||||
|
@ -20,7 +20,7 @@ using namespace std;
|
||||
namespace {
|
||||
int restore(string const &xml_file, string const &dev) {
|
||||
try {
|
||||
block_manager<>::ptr bm = open_bm(dev, block_io<>::READ_ONLY);
|
||||
block_manager<>::ptr bm = open_bm(dev, block_io<>::READ_WRITE);
|
||||
metadata::ptr md(new metadata(bm, metadata::CREATE));
|
||||
emitter::ptr restorer = create_restore_emitter(md);
|
||||
|
||||
|
@ -7,6 +7,11 @@
|
||||
|
||||
namespace caching {
|
||||
namespace mapping_array_detail {
|
||||
enum mapping_flags {
|
||||
M_VALID = 1,
|
||||
M_DIRTY = 2
|
||||
};
|
||||
|
||||
struct mapping {
|
||||
uint64_t oblock_;
|
||||
uint32_t flags_;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "caching/metadata.h"
|
||||
#include "caching/superblock.h"
|
||||
#include "persistent-data/space-maps/core.h"
|
||||
|
||||
using namespace caching;
|
||||
@ -27,18 +28,6 @@ namespace {
|
||||
lhs->set_count(b, rhs->get_count(b));
|
||||
}
|
||||
}
|
||||
|
||||
void init_superblock(superblock &sb) {
|
||||
#if 0
|
||||
sb.magic_ = SUPERBLOCK_MAGIC;
|
||||
sb.version_ = 1;
|
||||
sb.data_mapping_root_ = mappings_->get_root();
|
||||
sb.device_details_root_ = details_->get_root();
|
||||
sb.data_block_size_ = data_block_size;
|
||||
sb.metadata_block_size_ = MD_BLOCK_SIZE;
|
||||
sb.metadata_nr_blocks_ = tm_->get_bm()->get_nr_blocks();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
@ -46,22 +35,16 @@ namespace {
|
||||
metadata::metadata(block_manager<>::ptr bm, open_type ot)
|
||||
{
|
||||
switch (ot) {
|
||||
case OPEN:
|
||||
throw runtime_error("not implemented");
|
||||
case CREATE:
|
||||
create_metadata(bm);
|
||||
break;
|
||||
|
||||
case CREATE:
|
||||
tm_ = open_tm(bm);
|
||||
space_map::ptr core = tm_->get_sm();
|
||||
metadata_sm_ = create_metadata_sm(tm_, tm_->get_bm()->get_nr_blocks());
|
||||
copy_space_maps(metadata_sm_, core);
|
||||
tm_->set_sm(metadata_sm_);
|
||||
case OPEN:
|
||||
open_metadata(bm);
|
||||
break;
|
||||
|
||||
mappings_ = mapping_array::ptr(new mapping_array(tm_, mapping_array::ref_counter()));
|
||||
// hints_ = hint_array::ptr(new hint_array(tm_));
|
||||
|
||||
::memset(&sb_, 0, sizeof(sb_));
|
||||
init_superblock(sb_);
|
||||
default:
|
||||
throw runtime_error("unhandled open_type");
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,4 +60,42 @@ metadata::commit()
|
||||
superblock_traits::pack(sb_, *disk);
|
||||
}
|
||||
|
||||
void
|
||||
metadata::init_superblock()
|
||||
{
|
||||
#if 0
|
||||
sb_.magic_ = SUPERBLOCK_MAGIC;
|
||||
sb_.version_ = 1;
|
||||
sb_.data_mapping_root_ = mappings_->get_root();
|
||||
sb_.device_details_root_ = details_->get_root();
|
||||
sb_.data_block_size_ = data_block_size;
|
||||
sb_.metadata_block_size_ = MD_BLOCK_SIZE;
|
||||
sb_.metadata_nr_blocks_ = tm_->get_bm()->get_nr_blocks();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
metadata::create_metadata(block_manager<>::ptr bm)
|
||||
{
|
||||
tm_ = open_tm(bm);
|
||||
|
||||
::memset(&sb_, 0, sizeof(sb_));
|
||||
init_superblock();
|
||||
|
||||
space_map::ptr core = tm_->get_sm();
|
||||
metadata_sm_ = create_metadata_sm(tm_, tm_->get_bm()->get_nr_blocks());
|
||||
copy_space_maps(metadata_sm_, core);
|
||||
tm_->set_sm(metadata_sm_);
|
||||
|
||||
mappings_ = mapping_array::ptr(new mapping_array(tm_, mapping_array::ref_counter()));
|
||||
// hints_ = hint_array::ptr(new hint_array(tm_));
|
||||
}
|
||||
|
||||
void
|
||||
metadata::open_metadata(block_manager<>::ptr bm)
|
||||
{
|
||||
tm_ = open_tm(bm);
|
||||
sb_ = read_superblock(tm_->get_bm());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
@ -35,6 +35,12 @@ namespace caching {
|
||||
checked_space_map::ptr metadata_sm_;
|
||||
mapping_array::ptr mappings_;
|
||||
//hint_array::ptr hints_;
|
||||
|
||||
private:
|
||||
void init_superblock();
|
||||
|
||||
void create_metadata(block_manager<>::ptr bm);
|
||||
void open_metadata(block_manager<>::ptr bm);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
#include "caching/restore_emitter.h"
|
||||
#include "caching/superblock.h"
|
||||
#include "caching/mapping_array.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace caching;
|
||||
using namespace mapping_array_detail;
|
||||
using namespace std;
|
||||
using namespace superblock_detail;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
using namespace superblock_detail;
|
||||
|
||||
class restorer : public emitter {
|
||||
public:
|
||||
restorer(metadata::ptr md)
|
||||
@ -54,6 +55,11 @@ namespace {
|
||||
sb.read_misses = 0;
|
||||
sb.write_hits = 0;
|
||||
sb.write_misses = 0;
|
||||
|
||||
struct mapping unmapped_value;
|
||||
unmapped_value.oblock_ = 0;
|
||||
unmapped_value.flags_ = 0;
|
||||
md_->mappings_->grow(nr_cache_blocks, unmapped_value);
|
||||
}
|
||||
|
||||
virtual void end_superblock() {
|
||||
|
@ -141,8 +141,7 @@ caching::superblock_validator()
|
||||
//--------------------------------
|
||||
|
||||
superblock_detail::superblock
|
||||
caching::read_superblock(persistent_data::block_manager<>::ptr bm,
|
||||
persistent_data::block_address location)
|
||||
caching::read_superblock(block_manager<>::ptr bm, block_address location)
|
||||
{
|
||||
using namespace superblock_detail;
|
||||
|
||||
@ -160,6 +159,24 @@ caching::read_superblock(persistent_data::block_manager<>::ptr bm)
|
||||
return read_superblock(bm, SUPERBLOCK_LOCATION);
|
||||
}
|
||||
|
||||
void
|
||||
caching::write_superblock(block_manager<>::ptr bm,
|
||||
block_address location,
|
||||
superblock_detail::superblock const &sb)
|
||||
{
|
||||
using namespace superblock_detail;
|
||||
|
||||
block_manager<>::write_ref w = bm->write_lock(location, superblock_validator());
|
||||
superblock_traits::pack(sb, *reinterpret_cast<superblock_disk *>(&w.data()));
|
||||
}
|
||||
|
||||
void
|
||||
caching::write_superblock(block_manager<>::ptr bm,
|
||||
superblock_detail::superblock const &sb)
|
||||
{
|
||||
write_superblock(bm, SUPERBLOCK_LOCATION, sb);
|
||||
}
|
||||
|
||||
void
|
||||
caching::check_superblock(persistent_data::block_manager<>::ptr bm,
|
||||
superblock_detail::damage_visitor &visitor)
|
||||
|
@ -130,6 +130,13 @@ namespace caching {
|
||||
superblock_detail::superblock read_superblock(persistent_data::block_manager<>::ptr bm);
|
||||
superblock_detail::superblock read_superblock(persistent_data::block_manager<>::ptr bm,
|
||||
persistent_data::block_address location);
|
||||
|
||||
void write_superblock(persistent_data::block_manager<>::ptr bm,
|
||||
superblock_detail::superblock const &sb);
|
||||
void write_superblock(persistent_data::block_manager<>::ptr bm,
|
||||
persistent_data::block_address location,
|
||||
superblock_detail::superblock const &sb);
|
||||
|
||||
void check_superblock(persistent_data::block_manager<>::ptr bm,
|
||||
superblock_detail::damage_visitor &visitor);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ Feature: cache_dump
|
||||
No input file provided.
|
||||
"""
|
||||
|
||||
@announce
|
||||
Scenario: dump/restore is a noop
|
||||
Given valid cache metadata
|
||||
When I cache_dump
|
||||
|
@ -53,6 +53,7 @@ Feature: thin_restore
|
||||
No output file provided.
|
||||
"""
|
||||
|
||||
@announce
|
||||
Scenario: successfully restores a valid xml file
|
||||
Given a small xml file
|
||||
And an empty dev file
|
||||
|
@ -74,14 +74,14 @@ end
|
||||
|
||||
Given(/^valid cache metadata$/) do
|
||||
in_current_dir do
|
||||
system("cache_xml create --nr-cache-blocks uniform[1000-5000] --nr-mappings uniform[500-1000] > #{xml_file}")
|
||||
system("cache_xml create --nr-cache-blocks uniform[1000..5000] --nr-mappings uniform[500..1000] > #{xml_file}")
|
||||
end
|
||||
|
||||
run_simple("dd if=/dev/zero of=#{dev_file} bs=4k count=1024")
|
||||
run_simple("cache_restore -i #{xml_file} -o #{dev_file}")
|
||||
end
|
||||
|
||||
Then(/^cache dumps (\d+) and (\d+) should be identical$/) do |arg1, arg2|
|
||||
Then(/^cache dumps (\d+) and (\d+) should be identical$/) do |d1, d2|
|
||||
run_simple("diff -ub #{dump_files[d1.to_i]} #{dump_files[d2.to_i]}", true)
|
||||
end
|
||||
|
||||
|
@ -122,6 +122,8 @@ namespace thin_provisioning {
|
||||
|
||||
persistent_data::block_manager<>::validator::ptr superblock_validator();
|
||||
|
||||
// FIXME: should we put init_superblock in here too?
|
||||
|
||||
superblock_detail::superblock read_superblock(persistent_data::block_manager<>::ptr bm);
|
||||
superblock_detail::superblock read_superblock(persistent_data::block_manager<>::ptr bm, persistent_data::block_address location);
|
||||
void check_superblock(persistent_data::block_manager<>::ptr bm,
|
||||
|
Loading…
Reference in New Issue
Block a user