device_tree
This commit is contained in:
parent
1ee8afd814
commit
fcb617f858
@ -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 \
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
// 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_)));
|
||||||
|
|
||||||
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 \
|
||||||
|
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user