device_tree
This commit is contained in:
parent
1ee8afd814
commit
fcb617f858
@ -48,7 +48,7 @@ SOURCE=\
|
||||
\
|
||||
cache/metadata_disk_structures.cc \
|
||||
\
|
||||
thin-provisioning/device_checker.cc \
|
||||
thin-provisioning/device_tree.cc \
|
||||
thin-provisioning/file_utils.cc \
|
||||
thin-provisioning/human_readable_format.cc \
|
||||
thin-provisioning/metadata.cc \
|
||||
|
@ -7,7 +7,6 @@
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace persistent_data {
|
||||
|
||||
namespace btree_detail {
|
||||
struct damage {
|
||||
typedef boost::shared_ptr<damage> ptr;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
@ -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
|
61
thin-provisioning/device_tree.cc
Normal file
61
thin-provisioning/device_tree.cc
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
51
thin-provisioning/device_tree.h
Normal file
51
thin-provisioning/device_tree.h
Normal 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
|
@ -16,6 +16,7 @@
|
||||
// with thin-provisioning-tools. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "thin-provisioning/device_tree.h"
|
||||
#include "thin-provisioning/file_utils.h"
|
||||
#include "thin-provisioning/metadata.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_);
|
||||
|
||||
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_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_)));
|
||||
break;
|
||||
@ -119,7 +120,7 @@ metadata::metadata(std::string const &dev_path, open_type ot,
|
||||
tm_->set_sm(metadata_sm_);
|
||||
|
||||
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_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_);
|
||||
|
||||
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_ = 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_);
|
||||
|
||||
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_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_)));
|
||||
break;
|
||||
@ -180,7 +181,7 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot,
|
||||
tm_->set_sm(metadata_sm_);
|
||||
|
||||
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_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(), mtree_ref_counter(tm_)));
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "persistent-data/transaction_manager.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?
|
||||
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<2, block_traits> 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 data_sm_;
|
||||
detail_tree::ptr details_;
|
||||
device_tree::ptr details_;
|
||||
dev_tree::ptr mappings_top_level_;
|
||||
mapping_tree::ptr mappings_;
|
||||
};
|
||||
|
@ -130,7 +130,7 @@ namespace {
|
||||
|
||||
bool device_exists(thin_dev_t dev) const {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,6 @@ TEST_SOURCE=\
|
||||
unit-tests/cache_t.cc \
|
||||
unit-tests/damage_tracker_t.cc \
|
||||
unit-tests/endian_t.cc \
|
||||
unit-tests/metadata_checker_t.cc \
|
||||
unit-tests/space_map_t.cc \
|
||||
unit-tests/span_iterator_t.cc \
|
||||
unit-tests/thin_metadata_t.cc \
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "test_utils.h"
|
||||
|
||||
#include "persistent-data/block.h"
|
||||
#include "thin-provisioning/device_checker.h"
|
||||
#include "thin-provisioning/restore_emitter.h"
|
||||
#include "thin-provisioning/superblock_checker.h"
|
||||
#include "thin-provisioning/superblock_validator.h"
|
||||
|
Loading…
Reference in New Issue
Block a user