[thin_check] Wire up check_device_tree.

This commit is contained in:
Joe Thornber 2013-05-21 15:49:20 +01:00
parent f91b8f2fba
commit b456f16aa0
6 changed files with 84 additions and 6 deletions

View File

@ -135,6 +135,7 @@ THIN_CHECK_SOURCE=\
persistent-data/space-maps/careful_alloc.cc \ persistent-data/space-maps/careful_alloc.cc \
persistent-data/transaction_manager.cc \ persistent-data/transaction_manager.cc \
thin-provisioning/file_utils.cc \ thin-provisioning/file_utils.cc \
thin-provisioning/device_tree.cc \
thin-provisioning/metadata.cc \ thin-provisioning/metadata.cc \
thin-provisioning/metadata_checker.cc \ thin-provisioning/metadata_checker.cc \
thin-provisioning/superblock.cc thin-provisioning/superblock.cc

View File

@ -49,6 +49,7 @@ Feature: thin_check
When I run thin_check with --super-block-only When I run thin_check with --super-block-only
Then it should pass Then it should pass
@announce
Scenario: --super-block-only check fails with corrupt superblock Scenario: --super-block-only check fails with corrupt superblock
Given a corrupt superblock Given a corrupt superblock
When I run thin_check with --super-block-only When I run thin_check with --super-block-only

View File

@ -34,7 +34,7 @@ using namespace base;
using namespace thin_provisioning; using namespace thin_provisioning;
//---------------------------------------------------------------- //----------------------------------------------------------------
#if 0
namespace { namespace {
using namespace superblock_detail; using namespace superblock_detail;
@ -227,3 +227,4 @@ metadata::commit()
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
#endif

View File

@ -126,6 +126,17 @@ namespace thin_provisioning {
} }
} }
superblock_detail::superblock read_superblock(block_manager<>::ptr bm)
{
using namespace superblock_detail;
superblock sb;
auto r = bm->read_lock(SUPERBLOCK_LOCATION, superblock_validator());
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data());
superblock_traits::unpack(*sbd, sb);
return sb;
}
void void
check_superblock(block_manager<>::ptr bm, check_superblock(block_manager<>::ptr bm,
superblock_detail::damage_visitor &visitor) { superblock_detail::damage_visitor &visitor) {

View File

@ -122,6 +122,7 @@ namespace thin_provisioning {
block_manager<>::validator::ptr superblock_validator(); block_manager<>::validator::ptr superblock_validator();
superblock_detail::superblock read_superblock(block_manager<>::ptr bm);
void check_superblock(block_manager<>::ptr bm, void check_superblock(block_manager<>::ptr bm,
superblock_detail::damage_visitor &visitor); superblock_detail::damage_visitor &visitor);
} }

View File

@ -22,6 +22,7 @@
#include "version.h" #include "version.h"
#include "persistent-data/space-maps/core.h"
#include "thin-provisioning/device_tree.h" #include "thin-provisioning/device_tree.h"
#include "thin-provisioning/file_utils.h" #include "thin-provisioning/file_utils.h"
#include "thin-provisioning/mapping_tree.h" #include "thin-provisioning/mapping_tree.h"
@ -103,7 +104,6 @@ namespace {
//-------------------------------- //--------------------------------
enum error_state { enum error_state {
NO_ERROR, NO_ERROR,
NON_FATAL, // eg, lost blocks NON_FATAL, // eg, lost blocks
@ -124,12 +124,25 @@ namespace {
} }
} }
block_manager<>::ptr open_bm(string const &path) { //--------------------------------
block_manager<>::ptr
open_bm(string const &path) {
block_address nr_blocks = get_nr_blocks(path); block_address nr_blocks = get_nr_blocks(path);
typename block_io<>::mode m = block_io<>::READ_ONLY; typename block_io<>::mode m = block_io<>::READ_ONLY;
return block_manager<>::ptr(new block_manager<>(path, nr_blocks, 1, m)); return block_manager<>::ptr(new block_manager<>(path, nr_blocks, 1, m));
} }
transaction_manager::ptr
open_tm(block_manager<>::ptr bm) {
space_map::ptr sm(new core_map(bm->get_nr_blocks()));
sm->inc(superblock_detail::SUPERBLOCK_LOCATION);
transaction_manager::ptr tm(new transaction_manager(bm, sm));
return tm;
}
//--------------------------------
class superblock_reporter : public superblock_detail::damage_visitor { class superblock_reporter : public superblock_detail::damage_visitor {
public: public:
superblock_reporter(nested_output &out) superblock_reporter(nested_output &out)
@ -139,6 +152,10 @@ namespace {
virtual void visit(superblock_detail::superblock_corruption const &d) { virtual void visit(superblock_detail::superblock_corruption const &d) {
out_ << "superblock is corrupt" << end_message(); out_ << "superblock is corrupt" << end_message();
{
auto _ = out_.push();
out_ << d.desc_ << end_message();
}
err_ = combine_errors(err_, FATAL); err_ = combine_errors(err_, FATAL);
} }
@ -151,18 +168,64 @@ namespace {
error_state err_; error_state err_;
}; };
//--------------------------------
class devices_reporter : public device_tree_detail::damage_visitor {
public:
devices_reporter(nested_output &out)
: out_(out),
err_(NO_ERROR) {
}
virtual void visit(device_tree_detail::missing_devices const &d) {
out_ << "missing devices: " << d.keys_ << end_message();
{
auto _ = out_.push();
out_ << d.desc_ << end_message();
}
err_ = combine_errors(err_, FATAL);
}
error_state get_error() const {
return err_;
}
private:
nested_output &out_;
error_state err_;
};
//--------------------------------
error_state metadata_check(string const &path) { error_state metadata_check(string const &path) {
block_manager<>::ptr bm = open_bm(path); block_manager<>::ptr bm = open_bm(path);
nested_output out(cerr, 2); nested_output out(cerr, 2);
superblock_reporter sb_rep(out);
devices_reporter dev_rep(out);
out << "examining superblock" << end_message(); out << "examining superblock" << end_message();
{ {
auto _ = out.push(); auto _ = out.push();
superblock_reporter sb_rep(out);
check_superblock(bm, sb_rep); check_superblock(bm, sb_rep);
return sb_rep.get_error();
} }
if (sb_rep.get_error() == FATAL)
return FATAL;
out << "examining devices tree" << end_message();
{
auto _ = out.push();
superblock_detail::superblock sb = read_superblock(bm);
transaction_manager::ptr tm = open_tm(bm);
device_tree dtree(tm, sb.device_details_root_,
device_tree_detail::device_details_traits::ref_counter());
check_device_tree(dtree, dev_rep);
}
return combine_errors(sb_rep.get_error(),
dev_rep.get_error());
} }
int check(string const &path, bool quiet) { int check(string const &path, bool quiet) {