[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/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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user