[thin_check] Wire up check_device_tree.
This commit is contained in:
parent
f91b8f2fba
commit
b456f16aa0
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user