[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/transaction_manager.cc \
thin-provisioning/file_utils.cc \
thin-provisioning/device_tree.cc \
thin-provisioning/metadata.cc \
thin-provisioning/metadata_checker.cc \
thin-provisioning/superblock.cc

View File

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

View File

@ -34,7 +34,7 @@ using namespace base;
using namespace thin_provisioning;
//----------------------------------------------------------------
#if 0
namespace {
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
check_superblock(block_manager<>::ptr bm,
superblock_detail::damage_visitor &visitor) {

View File

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

View File

@ -22,6 +22,7 @@
#include "version.h"
#include "persistent-data/space-maps/core.h"
#include "thin-provisioning/device_tree.h"
#include "thin-provisioning/file_utils.h"
#include "thin-provisioning/mapping_tree.h"
@ -103,7 +104,6 @@ namespace {
//--------------------------------
enum error_state {
NO_ERROR,
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);
typename block_io<>::mode m = block_io<>::READ_ONLY;
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 {
public:
superblock_reporter(nested_output &out)
@ -139,6 +152,10 @@ namespace {
virtual void visit(superblock_detail::superblock_corruption const &d) {
out_ << "superblock is corrupt" << end_message();
{
auto _ = out_.push();
out_ << d.desc_ << end_message();
}
err_ = combine_errors(err_, FATAL);
}
@ -151,18 +168,64 @@ namespace {
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) {
block_manager<>::ptr bm = open_bm(path);
nested_output out(cerr, 2);
superblock_reporter sb_rep(out);
devices_reporter dev_rep(out);
out << "examining superblock" << end_message();
{
auto _ = out.push();
superblock_reporter sb_rep(out);
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) {