Working on device_checker
This commit is contained in:
		@@ -1,19 +1,103 @@
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
device_checker::device_checker(block_manager::ptr bm)
 | 
			
		||||
	: checker(bm)
 | 
			
		||||
namespace {
 | 
			
		||||
	// FIXME: duplication with metadata.cc
 | 
			
		||||
	transaction_manager::ptr
 | 
			
		||||
	open_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(unsigned level,
 | 
			
		||||
				    bool sub_root,
 | 
			
		||||
				    optional<uint64_t> key,
 | 
			
		||||
				    btree_detail::node_ref<uint64_traits> const &n) {
 | 
			
		||||
			return checker_.visit_internal(level, sub_root, key, n);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool visit_internal_leaf(unsigned level,
 | 
			
		||||
					 bool sub_root,
 | 
			
		||||
					 optional<uint64_t> key,
 | 
			
		||||
					 btree_detail::node_ref<uint64_traits> const &n) {
 | 
			
		||||
			return checker_.visit_internal_leaf(level, sub_root, key, n);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool visit_leaf(unsigned level,
 | 
			
		||||
				bool sub_root,
 | 
			
		||||
				optional<uint64_t> key,
 | 
			
		||||
				btree_detail::node_ref<device_details_traits> const &n) {
 | 
			
		||||
 | 
			
		||||
			if (!checker_.visit_leaf(level, sub_root, key, 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()
 | 
			
		||||
{
 | 
			
		||||
	// FIXME: finish.
 | 
			
		||||
	return damage_list_ptr(new damage_list);
 | 
			
		||||
	block_counter counter;
 | 
			
		||||
	device_visitor::ptr v(new device_visitor(counter));
 | 
			
		||||
	transaction_manager::ptr tm(open_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(v);
 | 
			
		||||
 | 
			
		||||
	} catch (std::exception const &e) {
 | 
			
		||||
 | 
			
		||||
		metadata_damage::ptr d(new missing_device_details(range64()));
 | 
			
		||||
		damage->push_back(d);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return damage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,11 @@
 | 
			
		||||
namespace thin_provisioning {
 | 
			
		||||
	class device_checker : public checker {
 | 
			
		||||
	public:
 | 
			
		||||
		device_checker(block_manager::ptr bm);
 | 
			
		||||
		device_checker(block_manager::ptr bm, block_address btree_root);
 | 
			
		||||
		damage_list_ptr check();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		block_address root_;
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -48,10 +48,8 @@ super_block_corruption::visit(metadata_damage_visitor &visitor) const
 | 
			
		||||
 | 
			
		||||
//--------------------------------
 | 
			
		||||
 | 
			
		||||
missing_device_details::missing_device_details(uint64_t missing_begin,
 | 
			
		||||
					       uint64_t missing_end)
 | 
			
		||||
	: missing_begin_(missing_begin),
 | 
			
		||||
	  missing_end_(missing_end)
 | 
			
		||||
missing_device_details::missing_device_details(range64 missing)
 | 
			
		||||
	: missing_(missing)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -63,10 +61,8 @@ missing_device_details::visit(metadata_damage_visitor &visitor) const
 | 
			
		||||
 | 
			
		||||
//--------------------------------
 | 
			
		||||
 | 
			
		||||
missing_devices::missing_devices(uint64_t missing_begin,
 | 
			
		||||
				 uint64_t missing_end)
 | 
			
		||||
	: missing_begin_(missing_begin),
 | 
			
		||||
	  missing_end_(missing_end)
 | 
			
		||||
missing_devices::missing_devices(range64 missing)
 | 
			
		||||
	: missing_(missing)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -78,12 +74,9 @@ missing_devices::visit(metadata_damage_visitor &visitor) const
 | 
			
		||||
 | 
			
		||||
//--------------------------------
 | 
			
		||||
 | 
			
		||||
missing_mappings::missing_mappings(uint64_t dev,
 | 
			
		||||
				   uint64_t missing_begin,
 | 
			
		||||
				   uint64_t missing_end)
 | 
			
		||||
missing_mappings::missing_mappings(uint64_t dev, range64 missing)
 | 
			
		||||
	: dev_(dev),
 | 
			
		||||
	  missing_begin_(missing_begin),
 | 
			
		||||
	  missing_end_(missing_end)
 | 
			
		||||
	  missing_(missing)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -129,10 +122,8 @@ bad_data_ref_count::visit(metadata_damage_visitor &visitor) const
 | 
			
		||||
 | 
			
		||||
//--------------------------------
 | 
			
		||||
 | 
			
		||||
missing_metadata_ref_counts::missing_metadata_ref_counts(block_address missing_begin,
 | 
			
		||||
							 block_address missing_end)
 | 
			
		||||
	: missing_begin_(missing_begin),
 | 
			
		||||
	  missing_end_(missing_end)
 | 
			
		||||
missing_metadata_ref_counts::missing_metadata_ref_counts(range64 missing)
 | 
			
		||||
	: missing_(missing)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -144,10 +135,8 @@ missing_metadata_ref_counts::visit(metadata_damage_visitor &visitor) const
 | 
			
		||||
 | 
			
		||||
//--------------------------------
 | 
			
		||||
 | 
			
		||||
missing_data_ref_counts::missing_data_ref_counts(block_address missing_begin,
 | 
			
		||||
						 block_address missing_end)
 | 
			
		||||
	: missing_begin_(missing_begin),
 | 
			
		||||
	  missing_end_(missing_end)
 | 
			
		||||
missing_data_ref_counts::missing_data_ref_counts(range64 missing)
 | 
			
		||||
	: missing_(missing)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -236,52 +225,6 @@ namespace {
 | 
			
		||||
		set<uint64_t> devices_;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	class details_validator : public btree<1, device_details_traits>::visitor {
 | 
			
		||||
	public:
 | 
			
		||||
		typedef boost::shared_ptr<details_validator> ptr;
 | 
			
		||||
		typedef btree_checker<1, device_details_traits> checker;
 | 
			
		||||
 | 
			
		||||
		details_validator(block_counter &counter)
 | 
			
		||||
			: checker_(counter) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool visit_internal(unsigned level,
 | 
			
		||||
				    bool sub_root,
 | 
			
		||||
				    optional<uint64_t> key,
 | 
			
		||||
				    btree_detail::node_ref<uint64_traits> const &n) {
 | 
			
		||||
			return checker_.visit_internal(level, sub_root, key, n);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool visit_internal_leaf(unsigned level,
 | 
			
		||||
					 bool sub_root,
 | 
			
		||||
					 optional<uint64_t> key,
 | 
			
		||||
					 btree_detail::node_ref<uint64_traits> const &n) {
 | 
			
		||||
			return checker_.visit_internal_leaf(level, sub_root, key, n);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool visit_leaf(unsigned level,
 | 
			
		||||
				bool sub_root,
 | 
			
		||||
				optional<uint64_t> key,
 | 
			
		||||
				btree_detail::node_ref<device_details_traits> const &n) {
 | 
			
		||||
 | 
			
		||||
			if (!checker_.visit_leaf(level, sub_root, key, 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_;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct check_count : public space_map::iterator {
 | 
			
		||||
		check_count(string const &desc, block_counter const &expected)
 | 
			
		||||
			: bad_(false),
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,8 @@
 | 
			
		||||
#include "persistent-data/error_set.h"
 | 
			
		||||
#include "persistent-data/space_map.h"
 | 
			
		||||
 | 
			
		||||
#include "thin-provisioning/range.h"
 | 
			
		||||
 | 
			
		||||
#include <deque>
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------
 | 
			
		||||
@@ -53,36 +55,28 @@ namespace thin_provisioning {
 | 
			
		||||
		void visit(metadata_damage_visitor &visitor) const;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct missing_device_details : public metadata_damage {
 | 
			
		||||
		missing_device_details(uint64_t missing_begin,
 | 
			
		||||
				       uint64_t missing_end);
 | 
			
		||||
	typedef range<uint64_t> range64;
 | 
			
		||||
 | 
			
		||||
	struct missing_device_details : public metadata_damage {
 | 
			
		||||
		missing_device_details(range64 missing);
 | 
			
		||||
		virtual void visit(metadata_damage_visitor &visitor) const;
 | 
			
		||||
 | 
			
		||||
		uint64_t missing_begin_;
 | 
			
		||||
		uint64_t missing_end_;
 | 
			
		||||
		range64 missing_;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct missing_devices : public metadata_damage {
 | 
			
		||||
		missing_devices(uint64_t missing_begin,
 | 
			
		||||
				uint64_t missing_end);
 | 
			
		||||
 | 
			
		||||
		missing_devices(range64 missing);
 | 
			
		||||
		virtual void visit(metadata_damage_visitor &visitor) const;
 | 
			
		||||
 | 
			
		||||
		uint64_t missing_begin_;
 | 
			
		||||
		uint64_t missing_end_;
 | 
			
		||||
		range64 missing_;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct missing_mappings : public metadata_damage {
 | 
			
		||||
		missing_mappings(uint64_t dev,
 | 
			
		||||
				 uint64_t missing_begin,
 | 
			
		||||
				 uint64_t missing_end);
 | 
			
		||||
 | 
			
		||||
		missing_mappings(uint64_t dev, range64 missing);
 | 
			
		||||
		virtual void visit(metadata_damage_visitor &visitor) const;
 | 
			
		||||
 | 
			
		||||
		uint64_t dev_;
 | 
			
		||||
		uint64_t missing_begin_;
 | 
			
		||||
		uint64_t missing_end_;
 | 
			
		||||
		range64 missing_;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct bad_metadata_ref_count : public metadata_damage {
 | 
			
		||||
@@ -110,23 +104,17 @@ namespace thin_provisioning {
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct missing_metadata_ref_counts : public metadata_damage {
 | 
			
		||||
		missing_metadata_ref_counts(block_address missing_begin,
 | 
			
		||||
					    block_address missing_end);
 | 
			
		||||
 | 
			
		||||
		missing_metadata_ref_counts(range64 missing);
 | 
			
		||||
		virtual void visit(metadata_damage_visitor &visitor) const;
 | 
			
		||||
 | 
			
		||||
		block_address missing_begin_;
 | 
			
		||||
		block_address missing_end_;
 | 
			
		||||
		range64 missing_;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct missing_data_ref_counts : public metadata_damage {
 | 
			
		||||
		missing_data_ref_counts(block_address missing_begin,
 | 
			
		||||
					block_address missing_end);
 | 
			
		||||
 | 
			
		||||
		missing_data_ref_counts(range64 missing);
 | 
			
		||||
		virtual void visit(metadata_damage_visitor &visitor) const;
 | 
			
		||||
 | 
			
		||||
		block_address missing_begin_;
 | 
			
		||||
		block_address missing_end_;
 | 
			
		||||
		range64 missing_;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	class metadata_damage_visitor {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user