device_tree

This commit is contained in:
Joe Thornber 2013-05-20 16:09:13 +01:00
parent 1ee8afd814
commit fcb617f858
11 changed files with 122 additions and 129 deletions

View File

@ -48,7 +48,7 @@ SOURCE=\
\ \
cache/metadata_disk_structures.cc \ cache/metadata_disk_structures.cc \
\ \
thin-provisioning/device_checker.cc \ thin-provisioning/device_tree.cc \
thin-provisioning/file_utils.cc \ thin-provisioning/file_utils.cc \
thin-provisioning/human_readable_format.cc \ thin-provisioning/human_readable_format.cc \
thin-provisioning/metadata.cc \ thin-provisioning/metadata.cc \

View File

@ -7,7 +7,6 @@
//---------------------------------------------------------------- //----------------------------------------------------------------
namespace persistent_data { namespace persistent_data {
namespace btree_detail { namespace btree_detail {
struct damage { struct damage {
typedef boost::shared_ptr<damage> ptr; typedef boost::shared_ptr<damage> ptr;

View File

@ -1,96 +0,0 @@
#include "thin-provisioning/device_checker.h"
#include "persistent-data/data-structures/btree_checker.h"
#include "persistent-data/transaction_manager.h"
#include "persistent-data/space-maps/core.h"
#include "thin-provisioning/metadata.h"
#include "thin-provisioning/metadata_disk_structures.h"
using namespace persistent_data;
using namespace thin_provisioning;
//----------------------------------------------------------------
namespace {
// FIXME: duplication with metadata.cc
transaction_manager::ptr
open_core_tm(block_manager<>::ptr bm) {
space_map::ptr sm(new core_map(bm->get_nr_blocks()));
sm->inc(SUPERBLOCK_LOCATION);
transaction_manager::ptr tm(new transaction_manager(bm, sm));
return tm;
}
class device_visitor : public btree<1, device_details_traits>::visitor {
public:
typedef boost::shared_ptr<device_visitor> ptr;
typedef btree_checker<1, device_details_traits> checker;
device_visitor(block_counter &counter)
: checker_(counter) {
}
bool visit_internal(node_location const &loc,
btree_detail::node_ref<uint64_traits> const &n) {
return checker_.visit_internal(loc, n);
}
bool visit_internal_leaf(node_location const &loc,
btree_detail::node_ref<uint64_traits> const &n) {
return checker_.visit_internal_leaf(loc, n);
}
bool visit_leaf(node_location const &loc,
btree_detail::node_ref<device_details_traits> const &n) {
if (!checker_.visit_leaf(loc, n))
return false;
for (unsigned i = 0; i < n.get_nr_entries(); i++)
devices_.insert(n.key_at(i));
return true;
}
set<uint64_t> const &get_devices() const {
return devices_;
}
private:
checker checker_;
set<uint64_t> devices_;
};
}
//----------------------------------------------------------------
device_checker::device_checker(block_manager::ptr bm,
block_address root)
: checker(bm),
root_(root)
{
}
damage_list_ptr
device_checker::check()
{
block_counter counter;
device_visitor v(counter);
transaction_manager::ptr tm(open_core_tm(bm_));
detail_tree::ptr details(new detail_tree(tm, root_,
device_details_traits::ref_counter()));
damage_list_ptr damage(new damage_list);
try {
details->visit_depth_first(v);
} catch (std::exception const &e) {
metadata_damage::ptr d(new missing_device_details(range64()));
damage->push_back(d);
}
return damage;
}
//----------------------------------------------------------------

View File

@ -1,21 +0,0 @@
#ifndef THIN_DEVICE_CHECKER_H
#define THIN_DEVICE_CHECKER_H
#include "thin-provisioning/metadata_checker.h"
//----------------------------------------------------------------
namespace thin_provisioning {
class device_checker : public checker {
public:
device_checker(block_manager::ptr bm, block_address btree_root);
damage_list_ptr check();
private:
block_address root_;
};
}
//----------------------------------------------------------------
#endif

View File

@ -0,0 +1,61 @@
#include "thin-provisioning/device_tree.h"
#include "persistent-data/data-structures/btree_damage_visitor.h"
#include "persistent-data/transaction_manager.h"
#include "persistent-data/space-maps/core.h"
#include "thin-provisioning/metadata.h"
#include "thin-provisioning/metadata_disk_structures.h"
using namespace persistent_data;
using namespace thin_provisioning;
//----------------------------------------------------------------
namespace {
using namespace device_tree_detail;
// No op for now, should add sanity checks in here however.
struct leaf_visitor {
virtual void visit(btree_path const &path, device_details const &dd) {
}
};
class ll_damage_visitor {
public:
ll_damage_visitor(device_tree_detail::damage_visitor &v)
: v_(v) {
}
virtual void visit(btree_path const &path, btree_detail::damage const &d) {
v_.visit(path, missing_devices(d.desc_, d.lost_keys_));
}
private:
device_tree_detail::damage_visitor &v_;
};
}
namespace thin_provisioning {
namespace device_tree_detail {
missing_devices::missing_devices(std::string const &desc,
range<uint64_t> const &keys)
: desc_(desc),
keys_(keys) {
}
void missing_devices::visit(damage_visitor &v) const {
v.visit(*this);
}
}
void check_device_tree(device_tree const &tree, damage_visitor &visitor)
{
block_counter counter; // FIXME: get rid of this counter arg
leaf_visitor vv;
ll_damage_visitor dv(visitor);
btree_visit_values(tree, counter, vv, dv);
}
}
//----------------------------------------------------------------

View File

@ -0,0 +1,51 @@
#ifndef THIN_DEVICE_CHECKER_H
#define THIN_DEVICE_CHECKER_H
#include "persistent-data/data-structures/btree.h"
#include "persistent-data/range.h"
#include "thin-provisioning/metadata_disk_structures.h"
//----------------------------------------------------------------
namespace thin_provisioning {
typedef persistent_data::btree<1, device_details_traits> device_tree;
namespace device_tree_detail {
class damage_visitor;
struct damage {
virtual ~damage() {}
virtual void visit(damage_visitor &v) const = 0;
};
struct missing_devices : public damage {
missing_devices(std::string const &desc, range<uint64_t> const &keys);
virtual void visit(damage_visitor &v) const;
std::string desc_;
range<uint64_t> keys_;
};
class damage_visitor {
public:
virtual ~damage_visitor() {}
void visit(damage const &d) {
d.visit(*this);
}
virtual void visit(btree_path const &path, missing_devices const &d) = 0;
};
// FIXME: need to add some more damage types for bad leaf data
};
void check_device_tree(device_tree const &tree,
device_tree_detail::damage_visitor &visitor);
}
//----------------------------------------------------------------
#endif

View File

@ -16,6 +16,7 @@
// with thin-provisioning-tools. If not, see // with thin-provisioning-tools. If not, see
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
#include "thin-provisioning/device_tree.h"
#include "thin-provisioning/file_utils.h" #include "thin-provisioning/file_utils.h"
#include "thin-provisioning/metadata.h" #include "thin-provisioning/metadata.h"
#include "thin-provisioning/superblock_validator.h" #include "thin-provisioning/superblock_validator.h"
@ -106,7 +107,7 @@ metadata::metadata(std::string const &dev_path, open_type ot,
tm_->set_sm(metadata_sm_); tm_->set_sm(metadata_sm_);
data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_)); data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_));
details_ = detail_tree::ptr(new detail_tree(tm_, sb_.device_details_root_, device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_details_traits::ref_counter()));
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_, mtree_ref_counter(tm_))); mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_, mtree_ref_counter(tm_)));
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_))); mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_)));
break; break;
@ -119,7 +120,7 @@ metadata::metadata(std::string const &dev_path, open_type ot,
tm_->set_sm(metadata_sm_); tm_->set_sm(metadata_sm_);
data_sm_ = create_disk_sm(tm_, nr_data_blocks); data_sm_ = create_disk_sm(tm_, nr_data_blocks);
details_ = detail_tree::ptr(new detail_tree(tm_, device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(tm_, device_details_traits::ref_counter()));
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, block_time_ref_counter(data_sm_))); mappings_ = mapping_tree::ptr(new mapping_tree(tm_, block_time_ref_counter(data_sm_)));
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(), mtree_ref_counter(tm_))); mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(), mtree_ref_counter(tm_)));
@ -145,7 +146,7 @@ metadata::metadata(std::string const &dev_path, block_address metadata_snap)
tm_->set_sm(metadata_sm_); tm_->set_sm(metadata_sm_);
data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_)); data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_));
details_ = detail_tree::ptr(new detail_tree(tm_, sb_.device_details_root_, device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_details_traits::ref_counter()));
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_, mtree_ref_counter(tm_))); mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_, mtree_ref_counter(tm_)));
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_))); mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_)));
} }
@ -167,7 +168,7 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot,
tm_->set_sm(metadata_sm_); tm_->set_sm(metadata_sm_);
data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_)); data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_));
details_ = detail_tree::ptr(new detail_tree(tm_, sb_.device_details_root_, device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_details_traits::ref_counter()));
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_, mtree_ref_counter(tm_))); mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_, mtree_ref_counter(tm_)));
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_))); mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_)));
break; break;
@ -180,7 +181,7 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot,
tm_->set_sm(metadata_sm_); tm_->set_sm(metadata_sm_);
data_sm_ = create_disk_sm(tm_, nr_data_blocks); data_sm_ = create_disk_sm(tm_, nr_data_blocks);
details_ = detail_tree::ptr(new detail_tree(tm_, device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(tm_, device_details_traits::ref_counter()));
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, block_time_ref_counter(data_sm_))); mappings_ = mapping_tree::ptr(new mapping_tree(tm_, block_time_ref_counter(data_sm_)));
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(), mtree_ref_counter(tm_))); mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(), mtree_ref_counter(tm_)));

