[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)
|
multi_test (0.0.2)
|
||||||
rspec-expectations (2.14.2)
|
rspec-expectations (2.14.2)
|
||||||
diff-lcs (>= 1.1.3, < 2.0)
|
diff-lcs (>= 1.1.3, < 2.0)
|
||||||
thinp_xml (0.0.9)
|
thinp_xml (0.0.10)
|
||||||
ejt_command_line (= 0.0.2)
|
ejt_command_line (= 0.0.2)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
|
@ -4,14 +4,24 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
#include "caching/metadata.h"
|
||||||
#include "caching/xml_format.h"
|
#include "caching/xml_format.h"
|
||||||
|
#include "persistent-data/file_utils.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace caching;
|
using namespace caching;
|
||||||
|
using namespace caching::superblock_detail;
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
namespace {
|
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("-");
|
string const STDOUT_PATH("-");
|
||||||
|
|
||||||
bool want_stdout(string const &output) {
|
bool want_stdout(string const &output) {
|
||||||
@ -19,16 +29,30 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int dump_(string const &dev, ostream &out) {
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dump(string const &dev, string const &output) {
|
int dump(string const &dev, string const &output) {
|
||||||
if (want_stdout(output)) {
|
try {
|
||||||
ofstream out(output.c_str());
|
if (want_stdout(output))
|
||||||
return dump_(dev, out);
|
return dump_(dev, cout);
|
||||||
} else
|
else {
|
||||||
return dump_(dev, cout);
|
ofstream out(output.c_str());
|
||||||
|
return dump_(dev, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
cerr << e.what() << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usage(ostream &out, string const &cmd) {
|
void usage(ostream &out, string const &cmd) {
|
||||||
|
@ -20,7 +20,7 @@ using namespace std;
|
|||||||
namespace {
|
namespace {
|
||||||
int restore(string const &xml_file, string const &dev) {
|
int restore(string const &xml_file, string const &dev) {
|
||||||
try {
|
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));
|
metadata::ptr md(new metadata(bm, metadata::CREATE));
|
||||||
emitter::ptr restorer = create_restore_emitter(md);
|
emitter::ptr restorer = create_restore_emitter(md);
|
||||||
|
|
||||||
|
@ -7,6 +7,11 @@
|
|||||||
|
|
||||||
namespace caching {
|
namespace caching {
|
||||||
namespace mapping_array_detail {
|
namespace mapping_array_detail {
|
||||||
|
enum mapping_flags {
|
||||||
|
M_VALID = 1,
|
||||||
|
M_DIRTY = 2
|
||||||
|
};
|
||||||
|
|
||||||
struct mapping {
|
struct mapping {
|
||||||
uint64_t oblock_;
|
uint64_t oblock_;
|
||||||
uint32_t flags_;
|
uint32_t flags_;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "caching/metadata.h"
|
#include "caching/metadata.h"
|
||||||
|
#include "caching/superblock.h"
|
||||||
#include "persistent-data/space-maps/core.h"
|
#include "persistent-data/space-maps/core.h"
|
||||||
|
|
||||||
using namespace caching;
|
using namespace caching;
|
||||||
@ -27,18 +28,6 @@ namespace {
|
|||||||
lhs->set_count(b, rhs->get_count(b));
|
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)
|
metadata::metadata(block_manager<>::ptr bm, open_type ot)
|
||||||
{
|
{
|
||||||
switch (ot) {
|
switch (ot) {
|
||||||
case OPEN:
|
case CREATE:
|
||||||
throw runtime_error("not implemented");
|
create_metadata(bm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREATE:
|
case OPEN:
|
||||||
tm_ = open_tm(bm);
|
open_metadata(bm);
|
||||||
space_map::ptr core = tm_->get_sm();
|
break;
|
||||||
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()));
|
default:
|
||||||
// hints_ = hint_array::ptr(new hint_array(tm_));
|
throw runtime_error("unhandled open_type");
|
||||||
|
|
||||||
::memset(&sb_, 0, sizeof(sb_));
|
|
||||||
init_superblock(sb_);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,4 +60,42 @@ metadata::commit()
|
|||||||
superblock_traits::pack(sb_, *disk);
|
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_;
|
checked_space_map::ptr metadata_sm_;
|
||||||
mapping_array::ptr mappings_;
|
mapping_array::ptr mappings_;
|
||||||
//hint_array::ptr hints_;
|
//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/restore_emitter.h"
|
||||||
#include "caching/superblock.h"
|
#include "caching/superblock.h"
|
||||||
|
#include "caching/mapping_array.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace caching;
|
using namespace caching;
|
||||||
|
using namespace mapping_array_detail;
|
||||||
|
using namespace std;
|
||||||
|
using namespace superblock_detail;
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
using namespace superblock_detail;
|
|
||||||
|
|
||||||
class restorer : public emitter {
|
class restorer : public emitter {
|
||||||
public:
|
public:
|
||||||
restorer(metadata::ptr md)
|
restorer(metadata::ptr md)
|
||||||
@ -54,6 +55,11 @@ namespace {
|
|||||||
sb.read_misses = 0;
|
sb.read_misses = 0;
|
||||||
sb.write_hits = 0;
|
sb.write_hits = 0;
|
||||||
sb.write_misses = 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() {
|
virtual void end_superblock() {
|
||||||
|
@ -141,8 +141,7 @@ caching::superblock_validator()
|
|||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
|
||||||
superblock_detail::superblock
|
superblock_detail::superblock
|
||||||
caching::read_superblock(persistent_data::block_manager<>::ptr bm,
|
caching::read_superblock(block_manager<>::ptr bm, block_address location)
|
||||||
persistent_data::block_address location)
|
|
||||||
{
|
{
|
||||||
using namespace superblock_detail;
|
using namespace superblock_detail;
|
||||||
|
|
||||||
@ -160,6 +159,24 @@ caching::read_superblock(persistent_data::block_manager<>::ptr bm)
|
|||||||
return read_superblock(bm, SUPERBLOCK_LOCATION);
|
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
|
void
|
||||||
caching::check_superblock(persistent_data::block_manager<>::ptr bm,
|
caching::check_superblock(persistent_data::block_manager<>::ptr bm,
|
||||||
superblock_detail::damage_visitor &visitor)
|
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);
|
||||||
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);
|
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,
|
void check_superblock(persistent_data::block_manager<>::ptr bm,
|
||||||
superblock_detail::damage_visitor &visitor);
|
superblock_detail::damage_visitor &visitor);
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ Feature: cache_dump
|
|||||||
No input file provided.
|
No input file provided.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@announce
|
||||||
Scenario: dump/restore is a noop
|
Scenario: dump/restore is a noop
|
||||||
Given valid cache metadata
|
Given valid cache metadata
|
||||||
When I cache_dump
|
When I cache_dump
|
||||||
|
@ -53,6 +53,7 @@ Feature: thin_restore
|
|||||||
No output file provided.
|
No output file provided.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@announce
|
||||||
Scenario: successfully restores a valid xml file
|
Scenario: successfully restores a valid xml file
|
||||||
Given a small xml file
|
Given a small xml file
|
||||||
And an empty dev file
|
And an empty dev file
|
||||||
|
@ -74,14 +74,14 @@ end
|
|||||||
|
|
||||||
Given(/^valid cache metadata$/) do
|
Given(/^valid cache metadata$/) do
|
||||||
in_current_dir 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
|
end
|
||||||
|
|
||||||
run_simple("dd if=/dev/zero of=#{dev_file} bs=4k count=1024")
|
run_simple("dd if=/dev/zero of=#{dev_file} bs=4k count=1024")
|
||||||
run_simple("cache_restore -i #{xml_file} -o #{dev_file}")
|
run_simple("cache_restore -i #{xml_file} -o #{dev_file}")
|
||||||
end
|
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)
|
run_simple("diff -ub #{dump_files[d1.to_i]} #{dump_files[d2.to_i]}", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -122,6 +122,8 @@ namespace thin_provisioning {
|
|||||||
|
|
||||||
persistent_data::block_manager<>::validator::ptr superblock_validator();
|
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);
|
||||||
superblock_detail::superblock read_superblock(persistent_data::block_manager<>::ptr bm, persistent_data::block_address location);
|
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,
|
void check_superblock(persistent_data::block_manager<>::ptr bm,
|
||||||
|
Loading…
Reference in New Issue
Block a user