[cache_check] wip
This commit is contained in:
parent
b1f5807513
commit
e7223037d4
@ -226,9 +226,11 @@ thin_metadata_size: thin-provisioning/thin_metadata_size.o
|
||||
# Cache tools
|
||||
|
||||
CACHE_CHECK_SOURCE=\
|
||||
base/error_state.cc \
|
||||
persistent-data/checksum.cc \
|
||||
persistent-data/endian_utils.cc \
|
||||
persistent-data/error_set.cc \
|
||||
persistent-data/file_utils.cc \
|
||||
persistent-data/hex_dump.cc \
|
||||
persistent-data/lock_tracker.cc \
|
||||
persistent-data/data-structures/btree.cc \
|
||||
|
@ -14,12 +14,108 @@
|
||||
|
||||
#include "base/error_state.h"
|
||||
#include "base/nested_output.h"
|
||||
#include "caching/metadata.h"
|
||||
#include "persistent-data/block.h"
|
||||
#include "persistent-data/file_utils.h"
|
||||
#include "persistent-data/space-maps/core.h"
|
||||
|
||||
using namespace boost;
|
||||
using namespace caching;
|
||||
using namespace persistent_data;
|
||||
using namespace std;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
|
||||
class reporter_base {
|
||||
public:
|
||||
reporter_base(nested_output &o)
|
||||
: out_(o),
|
||||
err_(NO_ERROR) {
|
||||
}
|
||||
|
||||
virtual ~reporter_base() {}
|
||||
|
||||
nested_output &out() {
|
||||
return out_;
|
||||
}
|
||||
|
||||
nested_output::nest push() {
|
||||
return out_.push();
|
||||
}
|
||||
|
||||
base::error_state get_error() const {
|
||||
return err_;
|
||||
}
|
||||
|
||||
void mplus_error(error_state err) {
|
||||
err_ = combine_errors(err_, err);
|
||||
}
|
||||
|
||||
private:
|
||||
nested_output &out_;
|
||||
error_state err_;
|
||||
};
|
||||
|
||||
class superblock_reporter : public superblock_detail::damage_visitor, reporter_base {
|
||||
public:
|
||||
superblock_reporter(nested_output &o)
|
||||
: reporter_base(o) {
|
||||
}
|
||||
|
||||
virtual void visit(superblock_detail::superblock_corruption const &d) {
|
||||
out() << "superblock is corrupt" << end_message();
|
||||
{
|
||||
nested_output::nest _ = push();
|
||||
out() << d.desc_ << end_message();
|
||||
}
|
||||
|
||||
mplus_error(FATAL);
|
||||
}
|
||||
|
||||
using reporter_base::get_error;
|
||||
};
|
||||
|
||||
class mapping_reporter : public reporter_base {
|
||||
public:
|
||||
mapping_reporter(nested_output &o)
|
||||
: reporter_base(o) {
|
||||
}
|
||||
};
|
||||
|
||||
class hint_reporter : public reporter_base {
|
||||
public:
|
||||
hint_reporter(nested_output &o)
|
||||
: reporter_base(o) {
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
|
||||
struct flags {
|
||||
flags()
|
||||
: check_mappings_(false),
|
||||
check_hints_(false),
|
||||
ignore_non_fatal_errors_(false),
|
||||
quiet_(false) {
|
||||
}
|
||||
|
||||
bool check_mappings_;
|
||||
bool check_hints_;
|
||||
bool ignore_non_fatal_errors_;
|
||||
bool quiet_;
|
||||
};
|
||||
|
||||
struct stat guarded_stat(string const &path) {
|
||||
struct stat info;
|
||||
|
||||
@ -36,21 +132,49 @@ namespace {
|
||||
return info;
|
||||
}
|
||||
|
||||
int open_file(string const &path, int mode) {
|
||||
int fd = open(path.c_str(), mode);
|
||||
if (fd < 0) {
|
||||
ostringstream msg;
|
||||
char buffer[128], *ptr;
|
||||
error_state metadata_check(block_manager<>::ptr bm, flags const &fs) {
|
||||
error_state err = NO_ERROR;
|
||||
|
||||
ptr = strerror_r(errno, buffer, sizeof(buffer));
|
||||
msg << path << ": " << ptr;
|
||||
throw runtime_error(msg.str());
|
||||
nested_output out(cerr, 2);
|
||||
if (fs.quiet_)
|
||||
out.disable();
|
||||
|
||||
superblock_reporter sb_rep(out);
|
||||
mapping_reporter mapping_rep(out);
|
||||
hint_reporter hint_rep(out);
|
||||
|
||||
out << "examining superblock" << end_message();
|
||||
{
|
||||
nested_output::nest _ = out.push();
|
||||
check_superblock(bm, sb_rep);
|
||||
}
|
||||
|
||||
return fd;
|
||||
if (sb_rep.get_error() == FATAL)
|
||||
return FATAL;
|
||||
|
||||
superblock_detail::superblock sb = read_superblock(bm);
|
||||
transaction_manager::ptr tm = open_tm(bm);
|
||||
|
||||
if (fs.check_mappings_) {
|
||||
out << "examining mapping array" << end_message();
|
||||
{
|
||||
nested_output::nest _ = out.push();
|
||||
mapping_array ma(tm, mapping_array::ref_counter(), sb.mapping_root, sb.cache_blocks);
|
||||
// check_mapping_array(ma, mapping_rep);
|
||||
}
|
||||
}
|
||||
|
||||
if (fs.check_hints_) {
|
||||
out << "examining hint array" << end_message();
|
||||
{
|
||||
nested_output::nest _ = out.push();
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int check(string const &path, bool quiet) {
|
||||
int check(string const &path, flags const &fs) {
|
||||
struct stat info = guarded_stat(path);
|
||||
|
||||
if (!S_ISREG(info.st_mode) && !S_ISBLK(info.st_mode)) {
|
||||
@ -59,31 +183,26 @@ namespace {
|
||||
throw runtime_error(msg.str());
|
||||
}
|
||||
|
||||
int fd = open_file(path, O_RDONLY);
|
||||
|
||||
ostringstream msg;
|
||||
msg << path << ": " << "No superblock found";
|
||||
throw runtime_error(msg.str());
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
try {
|
||||
metadata::ptr md(new metadata(path, metadata::OPEN));
|
||||
block_manager<>::ptr bm = open_bm(path, block_io<>::READ_ONLY);
|
||||
//metadata::ptr md(new metadata(bm, metadata::OPEN));
|
||||
|
||||
optional<error_set::ptr> maybe_errors = metadata_check(md);
|
||||
error_state err = metadata_check(bm, fs);
|
||||
#if 0
|
||||
if (maybe_errors) {
|
||||
if (!quiet)
|
||||
if (!fs.quiet_)
|
||||
cerr << error_selector(*maybe_errors, 3);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
} catch (std::exception &e) {
|
||||
if (!quiet)
|
||||
if (!fs.quiet_)
|
||||
cerr << e.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void usage(ostream &out, string const &cmd) {
|
||||
@ -102,7 +221,7 @@ namespace {
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
bool quiet = false;
|
||||
flags fs;
|
||||
const char shortopts[] = "qhV";
|
||||
const struct option longopts[] = {
|
||||
{ "quiet", no_argument, NULL, 'q'},
|
||||
@ -118,7 +237,7 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
|
||||
case 'q':
|
||||
quiet = true;
|
||||
fs.quiet_ = true;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
@ -138,9 +257,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
try {
|
||||
check(argv[optind], quiet);
|
||||
check(argv[optind], fs);
|
||||
|
||||
} catch (exception const &e) {
|
||||
} catch (std::exception const &e) {
|
||||
cerr << e.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user