View File

@ -26,6 +26,7 @@
#include "persistent-data/transaction_manager.h" #include "persistent-data/transaction_manager.h"
#include "thin-provisioning/metadata_disk_structures.h" #include "thin-provisioning/metadata_disk_structures.h"
#include "thin-provisioning/device_tree.h"
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -131,7 +132,6 @@ namespace thin_provisioning {
// FIXME: should these be in a sub-namespace? // FIXME: should these be in a sub-namespace?
typedef persistent_data::transaction_manager::ptr tm_ptr; typedef persistent_data::transaction_manager::ptr tm_ptr;
typedef persistent_data::btree<1, device_details_traits> detail_tree;
typedef persistent_data::btree<1, mtree_traits> dev_tree; typedef persistent_data::btree<1, mtree_traits> dev_tree;
typedef persistent_data::btree<2, block_traits> mapping_tree; typedef persistent_data::btree<2, block_traits> mapping_tree;
typedef persistent_data::btree<1, block_traits> single_mapping_tree; typedef persistent_data::btree<1, block_traits> single_mapping_tree;
@ -173,7 +173,7 @@ namespace thin_provisioning {
checked_space_map::ptr metadata_sm_; checked_space_map::ptr metadata_sm_;
checked_space_map::ptr data_sm_; checked_space_map::ptr data_sm_;
detail_tree::ptr details_; device_tree::ptr details_;
dev_tree::ptr mappings_top_level_; dev_tree::ptr mappings_top_level_;
mapping_tree::ptr mappings_; mapping_tree::ptr mappings_;
}; };

View File

@ -130,7 +130,7 @@ namespace {
bool device_exists(thin_dev_t dev) const { bool device_exists(thin_dev_t dev) const {
uint64_t key[1] = {dev}; uint64_t key[1] = {dev};
detail_tree::maybe_value v = md_->details_->lookup(key); device_tree::maybe_value v = md_->details_->lookup(key);
return v; return v;
} }

View File

@ -52,7 +52,6 @@ TEST_SOURCE=\
unit-tests/cache_t.cc \ unit-tests/cache_t.cc \
unit-tests/damage_tracker_t.cc \ unit-tests/damage_tracker_t.cc \
unit-tests/endian_t.cc \ unit-tests/endian_t.cc \
unit-tests/metadata_checker_t.cc \
unit-tests/space_map_t.cc \ unit-tests/space_map_t.cc \
unit-tests/span_iterator_t.cc \ unit-tests/span_iterator_t.cc \
unit-tests/thin_metadata_t.cc \ unit-tests/thin_metadata_t.cc \

View File

@ -3,7 +3,6 @@
#include "test_utils.h" #include "test_utils.h"
#include "persistent-data/block.h" #include "persistent-data/block.h"
#include "thin-provisioning/device_checker.h"
#include "thin-provisioning/restore_emitter.h" #include "thin-provisioning/restore_emitter.h"
#include "thin-provisioning/superblock_checker.h" #include "thin-provisioning/superblock_checker.h"
#include "thin-provisioning/superblock_validator.h" #include "thin-provisioning/superblock_validator.h"